diff --git a/pyproject.toml b/pyproject.toml index 922637e49..7109ec4a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,7 +101,7 @@ name = "dycw-utilities" readme = "README.md" requires-python = ">= 3.13" - version = "0.169.4" + version = "0.169.3" [project.entry-points.pytest11] pytest-randomly = "utilities.pytest_plugins.pytest_randomly" @@ -135,7 +135,7 @@ # bump-my-version [tool.bumpversion] allow_dirty = true - current_version = "0.169.4" + current_version = "0.169.5" [[tool.bumpversion.files]] filename = "src/utilities/__init__.py" diff --git a/src/tests/test_objects/objects.py b/src/tests/test_objects/objects.py index 897e5610f..4833ea5ed 100644 --- a/src/tests/test_objects/objects.py +++ b/src/tests/test_objects/objects.py @@ -1,6 +1,6 @@ from __future__ import annotations -from enum import Enum, auto +from enum import Enum, StrEnum, auto from functools import partial from typing import Any @@ -223,3 +223,8 @@ class SubTuple(tuple): # noqa: SLOT001 class TruthEnum(Enum): true = auto() false = auto() + + +class TruthStrEnum(StrEnum): + true = auto() + false = auto() diff --git a/src/tests/test_typing.py b/src/tests/test_typing.py index 89437747b..add4178fc 100644 --- a/src/tests/test_typing.py +++ b/src/tests/test_typing.py @@ -14,7 +14,8 @@ Literal, NamedTuple, NotRequired, - _TypedDictMeta, # pyright: ignore[reportAttributeAccessIssue] + TypedDict, # pyright: ignore[reportAttributeAccessIssue] + _TypedDictMeta, assert_never, ) from uuid import UUID @@ -47,6 +48,7 @@ ZonedDateTime, ) +from tests.test_objects.objects import TruthEnum, TruthStrEnum from tests.test_typing_funcs.no_future import ( DataClassNoFutureNestedInnerFirstInner, DataClassNoFutureNestedInnerFirstOuter, @@ -134,6 +136,9 @@ from collections.abc import Callable +_NUM_CASES = 10 + + class TestGetArgs: @mark.parametrize( ("obj", "expected"), @@ -729,6 +734,18 @@ def test_others(self, *, obj: Any) -> None: assert not is_dataclass_instance(obj) +class TruthTypedDict(TypedDict): + truth: TruthEnum + + +class TruthTypedDictTrueOnly(TypedDict): + truth: Literal[TruthEnum.true] + + +class TruthTypedDictFalseOnly(TypedDict): + truth: Literal[TruthEnum.false] + + class TestIsInstanceGen: @given(data=data()) @mark.parametrize( @@ -737,19 +754,40 @@ class TestIsInstanceGen: # types - bool/int param(booleans(), bool, None, True), param(booleans(), int, 2, False), - param(integers(), bool, None, False), + param(integers(), bool, _NUM_CASES, False), param(integers(), int, None, True), param(booleans(), (bool, int), None, True), param(integers(), (bool, int), None, True), # types - datetime/date param(dates(), dt.date, None, True), - param(dates(), dt.datetime, None, False), - param(datetimes(), dt.date, None, False), + param(dates(), dt.datetime, _NUM_CASES, False), + param(datetimes(), dt.date, _NUM_CASES, False), param(datetimes(), dt.datetime, None, True), # parent union param(booleans(), Number, 2, False), param(integers(), Number, None, True), param(floats(), Number, None, True), + param( + just({"truth": TruthEnum.true}), + TruthTypedDict, + None, + True, + marks=mark.only, + ), + param( + just({"truth": TruthEnum.true}), + TruthTypedDictTrueOnly, + None, + True, + marks=mark.only, + ), + param( + just({"truth": TruthEnum.false}), + TruthTypedDictTrueOnly, + None, + False, + marks=mark.only, + ), # child tuple/union - skip # literals param(sampled_from([1, 2]), Literal[1, 2, 3], 2, True), @@ -762,6 +800,22 @@ class TestIsInstanceGen: param(sampled_from([1, "2", 3]), int | str, 3, True), param(sampled_from([1, "2", 3]), int, 3, False), param(sampled_from([1, "2", 3]), str, 3, False), + param(just(TruthEnum.true), TruthEnum, None, True, marks=mark.only), + param( + just(TruthEnum.true), + Literal[TruthEnum.true], + None, + True, + marks=mark.only, + ), + param(just(TruthStrEnum.true), TruthStrEnum, None, True, marks=mark.only), + param( + just(TruthStrEnum.true), + Literal[TruthStrEnum.true], + None, + True, + marks=mark.only, + ), param(booleans(), Literal[1, 2, 3], 2, False), param(text_ascii(), Literal["a", "b", "c"], 4, False), # tuple types @@ -776,7 +830,10 @@ class TestIsInstanceGen: param(tuples(just("a"), booleans()), tuple[Literal["a"], bool], None, True), param(tuples(just("a"), booleans()), tuple[Literal["a"], int], 2, False), param( - tuples(just("a"), integers()), tuple[Literal["a"], bool], None, False + tuples(just("a"), integers()), + tuple[Literal["a"], bool], + _NUM_CASES, + False, ), param(tuples(just("a"), integers()), tuple[Literal["a"], int], None, True), param( @@ -799,8 +856,8 @@ class TestIsInstanceGen: ), param(booleans(), tuple[bool], 2, False), param(booleans() | none(), tuple[bool], 3, False), - param(text_ascii(), tuple[bool], None, False), - param(text_ascii() | none(), tuple[bool], None, False), + param(text_ascii(), tuple[bool], _NUM_CASES, False), + param(text_ascii() | none(), tuple[bool], _NUM_CASES, False), ], ) def test_main( @@ -812,14 +869,18 @@ def test_main( min_size: int | None, expected: bool, ) -> None: - match expected: - case True: + match expected, min_size: + case True, None: value = data.draw(strategy) assert is_instance_gen(value, type_) - case False: - values = data.draw( - sets(strategy, min_size=10 if min_size is None else min_size) - ) + case True, int(): + values = data.draw(sets(strategy, min_size=min_size)) + assert all(is_instance_gen(v, type_) for v in values) + case False, None: + value = data.draw(strategy) + assert not is_instance_gen(value, type_) + case False, int(): + values = data.draw(sets(strategy, min_size=min_size)) assert not all(is_instance_gen(v, type_) for v in values) case never: assert_never(never) @@ -1069,6 +1130,17 @@ class TestIsSubclassGen: param(Literal[1, "2", 3], int | str, True), param(Literal[1, "2", 3], int, False), param(Literal[1, "2", 3], str, False), + param(Literal[TruthEnum.true], TruthEnum, True, marks=mark.only), + param( + Literal[TruthEnum.true], Literal[TruthEnum.true], True, marks=mark.only + ), + param(Literal[TruthStrEnum.true], TruthStrEnum, True, marks=mark.only), + param( + Literal[TruthStrEnum.true], + Literal[TruthStrEnum.true], + True, + marks=mark.only, + ), param(bool, Literal[1, 2, 3], False), param(str, Literal["a", "b", "c"], False), # tuple types diff --git a/src/utilities/__init__.py b/src/utilities/__init__.py index 20422c2d4..21a4e0c83 100644 --- a/src/utilities/__init__.py +++ b/src/utilities/__init__.py @@ -1,3 +1,3 @@ from __future__ import annotations -__version__ = "0.169.4" +__version__ = "0.169.3" diff --git a/uv.lock b/uv.lock index 14a0b6c41..5c810c32b 100644 --- a/uv.lock +++ b/uv.lock @@ -560,7 +560,7 @@ wheels = [ [[package]] name = "dycw-utilities" -version = "0.169.4" +version = "0.169.3" source = { editable = "." } dependencies = [ { name = "atomicwrites" },