Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ jobs:
uv run --no-sync
basedpyright -p scripts/config/bpr-np-${{ matrix.np }}.json

- name: basedmypy
run: uv run --no-sync scripts/bmp.py
- name: mypy
run: uv run --no-sync scripts/my.py

test:
timeout-minutes: 5
Expand Down
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
"editor.rulers": [88],
"git.branchProtection": ["master"],
"mypy-type-checker.args": [
"--ide",
"--config-file=${workspaceFolder}/pyproject.toml"
],
"mypy-type-checker.cwd": ".",
"mypy-type-checker.path": ["${workspaceFolder}/scripts/bmp.py"],
"mypy-type-checker.path": [
"${workspaceFolder}/scripts/my.py"
],
"python.testing.pytestEnabled": true
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
src="https://github.com/jorenham/optype/workflows/CI/badge.svg"
/>
</a>
<a href="https://github.com/KotlinIsland/basedmypy">
<a href="https://github.com/python/mypy">
<img
alt="optype - basedmypy"
src="https://img.shields.io/badge/basedmypy-checked-fd9002"
alt="scipy-stubs - mypy"
src="https://www.mypy-lang.org/static/mypy_badge.svg"
/>
</a>
<a href="https://detachhead.github.io/basedpyright">
Expand Down
2 changes: 1 addition & 1 deletion optype/_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __rewrite_module_names() -> None:

for module in [_can, _do, _does, _has, _just]:
for name in module.__all__:
member: type = getattr(module, name) # type: ignore[assignment]
member: type = getattr(module, name)
if member.__module__.startswith(name_self):
member.__module__ = name_base

Expand Down
2 changes: 1 addition & 1 deletion optype/_core/_can.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ class CanFormat(Protocol[_StrT_contra, _StrT_co]):
"""

@override
def __format__(self, fmt: _StrT_contra, /) -> _StrT_co: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
def __format__(self, fmt: _StrT_contra, /) -> _StrT_co: ... # pyright: ignore[reportIncompatibleMethodOverride]


# Iteration
Expand Down
20 changes: 10 additions & 10 deletions optype/_core/_do.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def __dir__() -> list[str]:
do_format: Final = cast("_d.DoesFormat", format)

# iteration
do_next: Final = cast("_d.DoesNext", next)
do_next: Final = next
do_iter: Final = cast("_d.DoesIter", iter)

# async iteration
Expand All @@ -137,13 +137,13 @@ def __dir__() -> list[str]:
# attributes
do_getattr: Final = cast("_d.DoesGetattr", getattr)
do_setattr: Final = cast("_d.DoesSetattr", setattr)
do_delattr: Final = cast("_d.DoesDelattr", delattr)
do_delattr: Final = delattr
do_dir: Final = cast("_d.DoesDir", dir)

# callables


do_call: Final = cast("_d.DoesCall", _o.call)
do_call: Final = _o.call

# containers and sequences

Expand Down Expand Up @@ -210,7 +210,7 @@ def do_contains(obj: _c.CanContains[_KT, _BoolT], key: _KT, /) -> _BoolT:
do_truediv: Final = cast("_d.DoesTruediv", _o.truediv)
do_floordiv: Final = cast("_d.DoesFloordiv", _o.floordiv)
do_mod: Final = cast("_d.DoesMod", _o.mod)
do_divmod: Final = cast("_d.DoesDivmod", divmod)
do_divmod: Final = divmod
do_pow: Final = cast("_d.DoesPow", pow)
do_lshift: Final = cast("_d.DoesLshift", _o.lshift)
do_rshift: Final = cast("_d.DoesRshift", _o.rshift)
Expand Down Expand Up @@ -314,19 +314,19 @@ def do_ror(a: _c.CanROr[_LeftT, _OutT], b: _LeftT, /) -> _OutT:
do_ior: Final = cast("_d.DoesIOr", _o.ior)

# unary ops
do_neg: Final = cast("_d.DoesNeg", _o.neg)
do_pos: Final = cast("_d.DoesPos", _o.pos)
do_abs: Final = cast("_d.DoesAbs", abs)
do_invert: Final = cast("_d.DoesInvert", _o.invert)
do_neg: Final = _o.neg
do_pos: Final = _o.pos
do_abs: Final = abs
do_invert: Final = _o.invert

# fingerprinting
do_hash: Final = cast("_d.DoesHash", hash)
do_hash: Final = hash
do_index: Final = cast("_d.DoesIndex", _o.index)

# rounding
# (the typeshed stubs for `round` are unnecessarily strict)
do_round: Final = cast("_d.DoesRound", round)
do_trunc: Final = cast("_d.DoesTrunc", math.trunc)
do_trunc: Final = math.trunc
do_floor: Final = cast("_d.DoesFloor", math.floor)
do_ceil: Final = cast("_d.DoesCeil", math.ceil)

Expand Down
2 changes: 1 addition & 1 deletion optype/_core/_has.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def typeof[TypeT: type](obj: HasClass[TypeT], /) -> TypeT: ...
the possible runtime outcomes of `typeof`, than that `type` does of itself.
"""

@property # type: ignore[explicit-override] # mypy bug
@property # type: ignore[override] # mypy bug
@override
def __class__(self) -> _TypeT: ...
@__class__.setter
Expand Down
2 changes: 1 addition & 1 deletion optype/_core/_just.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def __subclasscheck__(self, subclass: Any) -> TypeIs[type[_ObjectT]]:
tp = self.__just_class__

if isinstance(subclass, int):
# basedmypy "bare" bool and int literals
# "bare" bool and int literals
subclass = type(subclass)

if not isinstance(subclass, type):
Expand Down
2 changes: 1 addition & 1 deletion optype/numpy/ctypeslib.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
Complex128 = Never
CLongDouble = Never

from ._ctypeslib import CScalar, CType # type: ignore[type-check-only]
from ._ctypeslib import CScalar, CType

# ruff: noqa: RUF022
__all__ = [
Expand Down
17 changes: 4 additions & 13 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ dependencies = ["typing-extensions>=4.10; python_version<'3.13'"]
[dependency-groups]
extra = ["optype[numpy]"]
lint = [
"ruff>=0.11.11",
"ruff>=0.11.12",
"sp-repo-review[cli]>=2025.5.2",
]
type = [
"basedmypy[faster-cache]>=2.10.0",
"mypy[faster-cache]>=1.16.0",
"basedpyright>=1.29.2",
]
test = [
Expand Down Expand Up @@ -88,14 +88,10 @@ strict = true
allow_redefinition = true
disallow_any_expr = false
disallow_any_decorated = false
disallow_any_explicit = false # https://github.com/KotlinIsland/basedmypy/issues/861
disallow_any_explicit = false
disallow_untyped_defs = true
disallow_incomplete_defs = true
enable_error_code = [
"ignore-without-code",
"redundant-expr",
"truthy-bool",
]
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
local_partial_types = true
strict_bytes = true
warn_return_any = false
Expand All @@ -104,10 +100,6 @@ warn_unreachable = true
warn_unused_ignores = true
warn_incomplete_stub = true

# incompatible basedmypy features
default_return = false
bare_literals = false

[[tool.mypy.overrides]]
module = ["tests.*", "tests.numpy.*"]
disable_error_code = ["unreachable"]
Expand Down Expand Up @@ -154,7 +146,6 @@ xfail_strict = true
ignore = [
"PY004", # no `docs/` (maybe later)
"PY006", # no pre-commit
"PC140", # basedmypy > mypy
"PC170", # no sphinx
"PC180", # no css or js
"RTD", # no readthedocs
Expand Down
2 changes: 1 addition & 1 deletion scripts/bmp.py → scripts/my.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python

"""Run as `uv run scripts/bmp.py` from the repo root."""
"""Run as `uv run scripts/my.py` from the repo root."""

import subprocess
import sys
Expand Down
15 changes: 5 additions & 10 deletions tests/numpy/test_any_dtype.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import types
from typing import Any, Final, Never
from typing import Final, Never

import numpy as np
import pytest
Expand Down Expand Up @@ -43,22 +43,17 @@
_TIME_UNITS: Final = "as", "fs", "ps", "ns", "us", "s", "m", "h", "D", "W", "M", "Y"


# basedmypy 2.9.1 workaround
def _getattr(obj: object, attr: str, /) -> Any:
return getattr(obj, attr)


def _get_dtype_codes(
dtype: np.dtype[np.generic],
module: types.ModuleType = _dtype_attr,
) -> tuple[frozenset[str], frozenset[str]]:
try:
strcode = dtype.str[1:]
literal_name = _getattr(module, f"{strcode}_name")
literal_char = _getattr(module, f"{strcode}_char")
literal_name = getattr(module, f"{strcode}_name")
literal_char = getattr(module, f"{strcode}_char")
except AttributeError:
literal_name = _getattr(module, f"{dtype.char}_name")
literal_char = _getattr(module, f"{dtype.char}_char")
literal_name = getattr(module, f"{dtype.char}_name")
literal_char = getattr(module, f"{dtype.char}_char")

names = frozenset(() if literal_name is Never else literal_name.__args__)
chars = frozenset(() if literal_char is Never else literal_char.__args__)
Expand Down
2 changes: 1 addition & 1 deletion tests/numpy/test_ufunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def test_anyufunc_custom_py() -> None:
# purposefully wrong
fn = beta_py

assert isinstance(fn, Fn)
assert isinstance(fn, Fn) # type: ignore[arg-type] # https://github.com/python/mypy/issues/18796
assert callable(fn)

not_a_ufunc: UFunc = fn # type: ignore[assignment] # pyright: ignore[reportAssignmentType]
Expand Down
Loading