Source code for jgdv.structs.strang._meta

  1#!/usr/bin/env python3
  2"""
  3
  4"""
  5# Imports:
  6from __future__ import annotations
  7
  8# ##-- stdlib imports
  9import datetime
 10import enum
 11import functools as ftz
 12import itertools as itz
 13import logging as logmod
 14import re
 15import time
 16import types
 17import collections
 18import contextlib
 19import hashlib
 20from copy import deepcopy
 21from uuid import UUID, uuid1
 22from weakref import ref
 23import atexit # for @atexit.register
 24import faulthandler
 25# ##-- end stdlib imports
 26
 27from . import errors
 28
 29# ##-- types
 30# isort: off
 31import abc
 32import collections.abc
 33import typing
 34from typing import TYPE_CHECKING, cast, assert_type, assert_never
 35from typing import Generic, NewType, Never
 36# Protocols:
 37from typing import Protocol, runtime_checkable
 38# Typing Decorators:
 39from typing import no_type_check, final, override, overload
 40
 41if TYPE_CHECKING:
 42    import pathlib as pl
 43    from jgdv import Maybe
 44    from typing import Final
 45    from typing import ClassVar, Any, LiteralString
 46    from typing import Self, Literal
 47    from typing import TypeGuard
 48    from collections.abc import Iterable, Iterator, Callable, Generator
 49    from collections.abc import Sequence, Mapping, MutableMapping, Hashable
 50
 51    from ._interface import Strang_p
 52    from jgdv._abstract.protocols.pre_processable import PreProcessor_p, PreProcessResult, InstanceData, PostInstanceData
 53##--|
 54
 55# isort: on
 56# ##-- end types
 57
 58##-- logging
 59logging = logmod.getLogger(__name__)
 60##-- end logging
 61
 62# Vars:
 63StrMeta      : Final[type]  = type(str)
 64HasDictFail  : Final[str]   = "The resulting strang has a __dict__. Set the subclass to have __slots__=()"
 65# Body:
 66
[docs] 67class StrangMeta(StrMeta): 68 """ A Metaclass for Strang 69 It runs the pre-processsing and post-processing on the constructed str 70 to turn it into a strang 71 """ 72 73 def __call__[T:Strang_p](cls:type[T], text:str|pl.Path, *args:Any, **kwargs:Any) -> Strang_p: # noqa: ANN401, N805 74 """ Overrides normal str creation to allow passing args to init """ 75 ctor : type[T] 76 obj : T 77 processor : PreProcessor_p[T] = cls._processor 78 stage : str = "Pre-Process" 79 80 try: 81 text, inst_data, post_data, new_ctor = processor.pre_process(cls, 82 text, 83 *args, 84 strict=kwargs.pop("strict", False), 85 **kwargs, 86 ) 87 ctor = new_ctor or cls 88 assert(isinstance(ctor, type|typing.GenericAlias)), ctor # type: ignore[attr-defined] 89 stage = "__new__" 90 obj = ctor.__new__(ctor, text) 91 stage = "__init__" 92 obj.__init__(*args, **collections.ChainMap(inst_data, kwargs)) # type: ignore[misc] 93 stage = "Process" 94 obj = processor.process(obj, data=post_data) or obj 95 stage = "Post-Process" 96 obj = processor.post_process(obj, data=post_data) or obj 97 except TypeError as err: 98 raise errors.StrangError(errors.StrangCtorFailure.format(cls=cls.__name__, stage=stage), 99 err, text, cls, processor) from None 100 except ValueError as err: 101 raise errors.StrangError(errors.StrangCtorFailure.format(cls=cls.__name__, stage=stage), 102 err, text, cls, processor) from None 103 else: 104 assert(isinstance(obj, str)) 105 if hasattr(obj, "__dict__"): 106 raise ValueError(HasDictFail, type(obj)) 107 return obj
108