diff --git a/instruct/__init__.py b/instruct/__init__.py index 5cc7eb3..db7fe18 100644 --- a/instruct/__init__.py +++ b/instruct/__init__.py @@ -15,9 +15,6 @@ from base64 import urlsafe_b64encode from collections.abc import ( Mapping as AbstractMapping, - Sequence, - ItemsView as _ItemsView, - Set as AbstractSet, Iterable as AbstractIterable, KeysView as AbstractKeysView, ValuesView as AbstractValuesView, @@ -71,6 +68,7 @@ TypingDefinition, ) from .typing import ( + Atomic, CellType, NoneType, TypeHint, @@ -81,24 +79,23 @@ CustomTypeCheck, Self, typevar_has_no_default, + T, + CoerceMapping, ) -from .typing import T, CellType, CoerceMapping, NoneType from .types import ( FrozenMapping, AttrsDict, ClassOrInstanceFuncsDescriptor, mark, getmarks, - AtomicImpl, + BaseAtomic, ImmutableValue, ImmutableMapping, ImmutableCollection, - IAtomic, + AbstractAtomic, InstanceCallable, Genericizable, ) -from .typing import Atomic -from .types import ReadOnly from .utils import flatten_fields, invert_mapping from .subtype import wrapper_for_type from .exceptions import ( @@ -262,9 +259,9 @@ def __post_init__(self) -> None: def supports_post_init_protocol(item: Union[Type[Atomic], Atomic]) -> TypeGuard[SupportsPostInit]: - if isinstance(item, AtomicImpl): + if isinstance(item, BaseAtomic): return hasattr(item, "__post_init__") - if isinstance(item, type) and issubclass(item, AtomicImpl): + if isinstance(item, type) and issubclass(item, BaseAtomic): return hasattr(item, "__post_init__") return False @@ -664,15 +661,6 @@ def _dump_skipped_fields(instance_or_cls): return skipped_fields(instance_or_cls) -class ItemsView(_ItemsView): - __slots__ = () - if TYPE_CHECKING: - _mapping: Mapping[str, Any] - - def __iter__(self): - yield from self._mapping - - def make_fast_clear(fields, set_block, class_name): set_block = set_block.format(key="%(key)s") code_template = env.get_template("fast_clear.jinja").render( @@ -992,7 +980,7 @@ class Py311Code(Protocol): def insert_class_closure( - klass: Type[AtomicImpl], function: Optional[Callable[..., Any]] + klass: Type[BaseAtomic], function: Optional[Callable[..., Any]] ) -> Optional[Callable[..., Any]]: """ an implicit super() works by looking at __class__ to fill in the @@ -1523,10 +1511,10 @@ def __init_subclass__(cls, **kwargs): return __init_subclass__ -class AtomicMeta(IAtomic, type, Generic[Atomic]): +class AtomicMeta(AbstractAtomic, type, Generic[Atomic]): __slots__ = () - REGISTRY = ImmutableCollection[Set[Type[AtomicImpl]]](set()) - MIXINS = ImmutableMapping[str, AtomicImpl]({}) + REGISTRY = ImmutableCollection[Set[Type[BaseAtomic]]](set()) + MIXINS = ImmutableMapping[str, BaseAtomic]({}) SKIPPED_FIELDS: Mapping[ Tuple[str, FrozenMapping[str, None]], Type[Atomic] ] = WeakValueDictionary() @@ -1558,7 +1546,7 @@ def __len__(self): return len(self._columns) def __and__( - self: IAtomic, + self: AbstractAtomic, include: Union[Set[str], List[str], Tuple[str], FrozenSet[str], str, Dict[str, Any]], ) -> Type[Atomic]: assert isinstance(include, (list, frozenset, set, tuple, dict, str, FrozenMapping)) @@ -1572,7 +1560,9 @@ def __and__( ) return cast(Type[Atomic], self - skip_fields) - def __sub__(self: IAtomic, skip: Union[Mapping[str, Any], Iterable[Any]]) -> Type[Atomic]: + def __sub__( + self: AbstractAtomic, skip: Union[Mapping[str, Any], Iterable[Any]] + ) -> Type[Atomic]: assert isinstance(skip, (list, frozenset, set, tuple, dict, str, FrozenMapping)) debug_mode = is_debug_mode("skip") @@ -1712,8 +1702,8 @@ def __new__( # ARJ: Used to create an "anchor"-base type that just marks # that this is now an "Atomic"-type (b/c there aren't good ways to express all # members of a metaclass in a type-hint, so we make an anchor). - if AtomicImpl not in bases: - bases = (*bases, AtomicImpl) + if BaseAtomic not in bases: + bases = (*bases, BaseAtomic) assert isinstance( skip_fields, FrozenMapping @@ -1916,7 +1906,7 @@ def __new__( pending_support_columns.extend(list(cls.__extra_slots__)) if ismetasubclass(cls, AtomicMeta): - parent_atomic: Type[AtomicImpl] = cast(Type[AtomicImpl], cls) + parent_atomic: Type[BaseAtomic] = cast(Type[BaseAtomic], cls) # Only AtomicMeta Descendants will merge in the helpers of # _columns: Dict[str, Type] if parent_atomic._annotated_metadata: @@ -2138,7 +2128,7 @@ def __new__( support_columns = tuple(_dedupe(pending_support_columns)) dataclass_attrs = {"NoneType": NoneType, "Flags": Flags, "typing": typing} - dataclass_attrs[class_name] = ImmutableValue[Optional[Type[AtomicImpl]]](None) + dataclass_attrs[class_name] = ImmutableValue[Optional[Type[BaseAtomic]]](None) init_subclass = None @@ -2271,12 +2261,12 @@ def __new__( annotated_metadata ) support_cls_attrs["_nested_atomic_collection_keys"] = ImmutableMapping[ - str, Tuple[Type[AtomicImpl], ...] + str, Tuple[Type[BaseAtomic], ...] ](nested_atomic_collections) support_cls_attrs["_skipped_fields"] = skip_fields if "_modified_fields" not in support_cls_attrs: support_cls_attrs["_modified_fields"] = () - conf = AttrsDict[Type[AtomicImpl]](**mixins) + conf = AttrsDict[Type[BaseAtomic]](**mixins) conf["fast"] = fast extra_slots = tuple(_dedupe(pending_extra_slots)) support_cls_attrs["__extra_slots__"] = ImmutableCollection[str](extra_slots) @@ -2285,7 +2275,7 @@ def __new__( support_cls_attrs["_all_accessible_fields"] = ImmutableCollection[str]( tuple(field for field in chain(combined_columns, properties)) ) - support_cls_attrs["_configuration"] = ImmutableMapping[str, Type[AtomicImpl]](conf) + support_cls_attrs["_configuration"] = ImmutableMapping[str, Type[BaseAtomic]](conf) support_cls_attrs["_listener_funcs"] = ImmutableMapping[str, Iterable[Callable]](listeners) # Ensure public class has zero slots! @@ -2316,10 +2306,10 @@ def __new__( support_cls_attrs["__init_subclass__"] = classmethod(wrap_init_subclass(init_subclass)) support_cls_attrs["_data_class"] = support_cls_attrs[f"_{class_name}"] = cast( - ImmutableValue[Type[AtomicImpl]], dc + ImmutableValue[Type[BaseAtomic]], dc ) support_cls_attrs["_parent"] = parent_cell = cast( - ImmutableValue[Type[AtomicImpl]], dc_parent + ImmutableValue[Type[BaseAtomic]], dc_parent ) support_cls = cast( Type[Atomic], diff --git a/instruct/typedef.py b/instruct/typedef.py index c6634e2..6e86ac9 100644 --- a/instruct/typedef.py +++ b/instruct/typedef.py @@ -54,7 +54,7 @@ ) from .utils import flatten_restrict as flatten from .exceptions import RangeError, TypeError as InstructTypeError -from .types import IAtomic +from .types import AbstractAtomic T = TypeVar("T") U = TypeVar("U") @@ -648,7 +648,7 @@ def test_func_literal(value: Union[Any, T]) -> TypeGuard[T]: arg_type = arg else: arg_type = type(arg) - if isinstance(arg_type, IAtomic): + if isinstance(arg_type, AbstractAtomic): arg_type = public_class( cast(Type["Atomic"], arg_type), preserve_subtraction=True ) diff --git a/instruct/types.py b/instruct/types.py index 9eb8dfd..e7098d7 100644 --- a/instruct/types.py +++ b/instruct/types.py @@ -110,12 +110,12 @@ def getmarks(func, *names, default=None): return tuple(results) -class IAtomic: +class AbstractAtomic: __slots__ = () if TYPE_CHECKING: - REGISTRY: ImmutableCollection[Set[Type[AtomicImpl]]] - MIXINS: ImmutableMapping[str, AtomicImpl] + REGISTRY: ImmutableCollection[Set[Type[BaseAtomic]]] + MIXINS: ImmutableMapping[str, BaseAtomic] BINARY_JSON_ENCODERS: Dict[str, Callable[[Union[bytearray, bytes]], Any]] _set_defaults: Callable[[], None] @@ -126,16 +126,16 @@ class IAtomic: _all_coercions: ImmutableMapping[str, Tuple[Union[TypingDefinition, Type], Callable]] _support_columns: Tuple[str, ...] _annotated_metadata: ImmutableMapping[str, Tuple[Any, ...]] - _nested_atomic_collection_keys: ImmutableMapping[str, Tuple[Type[AtomicImpl], ...]] + _nested_atomic_collection_keys: ImmutableMapping[str, Tuple[Type[BaseAtomic], ...]] _skipped_fields: FrozenMapping[str, None] _modified_fields: FrozenSet[str] _properties: KeysView[str] - _configuration: ImmutableMapping[str, Type[AtomicImpl]] + _configuration: ImmutableMapping[str, Type[BaseAtomic]] __extra_slots__: ImmutableCollection[str] _all_accessible_fields: ImmutableCollection[KeysView[str]] _listener_funcs: ImmutableMapping[str, Iterable[Callable]] - _data_class: ImmutableValue[Type[AtomicImpl]] - _parent: ImmutableValue[Type[AtomicImpl]] + _data_class: ImmutableValue[Type[BaseAtomic]] + _parent: ImmutableValue[Type[BaseAtomic]] def __iter__(self) -> Iterator[Tuple[str, Any]]: ... @@ -227,7 +227,7 @@ def __class_getitem__(self, key): raise TypeError(f"{self} is not a generic class") -class AtomicImpl(IAtomic): +class BaseAtomic(AbstractAtomic): __slots__ = () @mark(base_cls=True) diff --git a/instruct/typing.py b/instruct/typing.py index 7fe0ccc..e03bb2c 100644 --- a/instruct/typing.py +++ b/instruct/typing.py @@ -80,14 +80,14 @@ def bar(): CellType = type(foo().__closure__[0]) del foo -from .types import AtomicImpl, IAtomic +from .types import BaseAtomic, AbstractAtomic NoneType = type(None) CoerceMapping = Dict[str, Tuple[Union[Type, Tuple[Type, ...]], Callable]] Annotated TypedDict -IAtomic +AbstractAtomic Unpack Required NotRequired @@ -246,7 +246,7 @@ def isabstractcollectiontype( TypeHint: TypeAlias = Union[TypingDefinition, Type] -Atomic = TypeVar("Atomic", bound=AtomicImpl) +Atomic = TypeVar("Atomic", bound=BaseAtomic) if sys.version_info[:2] >= (3, 13): diff --git a/tests/test_atomic.py b/tests/test_atomic.py index a5c7b05..816b9d2 100644 --- a/tests/test_atomic.py +++ b/tests/test_atomic.py @@ -17,7 +17,7 @@ import pytest import instruct import inflection -from instruct.types import IAtomic +from instruct.types import AbstractAtomic from instruct import ( public_class, Base, @@ -62,8 +62,8 @@ class Data(SimpleBase): "baz": Dict[str, Any], "cool": int, } - assert isinstance(Data, IAtomic) - assert isinstance(Data(), IAtomic) + assert isinstance(Data, AbstractAtomic) + assert isinstance(Data(), AbstractAtomic) class Data(Base, history=True):