ronantakizawa/codereview-bench huggingface dataset:
Repository: numpy/numpy
File: numpy/typing/tests/data/pass/simple.py (Python)

Code before:

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

array = np.array([1, 2])

array.transpose()

array @ array

Review comment (suggestion):
This could use a trailing newline


```suggestion
array @ array

```

Code after:
"""Simple expression that should pass with mypy."""
import operator

import numpy as np
import numpy.typing as npt
from collections.abc import Iterable

# Basic checks
array = np.array([1, 2])


def ndarray_func(x: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
    return x


ndarray_func(np.array([1, 2], dtype=np.float64))
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.str_, 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.str_, 1)]
np.dtype(shape_like_dtype)

object_dtype = [("field1", object)]
np.dtype(object_dtype)

np.dtype((np.int32, (np.int8, 4)))

# Dtype comparison
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: Iterable[object]) -> Iterable[object]:
    return x


iterable_func(array)
list(array)
iter(array)
zip(array, array)
array[1]
array[:]
array[...]
array[:] = 0

array_2d = np.ones((3, 3))
array_2d[:2, :2]
array_2d[:2, :2] = 0
array_2d[..., 0]
array_2d[..., 0] = 2
array_2d[-1, -1] = None

array_obj = np.zeros(1, dtype=np.object_)
array_obj[0] = slice(None)

# Other special methods
len(array)
str(array)
array_scalar = np.array(1)
int(array_scalar)
float(array_scalar)
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
array.transpose()

array @ array
Repository: numpy/numpy
File: numpy/typing/tests/data/pass/simple.py (Python)

Code before:
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

array = np.array([1, 2])

array.transpose()

array @ array

Review comment (suggestion):
It's already defined this way on line 9, so this can go 

```suggestion
```

Code after:
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
array.transpose()

array @ array
Repository: numpy/numpy
File: tools/linter.py (Python)

Code before:
        res = subprocess.run(
            command,
            stdout=subprocess.PIPE,
            cwd=self.repository_root,
            encoding="utf-8",
        )
        return res.returncode, res.stdout

    def run_lint(self, fix: bool) -> None:
        retcode, errors = self.run_ruff(fix)

        errors and print(errors)

        # Running borrowed ref checker
        print("Running C API borrow-reference linter...")
        borrowed_ref_script = os.path.join(self.repository_root, "tools", "ci",
                                           "check_c_api_usage.sh")
        borrowed_res = subprocess.run(
            ["bash", borrowed_ref_script],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            encoding="utf-8",
        )

        print(borrowed_res.stdout)

        # Exit with non-zero if either Ruff or C API check fails
        final_code = retcode or borrowed_res.returncode
        sys.exit(final_code)


if __name__ == "__main__":
    parser = ArgumentParser()
    args = parser.parse_args()

    DiffLinter().run_lint(fix=False)


Review comment (suggestion):
This now looks oddly asymmetric between calling the `run_ruff` method for one linter check and then an inline invocation for the other check (also with asymmetric stdout/stderr handling). I suggest cleaning this up by using a `run_check_c_api` method and also making that return `return res.returncode, res.stdout`.

Code after:

        res = subprocess.run(
            command,
            stdout=subprocess.PIPE,
            cwd=self.repository_root,
            encoding="utf-8",
        )
        return res.returncode, res.stdout

    def run_lint(self, fix: bool) -> None:

        # Ruff Linter
        retcode, ruff_errors = self.run_ruff(fix)
        ruff_errors and print(ruff_errors)

        if retcode:
            sys.exit(retcode)

        # C API Borrowed-ref Linter
        retcode, c_API_errors = self.run_check_c_api()
        c_API_errors and print(c_API_errors)

        sys.exit(retcode)

    def run_check_c_api(self) -> tuple[int, str]:
        # Running borrowed ref checker
        print("Running C API borrow-reference linter...")
        borrowed_ref_script = os.path.join(self.repository_root, "tools", "ci",
                                           "check_c_api_usage.sh")
        borrowed_res = subprocess.run(
            ["bash", borrowed_ref_script],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            encoding="utf-8",
        )

        # Exit with non-zero if C API Check fails
        return borrowed_res.returncode, borrowed_res.stdout


if __name__ == "__main__":
    parser = ArgumentParser()
    args = parser.parse_args()

    DiffLinter().run_lint(fix=False)
Repository: numpy/numpy
File: numpy/_core/src/multiarray/number.c (C)

Code before:
        }

        if (exp == -1) {
            fastop = n_ops.reciprocal;
        }
        else if (exp == 2) {
            fastop = n_ops.square;
            is_square = 1;
        }
        else {
            return 1;
        }
    }
    else if (PyFloat_CheckExact(o2)) {
        double exp = PyFloat_AsDouble(o2);
        if (exp == 0.5) {
            fastop = n_ops.sqrt;
        }
        else {
            return 1;
        }
    }
    else {
        return 1;
    }

    PyArrayObject *a1 = (PyArrayObject *)o1;
    if (PyArray_ISOBJECT(a1)) {
        return 1;
    }
    if (!is_square && !PyArray_ISFLOAT(a1) && !PyArray_ISCOMPLEX(a1)) {
        // we special-case squaring for any array type
        // gh-29388
        return 1;
    }

    if (inplace || can_elide_temp_unary(a1)) {
        *result = PyArray_GenericInplaceUnaryFunction(a1, fastop);
    }
    else {
        *result = PyArray_GenericUnaryFunction(a1, fastop);
    }

    return 0;
}

static PyObject *
array_power(PyObject *a1, PyObject *o2, PyObject *modulo)
{
    PyObject *value = NULL;


Review comment (suggestion):
Thanks, yeah this seems right/safe to me.  I am not sure I see why `**2` confuses a custom `__array_ufunc__`, but I don't think this is an issue (and probably restores old behavior).  (If we had a bigger reason to keep it as is, I would be tempted to ask downstream to fix it there.)

Curious, does `**0.5` always end up with `sqrt()`?

---

(Maybe the nicer solution for at least `**2` would actually be to make the object `square` implementation use `**2` internally then this special case wouldn't even be needed.  But no priority so if, let's do that as a follow-up.)

Code after:

        if (exp == -1) {
            fastop = n_ops.reciprocal;
        }
        else if (exp == 2) {
            fastop = n_ops.square;
        }
        else {
            return 1;
        }
    }
    else if (PyFloat_CheckExact(o2)) {
        double exp = PyFloat_AsDouble(o2);
        if (exp == 0.5) {
            fastop = n_ops.sqrt;
        }
        else {
            return 1;
        }
    }
    else {
        return 1;
    }

    PyArrayObject *a1 = (PyArrayObject *)o1;
    if (PyArray_ISOBJECT(a1)) {
        return 1;
    }
    if (fastop != n_ops.square && !PyArray_ISFLOAT(a1) && !PyArray_ISCOMPLEX(a1)) {
        // we special-case squaring for any array type
        // gh-29388
        return 1;
    }

    if (inplace || can_elide_temp_unary(a1)) {
        *result = PyArray_GenericInplaceUnaryFunction(a1, fastop);
    }
    else {
        *result = PyArray_GenericUnaryFunction(a1, fastop);
    }

    return 0;
}

static PyObject *
array_power(PyObject *a1, PyObject *o2, PyObject *modulo)
{
    PyObject *value = NULL;

    if (modulo != Py_None) {
        /* modular exponentiation is not implemented (gh-8804) */
Repository: numpy/numpy
File: numpy/_core/src/multiarray/number.c (C)

Code before:
        else if (exp == 2) {
            fastop = n_ops.square;
            is_square = 1;
        }
        else {
            return 1;
        }
    }
    else if (PyFloat_CheckExact(o2)) {
        double exp = PyFloat_AsDouble(o2);
        if (exp == 0.5) {
            fastop = n_ops.sqrt;
        }
        else {
            return 1;
        }
    }
    else {
        return 1;
    }

    PyArrayObject *a1 = (PyArrayObject *)o1;
    if (PyArray_ISOBJECT(a1)) {
        return 1;
    }
    if (!is_square && !PyArray_ISFLOAT(a1) && !PyArray_ISCOMPLEX(a1)) {
        // we special-case squaring for any array type
        // gh-29388
        return 1;
    }

    if (inplace || can_elide_temp_unary(a1)) {
        *result = PyArray_GenericInplaceUnaryFunction(a1, fastop);
    }
    else {
        *result = PyArray_GenericUnaryFunction(a1, fastop);
    }

    return 0;
}

static PyObject *
array_power(PyObject *a1, PyObject *o2, PyObject *modulo)
{
    PyObject *value = NULL;

    if (modulo != Py_None) {
        /* modular exponentiation is not implemented (gh-8804) */
        Py_INCREF(Py_NotImplemented);
        return Py_NotImplemented;
    }

Review comment (refactor):
Actually, sorry should have looked closer.  This is either square or sqrt.  Maybe we can just remove this branch also for `sqrt`?
Or would that change behavior drastically from the original version?  (I think I would lean towards that.

(If not, it may be nice to just use `fastop != nops.square` rather than introducing a new variable, but nitpicking.)

Code after:
            fastop = n_ops.square;
        }
        else {
            return 1;
        }
    }
    else if (PyFloat_CheckExact(o2)) {
        double exp = PyFloat_AsDouble(o2);
        if (exp == 0.5) {
            fastop = n_ops.sqrt;
        }
        else {
            return 1;
        }
    }
    else {
        return 1;
    }

    PyArrayObject *a1 = (PyArrayObject *)o1;
    if (PyArray_ISOBJECT(a1)) {
        return 1;
    }
    if (fastop != n_ops.square && !PyArray_ISFLOAT(a1) && !PyArray_ISCOMPLEX(a1)) {
        // we special-case squaring for any array type
        // gh-29388
        return 1;
    }

    if (inplace || can_elide_temp_unary(a1)) {
        *result = PyArray_GenericInplaceUnaryFunction(a1, fastop);
    }
    else {
        *result = PyArray_GenericUnaryFunction(a1, fastop);
    }

    return 0;
}

static PyObject *
array_power(PyObject *a1, PyObject *o2, PyObject *modulo)
{
    PyObject *value = NULL;

    if (modulo != Py_None) {
        /* modular exponentiation is not implemented (gh-8804) */
        Py_INCREF(Py_NotImplemented);
        return Py_NotImplemented;
    }

    BINOP_GIVE_UP_IF_NEEDED(a1, o2, nb_power, array_power);
Repository: numpy/numpy
File: numpy/_core/src/multiarray/iterators.c (C)

Code before:
    for (i = 0; i < n; ++i) {
        args_impl[i] = va_arg(va, PyObject *);
    }
    va_end(va);

    return multiiter_new_impl(n, args_impl);
}


static PyObject*
arraymultiter_new(PyTypeObject *NPY_UNUSED(subtype), PyObject *args,
                  PyObject *kwds)
{
    PyObject *ret, *fast_seq;
    Py_ssize_t n;

    if (kwds != NULL && PyDict_Size(kwds) > 0) {
        PyErr_SetString(PyExc_ValueError,
                        "keyword arguments not accepted.");
        return NULL;
    }
    fast_seq = PySequence_Fast(args, "");  // noqa: borrowed-ref OK
    if (fast_seq == NULL) {
        return NULL;
    }
    NPY_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(args)
    n = PySequence_Fast_GET_SIZE(fast_seq);
    if (n > NPY_MAXARGS) {
        ret = multiiter_wrong_number_of_args();
    } else {
        ret = multiiter_new_impl(n, PySequence_Fast_ITEMS(fast_seq));
    }
    Py_DECREF(fast_seq);
    NPY_END_CRITICAL_SECTION_SEQUENCE_FAST()
    return ret;
}

static PyObject *
arraymultiter_next(PyArrayMultiIterObject *multi)
{
    PyObject *ret;
    int i, n;

    n = multi->numiter;
    ret = PyTuple_New(n);
    if (ret == NULL) {
        return NULL;
    }
    if (multi->index < multi->size) {
        for (i = 0; i < n; i++) {
            PyArrayIterObject *it=multi->iters[i];

Review comment (suggestion):
```suggestion
    NPY_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(fast_seq)
```

Code after:
    for (i = 0; i < n; ++i) {
        args_impl[i] = va_arg(va, PyObject *);
    }
    va_end(va);

    return multiiter_new_impl(n, args_impl);
}


static PyObject*
arraymultiter_new(PyTypeObject *NPY_UNUSED(subtype), PyObject *args,
                  PyObject *kwds)
{
    PyObject *ret, *fast_seq;
    Py_ssize_t n;

    if (kwds != NULL && PyDict_Size(kwds) > 0) {
        PyErr_SetString(PyExc_ValueError,
                        "keyword arguments not accepted.");
        return NULL;
    }
    fast_seq = PySequence_Fast(args, "");  // noqa: borrowed-ref OK
    if (fast_seq == NULL) {
        return NULL;
    }
    NPY_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(fast_seq)
    n = PySequence_Fast_GET_SIZE(fast_seq);
    if (n > NPY_MAXARGS) {
        ret = multiiter_wrong_number_of_args();
    } else {
        ret = multiiter_new_impl(n, PySequence_Fast_ITEMS(fast_seq));
    }
    Py_DECREF(fast_seq);
    NPY_END_CRITICAL_SECTION_SEQUENCE_FAST()
    return ret;
}

static PyObject *
arraymultiter_next(PyArrayMultiIterObject *multi)
{
    PyObject *ret;
    int i, n;

    n = multi->numiter;
    ret = PyTuple_New(n);
    if (ret == NULL) {
        return NULL;
    }
    if (multi->index < multi->size) {
        for (i = 0; i < n; i++) {
            PyArrayIterObject *it=multi->iters[i];
Repository: numpy/numpy
File: numpy/ma/core.pyi (Python)

Code before:
# pyright: reportIncompatibleMethodOverride=false
# ruff: noqa: ANN001, ANN002, ANN003, ANN201, ANN202 ANN204, ANN401

from _typeshed import Incomplete
from collections.abc import Sequence
from typing import (
    Any,
    Literal,
    Never,
    NoReturn,
    Self,
    SupportsIndex,
    TypeAlias,
    overload,
)
from typing_extensions import TypeIs, TypeVar

import numpy as np
from numpy import (
    _AnyShapeT,
    _HasDTypeWithRealAndImag,
    _ModeKind,
    _OrderKACF,
    _OrderACF,
    _PartitionKind,
    _SortKind,
    amax,
    amin,
    bool_,
    bytes_,
    character,
    complex128,
    complexfloating,
    datetime64,
    dtype,
    dtypes,
    expand_dims,
    float16,
    float32,
    float64,
    floating,
    generic,
    inexact,
    int8,
    int64,
    int_,
    integer,
    intp,
    ndarray,

Review comment (suggestion):
```suggestion
    _OrderACF,
    _OrderKACF,
```

Code after:
# pyright: reportIncompatibleMethodOverride=false
# ruff: noqa: ANN001, ANN002, ANN003, ANN201, ANN202 ANN204, ANN401

from _typeshed import Incomplete
from collections.abc import Sequence
from typing import (
    Any,
    Literal,
    Never,
    NoReturn,
    Self,
    SupportsIndex,
    TypeAlias,
    overload,
)
from typing_extensions import TypeIs, TypeVar

import numpy as np
from numpy import (
    _AnyShapeT,
    _HasDType,
    _HasDTypeWithRealAndImag,
    _ModeKind,
    _OrderACF,
    _OrderKACF,
    _PartitionKind,
    _SortKind,
    amax,
    amin,
    bool_,
    bytes_,
    character,
    complex128,
    complexfloating,
    datetime64,
    dtype,
    dtypes,
    expand_dims,
    float16,
    float32,
    float64,
    floating,
    generic,
    inexact,
    int8,
    int64,
    int_,
    integer,
    intp,
Repository: numpy/numpy
File: tools/write_release.py (Python)

Code before:
            Checksums
            =========

            MD5
            ---
            ::

            """))
        f.writelines([f'    {c}\n' for c in compute_hash(wheel_dir, md5)])

        f.writelines(textwrap.dedent(
            """
            SHA256
            ------
            ::

            """))
        f.writelines([f'    {c}\n' for c in compute_hash(wheel_dir, sha256)])

    # translate README.rst to md for posting on GitHub
    rst_to_md = subprocess.Popen(
        ["pandoc", "-s", "-o", f"{target_md}", f"{target_rst}", "--wrap=preserve"],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output, error = rst_to_md.communicate()
    if not rst_to_md.returncode == 0:
        raise RuntimeError(f"{error} failed")
 
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "version",
        help="NumPy version of the release, e.g. 2.3.2, etc.")

    args = parser.parse_args()
    write_release(args.version)


Review comment (bug):
This could be simplified a bit with `subprocess.run` (available since Python 3.5), e.g. like

```suggestion
    subprocess.run(
        ["pandoc", "-s", "-o", str(target_md), str(target_rst), "--wrap=preserve"],
        check=True,
    )
```

Or if you only want to print the stderr on non-zero exit codes, you could do something like

```suggestion
    rst_to_md = subprocess.run(
        ["pandoc", "-s", "-o", str(target_md), str(target_rst), "--wrap=preserve"],
        capture_output=True,
        text=True,
    )
    try:
        rst_to_md.check_returncode()
    except subprocess.CalledProcessError as e:
        raise RuntimeError(f"failed: \n{rst_to_md.stderr}") from e
```

Code after:

            MD5
            ---
            ::

            """))
        f.writelines([f'    {c}\n' for c in compute_hash(wheel_dir, md5)])

        f.writelines(textwrap.dedent(
            """
            SHA256
            ------
            ::

            """))
        f.writelines([f'    {c}\n' for c in compute_hash(wheel_dir, sha256)])

    # translate README.rst to md for posting on GitHub
    subprocess.run(
        ["pandoc", "-s", "-o", str(target_md), str(target_rst), "--wrap=preserve"],
        check=True,
    )


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "version",
        help="NumPy version of the release, e.g. 2.3.2, etc.")

    args = parser.parse_args()
    write_release(args.version)
Repository: numpy/numpy
File: tools/write_release.py (Python)

Code before:
OUTPUT_FILE = "README"

def compute_hash(wheel_dir, hash_func):
    """
    Compute hashes of files in wheel_dir.

    Parameters
    ----------
    wheel_dir: str
        Path to wheel directory from repo root.
    hash_func: function
        Hash function, i.e., md5, sha256, etc.

    Returns
    -------
    list_of_strings: list
        List of of strings. Each string is the hash
        followed by the file basename.

    """
    released = os.listdir(wheel_dir)
    checksums = []
    for fn in sorted(released):
        fn_path = Path(f"{wheel_dir}/{fn}") 
        with open(fn_path, 'rb') as f:
            m = hash_func(f.read())
        checksums.append(f"{m.hexdigest()}  {fn}")
    return checksums


def write_release(version):
    """
    Copy the <version>-notes.rst file to the OUTPUT_DIR, append
    the md5 and sha256 hashes of the wheels and sdist, and produce
    README.rst and README.md files.

    Parameters
    ----------
    version: str
       Release version, e.g., '2.3.2', etc.

    Returns
    -------
    None.

    """
    notes = Path(f"{NOTES_DIR}/{version}-notes.rst")
    wheel_dir = Path(f"{OUTPUT_DIR}/installers")
    target_md = Path(f"{OUTPUT_DIR}/{OUTPUT_FILE}.md")
    target_rst = Path(f"{OUTPUT_DIR}/{OUTPUT_FILE}.rst")
    

Review comment (suggestion):
nitpick:

```suggestion
        m = hash_func(fn_path.read_bytes())
```

Code after:

def compute_hash(wheel_dir, hash_func):
    """
    Compute hashes of files in wheel_dir.

    Parameters
    ----------
    wheel_dir: str
        Path to wheel directory from repo root.
    hash_func: function
        Hash function, i.e., md5, sha256, etc.

    Returns
    -------
    list_of_strings: list
        List of of strings. Each string is the hash
        followed by the file basename.

    """
    released = os.listdir(wheel_dir)
    checksums = []
    for fn in sorted(released):
        fn_path = Path(f"{wheel_dir}/{fn}")
        m = hash_func(fn_path.read_bytes())
        checksums.append(f"{m.hexdigest()}  {fn}")
    return checksums


def write_release(version):
    """
    Copy the <version>-notes.rst file to the OUTPUT_DIR, append
    the md5 and sha256 hashes of the wheels and sdist, and produce
    README.rst and README.md files.

    Parameters
    ----------
    version: str
       Release version, e.g., '2.3.2', etc.

    Returns
    -------
    None.

    """
    notes = Path(NOTES_DIR) / f"{version}-notes.rst"
    wheel_dir = Path(OUTPUT_DIR) / "installers"
    target_md = Path(OUTPUT_DIR) / f"{OUTPUT_FILE}.md"
    target_rst = Path(OUTPUT_DIR) / f"{OUTPUT_FILE}.rst"

    os.system(f"cp {notes} {target_rst}")