diff options
| -rw-r--r-- | doc/release/upcoming_changes/19805.new_feature.rst | 5 | ||||
| -rw-r--r-- | doc/release/upcoming_changes/19921.deprecation.rst | 3 | ||||
| -rw-r--r-- | doc/source/f2py/index.rst | 2 | ||||
| -rw-r--r-- | doc/source/user/building.rst | 3 | ||||
| -rw-r--r-- | doc/source/user/c-info.python-as-glue.rst | 87 | ||||
| -rw-r--r-- | numpy/__init__.pyi | 75 | ||||
| -rw-r--r-- | numpy/core/code_generators/ufunc_docstrings.py | 29 | ||||
| -rw-r--r-- | numpy/core/memmap.pyi | 5 | ||||
| -rw-r--r-- | numpy/core/src/npymath/npy_math_internal.h.src | 19 | ||||
| -rw-r--r-- | numpy/distutils/fcompiler/nag.py | 7 | ||||
| -rw-r--r-- | numpy/f2py/tests/test_crackfortran.py | 4 | ||||
| -rw-r--r-- | numpy/lib/function_base.py | 2 | ||||
| -rw-r--r-- | numpy/ma/mrecords.py | 14 | ||||
| -rw-r--r-- | numpy/ma/mrecords.pyi | 2 | ||||
| -rw-r--r-- | numpy/ma/tests/test_deprecations.py | 21 | ||||
| -rw-r--r-- | numpy/random/_generator.pyx | 4 | ||||
| -rw-r--r-- | numpy/random/mtrand.pyx | 4 | ||||
| -rw-r--r-- | numpy/typing/tests/data/fail/memmap.py | 5 | ||||
| -rw-r--r-- | numpy/typing/tests/data/reveal/memmap.py | 16 | ||||
| -rw-r--r-- | pytest.ini | 2 |
20 files changed, 229 insertions, 80 deletions
diff --git a/doc/release/upcoming_changes/19805.new_feature.rst b/doc/release/upcoming_changes/19805.new_feature.rst new file mode 100644 index 000000000..f59409254 --- /dev/null +++ b/doc/release/upcoming_changes/19805.new_feature.rst @@ -0,0 +1,5 @@ +Symbolic parser for Fortran dimension specifications +---------------------------------------------------- +A new symbolic parser has been added to f2py in order to correctly parse +dimension specifications. The parser is the basis for future improvements +and provides compatibility with Draft Fortran 202x. diff --git a/doc/release/upcoming_changes/19921.deprecation.rst b/doc/release/upcoming_changes/19921.deprecation.rst new file mode 100644 index 000000000..17fa0f605 --- /dev/null +++ b/doc/release/upcoming_changes/19921.deprecation.rst @@ -0,0 +1,3 @@ +* the misspelled keyword argument ``delimitor`` of + ``numpy.ma.mrecords.fromtextfile()`` has been changed into + ``delimiter``, using it will emit a deprecation warning. diff --git a/doc/source/f2py/index.rst b/doc/source/f2py/index.rst index 07d26e39e..c774a0df6 100644 --- a/doc/source/f2py/index.rst +++ b/doc/source/f2py/index.rst @@ -1,3 +1,5 @@ +.. _f2py: + ===================================== F2PY user guide and reference manual ===================================== diff --git a/doc/source/user/building.rst b/doc/source/user/building.rst index 10983ce8f..22efca4a6 100644 --- a/doc/source/user/building.rst +++ b/doc/source/user/building.rst @@ -45,6 +45,9 @@ Building NumPy requires the following software installed: 2) Compilers + Much of NumPy is written in C. You will need a C compiler that complies + with the C99 standard. + While a FORTRAN 77 compiler is not necessary for building NumPy, it is needed to run the ``numpy.f2py`` tests. These tests are skipped if the compiler is not auto-detected. diff --git a/doc/source/user/c-info.python-as-glue.rst b/doc/source/user/c-info.python-as-glue.rst index 2798aa08a..6d514f146 100644 --- a/doc/source/user/c-info.python-as-glue.rst +++ b/doc/source/user/c-info.python-as-glue.rst @@ -1,6 +1,6 @@ -******************** +==================== Using Python as glue -******************** +==================== | There is no conversation more boring than the one where everybody | agrees. @@ -124,9 +124,9 @@ Creating source for a basic extension module Probably the easiest way to introduce f2py is to offer a simple example. Here is one of the subroutines contained in a file named -:file:`add.f`: +:file:`add.f` -.. code-block:: none +.. code-block:: fortran C SUBROUTINE ZADD(A,B,C,N) @@ -149,14 +149,14 @@ routine can be automatically generated by f2py:: You should be able to run this command assuming your search-path is set-up properly. This command will produce an extension module named -addmodule.c in the current directory. This extension module can now be +:file:`addmodule.c` in the current directory. This extension module can now be compiled and used from Python just like any other extension module. Creating a compiled extension module ------------------------------------ -You can also get f2py to compile add.f and also compile its produced +You can also get f2py to both compile :file:`add.f` along with the produced extension module leaving only a shared-library extension file that can be imported from Python:: @@ -211,7 +211,7 @@ interface file use the -h option:: This command leaves the file add.pyf in the current directory. The section of this file corresponding to zadd is: -.. code-block:: none +.. code-block:: fortran subroutine zadd(a,b,c,n) ! in :add:add.f double complex dimension(*) :: a @@ -224,7 +224,7 @@ By placing intent directives and checking code, the interface can be cleaned up quite a bit until the Python module method is both easier to use and more robust. -.. code-block:: none +.. code-block:: fortran subroutine zadd(a,b,c,n) ! in :add:add.f double complex dimension(n) :: a @@ -277,9 +277,9 @@ Inserting directives in Fortran source The nice interface can also be generated automatically by placing the variable directives as special comments in the original Fortran code. -Thus, if I modify the source code to contain: +Thus, if the source code is modified to contain: -.. code-block:: none +.. code-block:: fortran C SUBROUTINE ZADD(A,B,C,N) @@ -298,14 +298,14 @@ Thus, if I modify the source code to contain: 20 CONTINUE END -Then, I can compile the extension module using:: +Then, one can compile the extension module using:: f2py -c -m add add.f The resulting signature for the function add.zadd is exactly the same one that was created previously. If the original source code had contained ``A(N)`` instead of ``A(*)`` and so forth with ``B`` and ``C``, -then I could obtain (nearly) the same interface simply by placing the +then nearly the same interface can be obtained by placing the ``INTENT(OUT) :: C`` comment line in the source code. The only difference is that ``N`` would be an optional input that would default to the length of ``A``. @@ -320,7 +320,7 @@ precision floating-point numbers using a fixed averaging filter. The advantage of using Fortran to index into multi-dimensional arrays should be clear from this example. -.. code-block:: none +.. code-block:: SUBROUTINE DFILTER2D(A,B,M,N) C @@ -407,13 +407,12 @@ conversion of the .pyf file to a .c file is handled by `numpy.disutils`. Conclusion ---------- -The interface definition file (.pyf) is how you can fine-tune the -interface between Python and Fortran. There is decent documentation -for f2py found in the numpy/f2py/docs directory where-ever NumPy is -installed on your system (usually under site-packages). There is also -more information on using f2py (including how to use it to wrap C -codes) at https://scipy-cookbook.readthedocs.io under the "Interfacing -With Other Languages" heading. +The interface definition file (.pyf) is how you can fine-tune the interface +between Python and Fortran. There is decent documentation for f2py at +:ref:`f2py`. There is also more information on using f2py (including how to use +it to wrap C codes) at the `"Interfacing With Other Languages" heading of the +SciPy Cookbook. +<https://scipy-cookbook.readthedocs.io/items/idx_interfacing_with_other_languages.html>`_ The f2py method of linking compiled code is currently the most sophisticated and integrated approach. It allows clean separation of @@ -422,7 +421,7 @@ distribution of the extension module. The only draw-back is that it requires the existence of a Fortran compiler in order for a user to install the code. However, with the existence of the free-compilers g77, gfortran, and g95, as well as high-quality commercial compilers, -this restriction is not particularly onerous. In my opinion, Fortran +this restriction is not particularly onerous. In our opinion, Fortran is still the easiest way to write fast and clear code for scientific computing. It handles complex numbers, and multi-dimensional indexing in the most straightforward way. Be aware, however, that some Fortran @@ -493,7 +492,7 @@ Complex addition in Cython Here is part of a Cython module named ``add.pyx`` which implements the complex addition functions we previously implemented using f2py: -.. code-block:: none +.. code-block:: cython cimport cython cimport numpy as np @@ -546,7 +545,7 @@ Image filter in Cython The two-dimensional example we created using Fortran is just as easy to write in Cython: -.. code-block:: none +.. code-block:: cython cimport numpy as np import numpy as np @@ -809,7 +808,7 @@ Calling the function The function is accessed as an attribute of or an item from the loaded shared-library. Thus, if ``./mylib.so`` has a function named -``cool_function1``, I could access this function either as: +``cool_function1``, it may be accessed either as: .. code-block:: python @@ -859,7 +858,7 @@ kind of array from a given input. Complete example ---------------- -In this example, I will show how the addition function and the filter +In this example, we will demonstrate how the addition function and the filter function implemented previously using the other approaches can be implemented using ctypes. First, the C code which implements the algorithms contains the functions ``zadd``, ``dadd``, ``sadd``, ``cadd``, @@ -1073,7 +1072,7 @@ Its disadvantages include - It is difficult to distribute an extension module made using ctypes because of a lack of support for building shared libraries in - distutils (but I suspect this will change in time). + distutils. - You must have shared-libraries of your code (no static libraries). @@ -1095,15 +1094,14 @@ Additional tools you may find useful These tools have been found useful by others using Python and so are included here. They are discussed separately because they are either older ways to do things now handled by f2py, Cython, or ctypes -(SWIG, PyFort) or because I don't know much about them (SIP, Boost). -I have not added links to these -methods because my experience is that you can find the most relevant -link faster using Google or some other search engine, and any links -provided here would be quickly dated. Do not assume that just because -it is included in this list, I don't think the package deserves your -attention. I'm including information about these packages because many -people have found them useful and I'd like to give you as many options -as possible for tackling the problem of easily integrating your code. +(SWIG, PyFort) or because of a lack of reasonable documentation (SIP, Boost). +Links to these methods are not included since the most relevant +can be found using Google or some other search engine, and any links provided +here would be quickly dated. Do not assume that inclusion in this list means +that the package deserves attention. Information about these packages are +collected here because many people have found them useful and we'd like to give +you as many options as possible for tackling the problem of easily integrating +your code. SWIG @@ -1132,12 +1130,12 @@ to the Python-specific typemaps, SWIG can be used to interface a library with other languages such as Perl, Tcl, and Ruby. My experience with SWIG has been generally positive in that it is -relatively easy to use and quite powerful. I used to use it quite +relatively easy to use and quite powerful. It has been used often before becoming more proficient at writing C-extensions. -However, I struggled writing custom interfaces with SWIG because it +However, writing custom interfaces with SWIG is often troublesome because it must be done using the concept of typemaps which are not Python -specific and are written in a C-like syntax. Therefore, I tend to -prefer other gluing strategies and would only attempt to use SWIG to +specific and are written in a C-like syntax. Therefore, other gluing strategies +are preferred and SWIG would be probably considered only to wrap a very-large C/C++ library. Nonetheless, there are others who use SWIG quite happily. @@ -1170,12 +1168,11 @@ those libraries which provides a concise interface for binding C++ classes and functions to Python. The amazing part of the Boost.Python approach is that it works entirely in pure C++ without introducing a new syntax. Many users of C++ report that Boost.Python makes it -possible to combine the best of both worlds in a seamless fashion. I -have not used Boost.Python because I am not a big user of C++ and -using Boost to wrap simple C-subroutines is usually over-kill. It's -primary purpose is to make C++ classes available in Python. So, if you -have a set of C++ classes that need to be integrated cleanly into -Python, consider learning about and using Boost.Python. +possible to combine the best of both worlds in a seamless fashion. Using Boost +to wrap simple C-subroutines is usually over-kill. Its primary purpose is to +make C++ classes available in Python. So, if you have a set of C++ classes that +need to be integrated cleanly into Python, consider learning about and using +Boost.Python. PyFort diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 84a60483d..c78d48cc6 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -196,6 +196,7 @@ from typing import ( SupportsIndex, Final, final, + ClassVar, ) # Ensures that the stubs are picked up @@ -636,6 +637,17 @@ class _IOProtocol(Protocol): def tell(self) -> SupportsIndex: ... def seek(self, offset: int, whence: int, /) -> object: ... +# NOTE: `seek`, `write` and `flush` are technically only required +# for `readwrite`/`write` modes +class _MemMapIOProtocol(Protocol): + def flush(self) -> object: ... + def fileno(self) -> SupportsIndex: ... + def tell(self) -> int: ... + def seek(self, offset: int, whence: int, /) -> object: ... + def write(self, s: bytes, /) -> object: ... + @property + def read(self) -> object: ... + __all__: List[str] __path__: List[str] __version__: str @@ -758,18 +770,6 @@ class matrix(ndarray[_ShapeType, _DType_co]): def getH(self): ... def getI(self): ... -class memmap(ndarray[_ShapeType, _DType_co]): - def __new__( - subtype, - filename: Any, - dtype: Any = ..., - mode: Any = ..., - offset: Any = ..., - shape: Any = ..., - order: Any = ..., - ) -> Any: ... - def __getattr__(self, key: str) -> Any: ... - class poly1d: def __init__( self, @@ -3828,3 +3828,54 @@ class nditer: def shape(self) -> Tuple[int, ...]: ... @property def value(self) -> Tuple[NDArray[Any], ...]: ... + +_MemMapModeKind = L[ + "readonly", "r", + "copyonwrite", "c", + "readwrite", "r+", + "write", "w+", +] + +class memmap(ndarray[_ShapeType, _DType_co]): + __array_priority__: ClassVar[float] + filename: str | None + offset: int + mode: str + @overload + def __new__( + subtype, + filename: str | bytes | os.PathLike[str] | os.PathLike[bytes] | _MemMapIOProtocol, + dtype: Type[uint8] = ..., + mode: _MemMapModeKind = ..., + offset: int = ..., + shape: None | int | Tuple[int, ...] = ..., + order: _OrderKACF = ..., + ) -> memmap[Any, dtype[uint8]]: ... + @overload + def __new__( + subtype, + filename: str | bytes | os.PathLike[str] | os.PathLike[bytes] | _MemMapIOProtocol, + dtype: _DTypeLike[_ScalarType], + mode: _MemMapModeKind = ..., + offset: int = ..., + shape: None | int | Tuple[int, ...] = ..., + order: _OrderKACF = ..., + ) -> memmap[Any, dtype[_ScalarType]]: ... + @overload + def __new__( + subtype, + filename: str | bytes | os.PathLike[str] | os.PathLike[bytes] | _MemMapIOProtocol, + dtype: DTypeLike, + mode: _MemMapModeKind = ..., + offset: int = ..., + shape: None | int | Tuple[int, ...] = ..., + order: _OrderKACF = ..., + ) -> memmap[Any, dtype[Any]]: ... + def __array_finalize__(self, obj: memmap[Any, Any]) -> None: ... + def __array_wrap__( + self, + array: memmap[_ShapeType, _DType_co], + context: None | Tuple[ufunc, Tuple[Any, ...], int] = ..., + ) -> Any: ... + def __getitem__(self, index): ... # TODO + def flush(self) -> None: ... diff --git a/numpy/core/code_generators/ufunc_docstrings.py b/numpy/core/code_generators/ufunc_docstrings.py index f19946be4..c15e1f042 100644 --- a/numpy/core/code_generators/ufunc_docstrings.py +++ b/numpy/core/code_generators/ufunc_docstrings.py @@ -201,7 +201,8 @@ add_newdoc('numpy.core.umath', 'arccos', References ---------- M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", - 10th printing, 1964, pp. 79. http://www.math.sfu.ca/~cbm/aands/ + 10th printing, 1964, pp. 79. + https://personal.math.ubc.ca/~cbm/aands/page_79.htm Examples -------- @@ -258,7 +259,8 @@ add_newdoc('numpy.core.umath', 'arccosh', References ---------- .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", - 10th printing, 1964, pp. 86. http://www.math.sfu.ca/~cbm/aands/ + 10th printing, 1964, pp. 86. + https://personal.math.ubc.ca/~cbm/aands/page_86.htm .. [2] Wikipedia, "Inverse hyperbolic function", https://en.wikipedia.org/wiki/Arccosh @@ -312,7 +314,7 @@ add_newdoc('numpy.core.umath', 'arcsin', ---------- Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*, 10th printing, New York: Dover, 1964, pp. 79ff. - http://www.math.sfu.ca/~cbm/aands/ + https://personal.math.ubc.ca/~cbm/aands/page_79.htm Examples -------- @@ -360,7 +362,8 @@ add_newdoc('numpy.core.umath', 'arcsinh', References ---------- .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", - 10th printing, 1964, pp. 86. http://www.math.sfu.ca/~cbm/aands/ + 10th printing, 1964, pp. 86. + https://personal.math.ubc.ca/~cbm/aands/page_86.htm .. [2] Wikipedia, "Inverse hyperbolic function", https://en.wikipedia.org/wiki/Arcsinh @@ -415,7 +418,7 @@ add_newdoc('numpy.core.umath', 'arctan', ---------- Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*, 10th printing, New York: Dover, 1964, pp. 79. - http://www.math.sfu.ca/~cbm/aands/ + https://personal.math.ubc.ca/~cbm/aands/page_79.htm Examples -------- @@ -560,7 +563,8 @@ add_newdoc('numpy.core.umath', 'arctanh', References ---------- .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", - 10th printing, 1964, pp. 86. http://www.math.sfu.ca/~cbm/aands/ + 10th printing, 1964, pp. 86. + https://personal.math.ubc.ca/~cbm/aands/page_86.htm .. [2] Wikipedia, "Inverse hyperbolic function", https://en.wikipedia.org/wiki/Arctanh @@ -1222,7 +1226,7 @@ add_newdoc('numpy.core.umath', 'exp', https://en.wikipedia.org/wiki/Exponential_function .. [2] M. Abramovitz and I. A. Stegun, "Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables," Dover, 1964, p. 69, - http://www.math.sfu.ca/~cbm/aands/page_69.htm + https://personal.math.ubc.ca/~cbm/aands/page_69.htm Examples -------- @@ -2052,7 +2056,8 @@ add_newdoc('numpy.core.umath', 'log', References ---------- .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", - 10th printing, 1964, pp. 67. http://www.math.sfu.ca/~cbm/aands/ + 10th printing, 1964, pp. 67. + https://personal.math.ubc.ca/~cbm/aands/page_67.htm .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm Examples @@ -2101,7 +2106,8 @@ add_newdoc('numpy.core.umath', 'log10', References ---------- .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", - 10th printing, 1964, pp. 67. http://www.math.sfu.ca/~cbm/aands/ + 10th printing, 1964, pp. 67. + https://personal.math.ubc.ca/~cbm/aands/page_67.htm .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm Examples @@ -2289,7 +2295,8 @@ add_newdoc('numpy.core.umath', 'log1p', References ---------- .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", - 10th printing, 1964, pp. 67. http://www.math.sfu.ca/~cbm/aands/ + 10th printing, 1964, pp. 67. + https://personal.math.ubc.ca/~cbm/aands/page_67.htm .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm Examples @@ -4002,7 +4009,7 @@ add_newdoc('numpy.core.umath', 'tanh', ---------- .. [1] M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions. New York, NY: Dover, 1972, pg. 83. - http://www.math.sfu.ca/~cbm/aands/ + https://personal.math.ubc.ca/~cbm/aands/page_83.htm .. [2] Wikipedia, "Hyperbolic function", https://en.wikipedia.org/wiki/Hyperbolic_function diff --git a/numpy/core/memmap.pyi b/numpy/core/memmap.pyi new file mode 100644 index 000000000..ba595bf1e --- /dev/null +++ b/numpy/core/memmap.pyi @@ -0,0 +1,5 @@ +from typing import List + +from numpy import memmap as memmap + +__all__: List[str] diff --git a/numpy/core/src/npymath/npy_math_internal.h.src b/numpy/core/src/npymath/npy_math_internal.h.src index 1e46a2303..cae84befe 100644 --- a/numpy/core/src/npymath/npy_math_internal.h.src +++ b/numpy/core/src/npymath/npy_math_internal.h.src @@ -457,21 +457,40 @@ NPY_INPLACE @type@ npy_frexp@c@(@type@ x, int* exp) * #c = l,,f# * #C = L,,F# */ + +/* + * On arm64 macOS, there's a bug with sin, cos, and tan where they don't + * raise "invalid" when given INFINITY as input. + */ +#if defined(__APPLE__) && defined(__arm64__) +#define WORKAROUND_APPLE_TRIG_BUG 1 +#else +#define WORKAROUND_APPLE_TRIG_BUG 0 +#endif + /**begin repeat1 * #kind = sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,rint,trunc,sqrt,log10, * log,exp,expm1,asin,acos,atan,asinh,acosh,atanh,log1p,exp2,log2# * #KIND = SIN,COS,TAN,SINH,COSH,TANH,FABS,FLOOR,CEIL,RINT,TRUNC,SQRT,LOG10, * LOG,EXP,EXPM1,ASIN,ACOS,ATAN,ASINH,ACOSH,ATANH,LOG1P,EXP2,LOG2# + * #TRIG_WORKAROUND = WORKAROUND_APPLE_TRIG_BUG*3, 0*22# */ #ifdef HAVE_@KIND@@C@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x) { +#if @TRIG_WORKAROUND@ + if (!npy_isfinite(x)) { + return (x - x); + } +#endif return @kind@@c@(x); } #endif /**end repeat1**/ +#undef WORKAROUND_APPLE_TRIG_BUG + /**begin repeat1 * #kind = atan2,hypot,pow,fmod,copysign# * #KIND = ATAN2,HYPOT,POW,FMOD,COPYSIGN# diff --git a/numpy/distutils/fcompiler/nag.py b/numpy/distutils/fcompiler/nag.py index 7df8ffe2c..fb85c821a 100644 --- a/numpy/distutils/fcompiler/nag.py +++ b/numpy/distutils/fcompiler/nag.py @@ -15,6 +15,9 @@ class BaseNAGFCompiler(FCompiler): return None def get_flags_linker_so(self): + if sys.platform == 'darwin': + return ['-unsharedf95', + '-Wl,-bundle,-flat_namespace,-undefined,suppress'] return ["-Wl,-shared"] def get_flags_opt(self): return ['-O4'] @@ -36,10 +39,6 @@ class NAGFCompiler(BaseNAGFCompiler): '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': diff --git a/numpy/f2py/tests/test_crackfortran.py b/numpy/f2py/tests/test_crackfortran.py index da7974d1a..b1503c1e0 100644 --- a/numpy/f2py/tests/test_crackfortran.py +++ b/numpy/f2py/tests/test_crackfortran.py @@ -170,7 +170,7 @@ class TestMarkinnerspaces(): class TestDimSpec(util.F2PyTest): - """This test site tests various expressions that are used as dimension + """This test suite tests various expressions that are used as dimension specifications. There exists two usage cases where analyzing dimensions @@ -183,7 +183,7 @@ class TestDimSpec(util.F2PyTest): `lower` and `upper` are arbitrary expressions of input parameters. The evaluation is performed in C, so f2py has to translate Fortran expressions to valid C expressions (an alternative approach is - that a developer specifies the corresponing C expressions in a + that a developer specifies the corresponding C expressions in a .pyf file). In the second case, when user provides an input array with a given diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index b77ce8782..80eaf8acf 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -3252,7 +3252,7 @@ def i0(x): 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 + https://personal.math.ubc.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 diff --git a/numpy/ma/mrecords.py b/numpy/ma/mrecords.py index bdce8b3bd..2ce1f0a23 100644 --- a/numpy/ma/mrecords.py +++ b/numpy/ma/mrecords.py @@ -668,7 +668,8 @@ def openfile(fname): def fromtextfile(fname, delimiter=None, commentchar='#', missingchar='', - varnames=None, vartypes=None): + varnames=None, vartypes=None, + *, delimitor=np._NoValue): # backwards compatibility """ Creates a mrecarray from data stored in the file `filename`. @@ -692,6 +693,17 @@ def fromtextfile(fname, delimiter=None, commentchar='#', missingchar='', Ultra simple: the varnames are in the header, one line""" + if delimitor is not np._NoValue: + if delimiter is not None: + raise TypeError("fromtextfile() got multiple values for argument " + "'delimiter'") + # NumPy 1.22.0, 2021-09-23 + warnings.warn("The 'delimitor' keyword argument of " + "numpy.ma.mrecords.fromtextfile() is deprecated " + "since NumPy 1.22.0, use 'delimiter' instead.", + DeprecationWarning, stacklevel=2) + delimiter = delimitor + # Try to open the file. ftext = openfile(fname) diff --git a/numpy/ma/mrecords.pyi b/numpy/ma/mrecords.pyi index cdd5347d6..7bd8678cf 100644 --- a/numpy/ma/mrecords.pyi +++ b/numpy/ma/mrecords.pyi @@ -83,6 +83,8 @@ def fromtextfile( missingchar=..., varnames=..., vartypes=..., + # NOTE: deprecated: NumPy 1.22.0, 2021-09-23 + # delimitor=..., ): ... def addfield(mrecord, newfield, newfieldname=...): ... diff --git a/numpy/ma/tests/test_deprecations.py b/numpy/ma/tests/test_deprecations.py index 14f697375..3e0e09fdd 100644 --- a/numpy/ma/tests/test_deprecations.py +++ b/numpy/ma/tests/test_deprecations.py @@ -1,10 +1,13 @@ """Test deprecation and future warnings. """ +import pytest import numpy as np from numpy.testing import assert_warns from numpy.ma.testutils import assert_equal from numpy.ma.core import MaskedArrayFutureWarning +import io +import textwrap class TestArgsort: """ gh-8701 """ @@ -66,3 +69,21 @@ class TestMinimumMaximum: result = ma_max(data1d) assert_equal(result, ma_max(data1d, axis=None)) assert_equal(result, ma_max(data1d, axis=0)) + + +class TestFromtextfile: + def test_fromtextfile_delimitor(self): + # NumPy 1.22.0, 2021-09-23 + + textfile = io.StringIO(textwrap.dedent( + """ + A,B,C,D + 'string 1';1;1.0;'mixed column' + 'string 2';2;2.0; + 'string 3';3;3.0;123 + 'string 4';4;4.0;3.14 + """ + )) + + with pytest.warns(DeprecationWarning): + result = np.ma.mrecords.fromtextfile(textfile, delimitor=';') diff --git a/numpy/random/_generator.pyx b/numpy/random/_generator.pyx index 8db1f0269..5bacb9f6f 100644 --- a/numpy/random/_generator.pyx +++ b/numpy/random/_generator.pyx @@ -4441,7 +4441,7 @@ cdef class Generator: # Fast, statically typed path: shuffle the underlying buffer. # Only for non-empty, 1d objects of class ndarray (subclasses such # as MaskedArrays may not support this approach). - x_ptr = <char*><size_t>np.PyArray_DATA(x) + x_ptr = np.PyArray_BYTES(x) stride = x.strides[0] itemsize = x.dtype.itemsize # As the array x could contain python objects we use a buffer @@ -4449,7 +4449,7 @@ cdef class Generator: # within the buffer and erroneously decrementing it's refcount # when the function exits. buf = np.empty(itemsize, dtype=np.int8) # GC'd at function exit - buf_ptr = <char*><size_t>np.PyArray_DATA(buf) + buf_ptr = np.PyArray_BYTES(buf) if x.dtype.hasobject: with self.lock: _shuffle_raw_wrap(&self._bitgen, n, 1, itemsize, stride, diff --git a/numpy/random/mtrand.pyx b/numpy/random/mtrand.pyx index c9d8ee8e3..06e75a698 100644 --- a/numpy/random/mtrand.pyx +++ b/numpy/random/mtrand.pyx @@ -4472,7 +4472,7 @@ cdef class RandomState: # Fast, statically typed path: shuffle the underlying buffer. # Only for non-empty, 1d objects of class ndarray (subclasses such # as MaskedArrays may not support this approach). - x_ptr = <char*><size_t>np.PyArray_DATA(x) + x_ptr = np.PyArray_BYTES(x) stride = x.strides[0] itemsize = x.dtype.itemsize # As the array x could contain python objects we use a buffer @@ -4480,7 +4480,7 @@ cdef class RandomState: # within the buffer and erroneously decrementing it's refcount # when the function exits. buf = np.empty(itemsize, dtype=np.int8) # GC'd at function exit - buf_ptr = <char*><size_t>np.PyArray_DATA(buf) + buf_ptr = np.PyArray_BYTES(buf) with self.lock: # We trick gcc into providing a specialized implementation for # the most common case, yielding a ~33% performance improvement. diff --git a/numpy/typing/tests/data/fail/memmap.py b/numpy/typing/tests/data/fail/memmap.py new file mode 100644 index 000000000..434870b60 --- /dev/null +++ b/numpy/typing/tests/data/fail/memmap.py @@ -0,0 +1,5 @@ +import numpy as np + +with open("file.txt", "r") as f: + np.memmap(f) # E: No overload variant +np.memmap("test.txt", shape=[10, 5]) # E: No overload variant diff --git a/numpy/typing/tests/data/reveal/memmap.py b/numpy/typing/tests/data/reveal/memmap.py new file mode 100644 index 000000000..c1d8edc67 --- /dev/null +++ b/numpy/typing/tests/data/reveal/memmap.py @@ -0,0 +1,16 @@ +import numpy as np +from typing import Any + +memmap_obj: np.memmap[Any, np.dtype[np.str_]] + +reveal_type(np.memmap.__array_priority__) # E: float +reveal_type(memmap_obj.__array_priority__) # E: float +reveal_type(memmap_obj.filename) # E: Union[builtins.str, None] +reveal_type(memmap_obj.offset) # E: int +reveal_type(memmap_obj.mode) # E: str +reveal_type(memmap_obj.flush()) # E: None + +reveal_type(np.memmap("file.txt", offset=5)) # E: numpy.memmap[Any, numpy.dtype[{uint8}]] +reveal_type(np.memmap(b"file.txt", dtype=np.float64, shape=(10, 3))) # E: numpy.memmap[Any, numpy.dtype[{float64}]] +with open("file.txt", "rb") as f: + reveal_type(np.memmap(f, dtype=float, order="K")) # E: numpy.memmap[Any, numpy.dtype[Any]] diff --git a/pytest.ini b/pytest.ini index dfad538c2..92ce6d6e2 100644 --- a/pytest.ini +++ b/pytest.ini @@ -16,3 +16,5 @@ filterwarnings = ignore:Importing from numpy.matlib is # pytest warning when using PYTHONOPTIMIZE ignore:assertions not in test modules or plugins:pytest.PytestConfigWarning +# TODO: remove below when array_api user warning is removed + ignore:The numpy.array_api submodule is still experimental. See NEP 47. |
