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
16 changes: 6 additions & 10 deletions optype/_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@


# same as from `typing_extensions._EXCLUDED_ATTRS`
_EXCLUDED_ATTRS: typing.Final = typing.cast(
"frozenset[str]",
frozenset(typing.EXCLUDED_ATTRIBUTES) # type: ignore[attr-defined] # pyright: ignore[reportUnknownMemberType, reportUnknownArgumentType, reportAttributeAccessIssue]
| {
"__match_args__",
"__protocol_attrs__",
"__non_callable_proto_members__",
"__final__",
},
)
_EXCLUDED_ATTRS: typing.Final = frozenset(getattr(typing, "EXCLUDED_ATTRIBUTES")) | { # noqa: B009
"__match_args__",
"__protocol_attrs__",
"__non_callable_proto_members__",
"__final__",
}


# same as `typing_extensions._get_protocol_attrs`
Expand Down
14 changes: 7 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["uv_build>=0.9.13,<0.10.0"]
requires = ["uv_build>=0.9.16,<0.10.0"]
build-backend = "uv_build"

[tool.uv.build-backend]
Expand Down Expand Up @@ -52,7 +52,7 @@ dependencies = ["typing-extensions>=4.10; python_version<'3.13'"]
[project.optional-dependencies]
numpy = [
"numpy>=1.25",
"numpy-typing-compat>=20250818.1.25,<20250819",
"numpy-typing-compat>=20250818.1.25,<20251207",
]

[project.urls]
Expand All @@ -68,21 +68,21 @@ extra = [
]
lint = [
"dprint-py>=0.50.2.0",
"ruff>=0.14.7",
"ruff>=0.14.8",
"sp-repo-review[cli]>=2025.11.21",
]
test = [
{ include-group = "extra" },
"beartype>=0.22.6",
"pytest>=9.0.1",
"beartype>=0.22.8",
"pytest>=9.0.2",
"typing-extensions>=4.15.0",
]
type = [
{ include-group = "extra" },
{ include-group = "test" },
"basedpyright>=1.34.0",
"basedpyright>=1.35.0",
"mypy[faster-cache]>=1.19.0",
"pyrefly==0.43.1",
"pyrefly==0.44.2",
]
dev = [
{ include-group = "extra" },
Expand Down
19 changes: 12 additions & 7 deletions tests/core/test_can.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ def test_can_add_same_int() -> None:
r0: op.CanAddSame[float] = x # type: ignore[assignment] # pyright: ignore[reportAssignmentType]
r1: op.CanAddSame[object] = x # type: ignore[assignment] # pyright: ignore[reportAssignmentType]

assert isinstance(x, op.CanAddSame)
assert issubclass(int, op.CanAddSame)
# https://github.com/facebook/pyrefly/issues/1783
assert isinstance(x, op.CanAddSame) # pyrefly:ignore[invalid-argument]
assert issubclass(int, op.CanAddSame) # pyrefly:ignore[invalid-argument]


def test_iadd() -> None:
Expand Down Expand Up @@ -181,15 +182,15 @@ def test_can_iadd_same_list_accept() -> None:
"""Ensure that `builtins.list` is assignable to `CanAddSame`."""
# acceptance tests (true negatives)
x: list[int] = [42]
assert isinstance(x, op.CanIAddSame)

a0: op.CanIAddSame = x
a1: op.CanIAddSame[Any] = x
a2: op.CanIAddSame[list[int]] = x
a3: op.CanIAddSame[bytes] = x

# https://github.com/facebook/pyrefly/issues/1164
assert issubclass(list, op.CanIAddSame)
# https://github.com/facebook/pyrefly/issues/1783
assert isinstance(x, op.CanIAddSame) # pyrefly:ignore[invalid-argument]
assert issubclass(list, op.CanIAddSame) # pyrefly:ignore[invalid-argument]


def test_can_iadd_same_list_reject() -> None:
Expand Down Expand Up @@ -228,8 +229,9 @@ def test_can_iter_int() -> None:
def test_can_iter_collection_str(
value: (str | tuple[str, ...] | list[str] | set[str] | dict[str, object]),
) -> None:
# sanity checks
assert isinstance(value, Collection)
# (in)sanity checks
# https://github.com/facebook/pyrefly/issues/1784
assert isinstance(value, Collection) # pyrefly:ignore[invalid-argument]
assert not isinstance(value, Iterator)

value_iter_next: op.CanIter[op.CanNext[str]] = value
Expand Down Expand Up @@ -271,6 +273,9 @@ def __len__(self, /) -> int:
def test_unsliceable_sequence() -> None:
seq_int_str: op.CanSequence[int, str] = UnsliceableSequence()
seq_wrong_str: op.CanSequence[slice, str] = UnsliceableSequence() # type: ignore[assignment] # pyright: ignore[reportAssignmentType]

# https://github.com/facebook/pyrefly/issues/1783
# pyrefly:ignore[invalid-argument]
assert isinstance(UnsliceableSequence, op.CanSequence)


Expand Down
5 changes: 3 additions & 2 deletions tests/numpy/test_ufunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def test_anyufunc_ufunc_type() -> None:
# purposefully wrong
tp_4_str: type[UFunc[Any, Any, Any, LiteralString]] = np.ufunc # type: ignore[assignment] # pyright: ignore[reportAssignmentType]

assert isinstance(tp, UFunc)
# https://github.com/facebook/pyrefly/issues/1783
assert isinstance(tp, UFunc) # pyrefly: ignore[invalid-argument]


def test_anyufunc_ufunc_11() -> None:
Expand Down Expand Up @@ -199,7 +200,7 @@ def test_anyufunc_gufunc21() -> None:
assert fn.nin == 2
assert fn.nout == 1
assert fn.nargs == 3
assert fn.signature is not None
assert fn.signature is not None # pyrefly:ignore[unnecessary-comparison]
assert fn.identity is None

# accepts either 2 or 3 positional-only arguments
Expand Down
6 changes: 4 additions & 2 deletions tests/test_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ def test_can_replace_date() -> None:
# pyrefly: ignore[bad-assignment]
d_copy_self: op.copy.CanReplaceSelf = d

assert isinstance(d, op.copy.CanReplace)
# https://github.com/facebook/pyrefly/issues/1783
assert isinstance(d, op.copy.CanReplace) # pyrefly: ignore[invalid-argument]
assert isinstance(d, op.copy.CanReplaceSelf)


Expand All @@ -106,5 +107,6 @@ def __replace__(self, /, *, val: int) -> Self:
# pyrefly: ignore[bad-assignment]
d_copy_self: op.copy.CanReplaceSelf = obj

assert isinstance(obj, op.copy.CanReplace)
# https://github.com/facebook/pyrefly/issues/1783
assert isinstance(obj, op.copy.CanReplace) # pyrefly: ignore[invalid-argument]
assert isinstance(obj, op.copy.CanReplaceSelf)
Loading