ronantakizawa/codereview-bench huggingface dataset:
Repository: numpy/numpy
File: numpy/tests/test_lazyloading.py (Python)

Code before:
import sys
from importlib.util import LazyLoader, find_spec, module_from_spec

# create lazy load of numpy as np
spec = find_spec("numpy")
module = module_from_spec(spec)
sys.modules["numpy"] = module
loader = LazyLoader(spec.loader)
loader.exec_module(module)
np = module

# test a subpackage import
from numpy.lib import recfunctions  # noqa: F401

# test triggering the import of the package
np.ndarray
"""
    p = subprocess.run(
        (sys.executable, '-c', code),
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        encoding='utf-8',
        check=False,
    )
    assert p.returncode == 0, p.stdout


Review comment (performance):
@dschult if you can have a quick look: I think doing the lazy loading test in a subprocess is identical (but safer as it avoids messing with `sys.modules`).  Does that seem right?

Code after:
    code = textwrap.dedent(r"""
        import sys
        from importlib.util import LazyLoader, find_spec, module_from_spec

        # create lazy load of numpy as np
        spec = find_spec("numpy")
        module = module_from_spec(spec)
        sys.modules["numpy"] = module
        loader = LazyLoader(spec.loader)
        loader.exec_module(module)
        np = module

        # test a subpackage import
        from numpy.lib import recfunctions  # noqa: F401

        # test triggering the import of the package
        np.ndarray
        """)
    p = subprocess.run(
        (sys.executable, '-c', code),
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        encoding='utf-8',
        check=False,
    )
    assert p.returncode == 0, p.stdout
Repository: numpy/numpy
File: numpy/_core/strings.pyi (Python)

Code before:
    a: U_co,
    table: str,
    deletechars: str | None = None,
) -> NDArray[np.str_]: ...
@overload
def translate(
    a: S_co,
    table: str,
    deletechars: str | None = None,
) -> NDArray[np.bytes_]: ...
@overload
def translate(
    a: _StringDTypeSupportsArray,
    table: str,
    deletechars: str | None = None,
) -> _StringDTypeArray: ...
@overload
def translate(
    a: T_co,
    table: str,
    deletechars: str | None = None,
) -> _StringDTypeOrUnicodeArray: ...

#
@overload
def slice(a: U_co, start: i_co | None = None, stop: i_co | None = None, step: i_co | None = None, /) -> NDArray[np.str_]: ...  # type: ignore[overload-overlap]
@overload
def slice(a: S_co, start: i_co | None = None, stop: i_co | None = None, step: i_co | None = None, /) -> NDArray[np.bytes_]: ...
@overload
def slice(
    a: _StringDTypeSupportsArray, start: i_co | None = None, stop: i_co | None = None, step: i_co | None = None, /
) -> _StringDTypeArray: ...


Review comment (bug):
I `# type: ignore`'d this mypy error because I believe that it's a false positive. This seems to be in line with what pyright believes, because it doesn't report an error here.

Code after:
    a: U_co,
    table: str,
    deletechars: str | None = None,
) -> NDArray[np.str_]: ...
@overload
def translate(
    a: S_co,
    table: str,
    deletechars: str | None = None,
) -> NDArray[np.bytes_]: ...
@overload
def translate(
    a: _StringDTypeSupportsArray,
    table: str,
    deletechars: str | None = None,
) -> _StringDTypeArray: ...
@overload
def translate(
    a: T_co,
    table: str,
    deletechars: str | None = None,
) -> _StringDTypeOrUnicodeArray: ...

#
@overload
def slice(a: U_co, start: i_co | None = None, stop: i_co | None = None, step: i_co | None = None, /) -> NDArray[np.str_]: ...  # type: ignore[overload-overlap]
@overload
def slice(a: S_co, start: i_co | None = None, stop: i_co | None = None, step: i_co | None = None, /) -> NDArray[np.bytes_]: ...
@overload
def slice(
    a: _StringDTypeSupportsArray, start: i_co | None = None, stop: i_co | None = None, step: i_co | None = None, /
) -> _StringDTypeArray: ...
@overload
def slice(
    a: T_co, start: i_co | None = None, stop: i_co | None = None, step: i_co | None = None, /
) -> _StringDTypeOrUnicodeArray: ...
Repository: numpy/numpy
File: numpy/_core/src/umath/string_ufuncs.cpp (C++)

Code before:
    size_t len2 = buf2.num_codepoints();
    buf1.buffer_memcpy(out, len1);
    buf2.buffer_memcpy(out + len1, len2);
    out.buffer_fill_with_zeros_after_index(len1 + len2);
}


template <ENCODING enc>
static inline int
string_multiply(Buffer<enc> buf1, npy_int64 reps, Buffer<enc> out)
{
    size_t len1 = buf1.num_codepoints();
    if (reps < 1 || len1 == 0) {
        out.buffer_fill_with_zeros_after_index(0);
        return 0;
    }

    size_t width = out.buffer_width();
    if (len1 == 1) {
        out.buffer_memset(*buf1, reps);
        out.buffer_fill_with_zeros_after_index(reps);
        return 0;
    }

    size_t newlen;
    if (NPY_UNLIKELY(npy_mul_with_overflow_size_t(&newlen, reps, len1) < 0) || newlen > PY_SSIZE_T_MAX) {
        return -1;
    }

    size_t pad = 0;
    if (width < newlen) {
        reps = width / len1;
        pad = width % len1;
    }

    for (npy_int64 i = 0; i < reps; i++) {
        buf1.buffer_memcpy(out, len1);
        out += len1;
    }

    buf1.buffer_memcpy(out, pad);
    out += pad;

    out.buffer_fill_with_zeros_after_index(0);

    return 0;
}


template <ENCODING enc>
static int

Review comment (bug):
```suggestion
    if (NPY_UNLIKELY(npy_mul_with_overflow_size_t(&newlen, reps, len1) != 0) || newlen > PY_SSIZE_T_MAX) {
```
I think this one isn't technically an error return, but a "has overflown" return...  Maybe the test should run into the overflow path, but `newlen > PY_SSIZE_T_MAX` also kicks in due to fun overflows?

Overflow error or memory error is both fine to me (for this branch I would also be OK with just using the `width < newlen` path).

Code after:
    size_t len2 = buf2.num_codepoints();
    buf1.buffer_memcpy(out, len1);
    buf2.buffer_memcpy(out + len1, len2);
    out.buffer_fill_with_zeros_after_index(len1 + len2);
}


template <ENCODING enc>
static inline int
string_multiply(Buffer<enc> buf1, npy_int64 reps, Buffer<enc> out)
{
    size_t len1 = buf1.num_codepoints();
    if (reps < 1 || len1 == 0) {
        out.buffer_fill_with_zeros_after_index(0);
        return 0;
    }

    if (len1 == 1) {
        out.buffer_memset(*buf1, reps);
        out.buffer_fill_with_zeros_after_index(reps);
        return 0;
    }

    size_t newlen;
    if (NPY_UNLIKELY(npy_mul_with_overflow_size_t(&newlen, reps, len1) != 0) || newlen > PY_SSIZE_T_MAX) {
        return -1;
    }

    size_t pad = 0;
    size_t width = out.buffer_width();
    if (width < newlen) {
        reps = width / len1;
        pad = width % len1;
    }

    for (npy_int64 i = 0; i < reps; i++) {
        buf1.buffer_memcpy(out, len1);
        out += len1;
    }

    buf1.buffer_memcpy(out, pad);
    out += pad;

    out.buffer_fill_with_zeros_after_index(0);

    return 0;
}


template <ENCODING enc>
static int
Repository: numpy/numpy
File: tools/pyright_completeness.py (Python)

Code before:
"""
Run PyRight's `--verifytypes` and check that its reported type completeness is above
a minimum threshold.

Example usage:

    spin run python tools/pyright_completeness.py --verifytypes numpy --ignoreexternal \
        --exclude-like '*.tests.*' '*.conftest.*'

We use `--ignoreexternal` to avoid "partially unknown" reports coming from the stdlib
`numbers` module, see https://github.com/microsoft/pyright/discussions/9911.
"""
import argparse
import fnmatch
import json
import subprocess
import sys
from collections.abc import Sequence


def main(argv: Sequence[str] | None = None) -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--exclude-like",
        required=False,
        nargs="*",
        type=str,
        help="Exclude symbols whose names matches this glob pattern",
    )
    args, unknownargs = parser.parse_known_args(argv)
    pyright_args = list(unknownargs)
    if "--outputjson" not in pyright_args:
        pyright_args.append("--outputjson")
    return run_pyright_with_coverage(pyright_args, args.exclude_like)


def run_pyright_with_coverage(

Review comment (suggestion):
for `ruff format` compat

```suggestion
"""

```

Code after:
"""
Run PyRight's `--verifytypes` and check that its reported type completeness is above
a minimum threshold.

Example usage:

    spin run python tools/pyright_completeness.py --verifytypes numpy --ignoreexternal \
        --exclude-like '*.tests.*' '*.conftest.*'

We use `--ignoreexternal` to avoid "partially unknown" reports coming from the stdlib
`numbers` module, see https://github.com/microsoft/pyright/discussions/9911.
"""

import argparse
import fnmatch
import json
import subprocess
import sys
from collections.abc import Sequence


def main(argv: Sequence[str] | None = None) -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--exclude-like",
        required=False,
        nargs="*",
        type=str,
        help="Exclude symbols whose names matches this glob pattern",
    )
    args, unknownargs = parser.parse_known_args(argv)
    pyright_args = list(unknownargs)
    if "--outputjson" not in pyright_args:
        pyright_args.append("--outputjson")
    return run_pyright_with_coverage(pyright_args, args.exclude_like)
Repository: numpy/numpy
File: numpy/typing/tests/data/pass/ma.py (Python)

Code before:
from typing import Any, TypeAlias, TypeVar, cast

import numpy as np
import numpy.typing as npt
from numpy._typing import _Shape

_ScalarT = TypeVar("_ScalarT", bound=np.generic)
MaskedArray: TypeAlias = np.ma.MaskedArray[_Shape, np.dtype[_ScalarT]]

MAR_b: MaskedArray[np.bool] = np.ma.MaskedArray([True])
MAR_u: MaskedArray[np.uint32] = np.ma.MaskedArray([1], dtype=np.uint32)
MAR_i: MaskedArray[np.int64] = np.ma.MaskedArray([1])
MAR_f: MaskedArray[np.float64] = np.ma.MaskedArray([1.0])
MAR_c: MaskedArray[np.complex128] = np.ma.MaskedArray([1j])
MAR_td64: MaskedArray[np.timedelta64] = np.ma.MaskedArray([np.timedelta64(1, "D")])
MAR_M_dt64: MaskedArray[np.datetime64] = np.ma.MaskedArray([np.datetime64(1, "D")])
MAR_S: MaskedArray[np.bytes_] = np.ma.MaskedArray([b'foo'], dtype=np.bytes_)
MAR_U: MaskedArray[np.str_] = np.ma.MaskedArray(['foo'], dtype=np.str_)
MAR_T = cast(np.ma.MaskedArray[Any, np.dtypes.StringDType],
             np.ma.MaskedArray(["a"], dtype="T"))

AR_b: npt.NDArray[np.bool] = np.array([True, False, True])

AR_LIKE_b = [True]
AR_LIKE_u = [np.uint32(1)]
AR_LIKE_i = [1]
AR_LIKE_f = [1.0]
AR_LIKE_c = [1j]
AR_LIKE_m = [np.timedelta64(1, "D")]
AR_LIKE_M = [np.datetime64(1, "D")]

MAR_f.mask = AR_b
MAR_f.mask = np.False_

# Inplace addition

Review comment (suggestion):
this is required because `numpy.ma.core.MaskedArray.__new__` is untyped.

Code after:
from typing import Any, TypeAlias, TypeVar, cast

import numpy as np
import numpy.typing as npt
from numpy._typing import _Shape

_ScalarT = TypeVar("_ScalarT", bound=np.generic)
MaskedArray: TypeAlias = np.ma.MaskedArray[_Shape, np.dtype[_ScalarT]]

# mypy: disable-error-code=no-untyped-call

MAR_b: MaskedArray[np.bool] = np.ma.MaskedArray([True])
MAR_u: MaskedArray[np.uint32] = np.ma.MaskedArray([1], dtype=np.uint32)
MAR_i: MaskedArray[np.int64] = np.ma.MaskedArray([1])
MAR_f: MaskedArray[np.float64] = np.ma.MaskedArray([1.0])
MAR_c: MaskedArray[np.complex128] = np.ma.MaskedArray([1j])
MAR_td64: MaskedArray[np.timedelta64] = np.ma.MaskedArray([np.timedelta64(1, "D")])
MAR_M_dt64: MaskedArray[np.datetime64] = np.ma.MaskedArray([np.datetime64(1, "D")])
MAR_S: MaskedArray[np.bytes_] = np.ma.MaskedArray([b'foo'], dtype=np.bytes_)
MAR_U: MaskedArray[np.str_] = np.ma.MaskedArray(['foo'], dtype=np.str_)
MAR_T = cast(np.ma.MaskedArray[Any, np.dtypes.StringDType],
             np.ma.MaskedArray(["a"], dtype="T"))

AR_b: npt.NDArray[np.bool] = np.array([True, False, True])

AR_LIKE_b = [True]
AR_LIKE_u = [np.uint32(1)]
AR_LIKE_i = [1]
AR_LIKE_f = [1.0]
AR_LIKE_c = [1j]
AR_LIKE_m = [np.timedelta64(1, "D")]
AR_LIKE_M = [np.datetime64(1, "D")]

MAR_f.mask = AR_b
MAR_f.mask = np.False_
Repository: numpy/numpy
File: numpy/_core/src/multiarray/calculation.c (C)

Code before:
        Py_DECREF(part);
        if (round_part == NULL) {
            Py_DECREF(arr);
            return NULL;
        }
        res = PyObject_SetAttrString(arr, "imag", round_part);
        Py_DECREF(round_part);
        if (res < 0) {
            Py_DECREF(arr);
            return NULL;
        }
        return arr;
    }
    /* do the most common case first */
    if (decimals >= 0) {
        if (PyArray_ISINTEGER(a)) {
            if (out) {
                if (PyArray_AssignArray(out, a,
                            NULL, NPY_DEFAULT_ASSIGN_CASTING) < 0) {
                    return NULL;
                }
                Py_INCREF(out);
                return (PyObject *)out;
            }
            else {
                return PyArray_Copy(a);
            }
        }
        if (decimals == 0) {
            if (out) {
                return PyObject_CallFunction(n_ops.rint, "OO", a, out);
            }
            return PyObject_CallFunction(n_ops.rint, "O", a);
        }
        op1 = n_ops.multiply;
        op2 = n_ops.true_divide;
    }
    else {
        op1 = n_ops.true_divide;
        op2 = n_ops.multiply;
        decimals = -decimals;
    }
    if (!out) {
        if (PyArray_ISINTEGER(a)) {
            ret_int = 1;
            my_descr = PyArray_DescrFromType(NPY_DOUBLE);
        }
        else {
            Py_INCREF(PyArray_DESCR(a));
            my_descr = PyArray_DESCR(a);
        }

Review comment (suggestion):
```suggestion
                return PyArray_NewCopy(a, NPY_KEEPORDER);
```

Code after:
        Py_DECREF(part);
        if (round_part == NULL) {
            Py_DECREF(arr);
            return NULL;
        }
        res = PyObject_SetAttrString(arr, "imag", round_part);
        Py_DECREF(round_part);
        if (res < 0) {
            Py_DECREF(arr);
            return NULL;
        }
        return arr;
    }
    /* do the most common case first */
    if (decimals >= 0) {
        if (PyArray_ISINTEGER(a)) {
            if (out) {
                if (PyArray_AssignArray(out, a,
                            NULL, NPY_DEFAULT_ASSIGN_CASTING) < 0) {
                    return NULL;
                }
                Py_INCREF(out);
                return (PyObject *)out;
            }
            else {
                return PyArray_NewCopy(a, NPY_KEEPORDER);
            }
        }
        if (decimals == 0) {
            if (out) {
                return PyObject_CallFunction(n_ops.rint, "OO", a, out);
            }
            return PyObject_CallFunction(n_ops.rint, "O", a);
        }
        op1 = n_ops.multiply;
        op2 = n_ops.true_divide;
    }
    else {
        op1 = n_ops.true_divide;
        op2 = n_ops.multiply;
        decimals = -decimals;
    }
    if (!out) {
        if (PyArray_ISINTEGER(a)) {
            ret_int = 1;
            my_descr = PyArray_DescrFromType(NPY_DOUBLE);
        }
        else {
            Py_INCREF(PyArray_DESCR(a));
            my_descr = PyArray_DESCR(a);
        }
Repository: numpy/numpy
File: numpy/_core/tests/test_datetime.py (Python)

Code before:
import datetime
import pickle
from zoneinfo import ZoneInfo

import pytest

import numpy
import numpy as np
from numpy.testing import (
    IS_WASM,
    assert_,
    assert_array_equal,
    assert_equal,
    assert_raises,
    assert_raises_regex,
    assert_warns,
    suppress_warnings,
)

try:
    RecursionError
except NameError:
    RecursionError = RuntimeError  # python < 3.5


def _assert_equal_hash(v1, v2):
    assert v1 == v2
    assert hash(v1) == hash(v2)
    assert v2 in {v1}


class TestDateTime:

    def test_string(self):
        msg = "no explicit representation of timezones available for " \
              "np.datetime64"
        with pytest.warns(UserWarning, match=msg):
            np.datetime64('2000-01-01T00+01')

    def test_datetime(self):
        msg = "no explicit representation of timezones available for " \
              "np.datetime64"
        with pytest.warns(UserWarning, match=msg):
            t0 = np.datetime64('2023-06-09T12:18:40Z', 'ns')

        t0 = np.datetime64('2023-06-09T12:18:40', 'ns')

    def test_datetime_dtype_creation(self):
        for unit in ['Y', 'M', 'W', 'D',
                     'h', 'm', 's', 'ms', 'us',

Review comment (bug):
On windows without installing `tzdata` creating a ZoneInfo object will fail. Perhaps you could do
```
try:
    ZoneInfo('US/Central')
    _has_tz = True
except zoneinfo.ZoneInfoNotFoundError:
    _has_tz = False
```

and then use it to skip the test below

Code after:
import datetime
import pickle
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError

import pytest

import numpy
import numpy as np
from numpy.testing import (
    IS_WASM,
    assert_,
    assert_array_equal,
    assert_equal,
    assert_raises,
    assert_raises_regex,
    assert_warns,
    suppress_warnings,
)

try:
    RecursionError
except NameError:
    RecursionError = RuntimeError  # python < 3.5

try:
    ZoneInfo("US/Central")
    _has_tz = True
except ZoneInfoNotFoundError:
    _has_tz = False

def _assert_equal_hash(v1, v2):
    assert v1 == v2
    assert hash(v1) == hash(v2)
    assert v2 in {v1}


class TestDateTime:

    def test_string(self):
        msg = "no explicit representation of timezones available for " \
              "np.datetime64"
        with pytest.warns(UserWarning, match=msg):
            np.datetime64('2000-01-01T00+01')

    def test_datetime(self):
        msg = "no explicit representation of timezones available for " \
              "np.datetime64"
        with pytest.warns(UserWarning, match=msg):
            t0 = np.datetime64('2023-06-09T12:18:40Z', 'ns')
Repository: numpy/numpy
File: numpy/lib/_index_tricks_impl.py (Python)

Code before:
    >>> 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)
    
    Notes
    -----
    New in version X.Y.Z.
    As of NumPy 2.3.0.dev0, this iterator is implemented using `itertools.product`
    from Python's standard library. This change provides significant improvements
    in both performance and and memory efficiency, particularly for large iteration
    spaces, while maintaining the original behavior and interface.

    """


    def __init__(self, *shape):
        if len(shape) == 1 and isinstance(shape[0], tuple):
            shape = shape[0]
        self.shape = shape
        self._iter = product(*(range(s) for s in shape))


    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.
        """

Review comment (suggestion):
repeated `and`; we'll probably want to change the version numbering you use above since i.e., `2.3.0` has already been released

Code after:
    (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]
        if min(shape, default=0) < 0:
            raise ValueError("negative dimensions are not allowed")
        self._iter = product(*map(range, shape))

    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.
Repository: numpy/numpy
File: numpy/lib/tests/test_index_tricks.py (Python)

Code before:

# 9. Empty Iterator Behavior
def test_ndindex_empty_iterator_behavior():
    """Test detailed behavior of empty iterators."""
    empty_iter = np.ndindex(0, 5)
    assert_equal(list(empty_iter), [])

    empty_iter2 = np.ndindex(3, 0, 2)
    with pytest.raises(StopIteration):
        next(empty_iter2)

# 10. Performance Regression
def test_ndindex_performance_regression():
    """Basic performance test to ensure no major regressions."""
    import time

    shape = (20, 30, 40)

    start_time = time.perf_counter()
    count = sum(1 for _ in np.ndindex(*shape))
    elapsed_time = time.perf_counter() - start_time

    expected_count = 20 * 30 * 40
    assert_equal(count, expected_count)

    assert elapsed_time < 1.0, f"ndindex took {elapsed_time:.3f}s, which seems slow"



Review comment (performance):
we don't usually do this in our testsuite--we typically guard against performance regressions using `asv` benchmarks separate from our regression tests proper (see my other comment about `asv`)

Code after:
        next(empty_iter2)


@pytest.mark.parametrize(
    "negative_shape_arg",
    [
        (-1,),  # Single negative dimension
        (2, -3, 4),  # Negative dimension in the middle
        (5, 0, -2),  # Mix of valid (0) and invalid (negative) dimensions
    ],
)
def test_ndindex_negative_dimensions(negative_shape_arg):
    """Test that negative dimensions raise ValueError."""
    with pytest.raises(ValueError):
        ndindex(negative_shape_arg)


def test_ndindex_empty_shape():
    import numpy as np
    # ndindex() and ndindex(()) should return a single empty tuple
    assert list(np.ndindex()) == [()]
    assert list(np.ndindex(())) == [()]

def test_ndindex_negative_dim_raises():
    # ndindex(-1) should raise a ValueError
    with pytest.raises(ValueError):
        list(np.ndindex(-1))