diff --git a/src/adaptix/_internal/morphing/concrete_provider.py b/src/adaptix/_internal/morphing/concrete_provider.py index 04e1e3e9..025bd6ed 100644 --- a/src/adaptix/_internal/morphing/concrete_provider.py +++ b/src/adaptix/_internal/morphing/concrete_provider.py @@ -213,7 +213,7 @@ class SecondsTimedeltaProvider(MorphingProvider): def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: return mediator.cached_call(self._make_loader) - + def _make_loader(self): ok_types = self._OK_TYPES @@ -244,13 +244,13 @@ def none_loader(data): class NoneProvider(MorphingProvider): def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: return mediator.cached_call(self._make_loader) - + def _make_loader(self): return none_loader def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: return mediator.cached_call(self._make_dumper) - + def _make_dumper(self): return as_is_stub @@ -279,7 +279,7 @@ def _generate_json_schema(self, mediator: Mediator, request: JSONSchemaRequest) class BytesBase64Provider(_Base64DumperMixin, _Base64JSONSchemaMixin, MorphingProvider): def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: return mediator.cached_call(self._make_loader) - + def _make_loader(self): def bytes_base64_loader(data): try: @@ -419,7 +419,7 @@ def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: strict_coercion=strict_coercion, ) - def _make_loader(self, strict_coercion: bool): + def _make_loader(self, *, strict_coercion: bool): return self._strict_coercion_loader if strict_coercion else self._lax_coercion_loader def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: @@ -646,11 +646,11 @@ class LiteralStringProvider(MorphingProvider): def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: strict_coercion = mediator.mandatory_provide(StrictCoercionRequest(loc_stack=request.loc_stack)) return mediator.cached_call( - self._make_loader, # type: ignore[return-value] + self._make_loader, strict_coercion=strict_coercion, ) - def _make_loader(self, strict_coercion: bool): + def _make_loader(self, *, strict_coercion: bool): return str_strict_coercion_loader if strict_coercion else str def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: diff --git a/src/adaptix/_internal/morphing/enum_provider.py b/src/adaptix/_internal/morphing/enum_provider.py index 58b62192..b9afb421 100644 --- a/src/adaptix/_internal/morphing/enum_provider.py +++ b/src/adaptix/_internal/morphing/enum_provider.py @@ -108,14 +108,13 @@ def __init__(self, mapping_generator: BaseEnumMappingGenerator): self._mapping_generator = mapping_generator def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: - enum = request.last_loc.type - mapping = self._mapping_generator.generate_for_loading(enum.__members__.values()) return mediator.cached_call( self._make_loader, - mapping=mapping, + enum=request.last_loc.type, ) - - def _make_loader(self, mapping: Mapping): + + def _make_loader(self, enum): + mapping = self._mapping_generator.generate_for_loading(enum.__members__.values()) variants = list(mapping.keys()) def enum_loader(data): @@ -130,12 +129,19 @@ def enum_loader(data): def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: enum = request.last_loc.type + + return mediator.cached_call( + self._make_dumper, + enum=enum, + ) + + def _make_dumper(self, enum): mapping = self._mapping_generator.generate_for_dumping(enum.__members__.values()) def enum_dumper(data: Enum) -> str: return mapping[data] - return mediator.cached_call(lambda: enum_dumper) + return enum_dumper class EnumValueProvider(BaseEnumProvider): @@ -148,6 +154,13 @@ def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: request.append_loc(TypeHintLoc(type=self._value_type)), ) + return mediator.cached_call( + self._make_loader, + enum=enum, + value_loader=value_loader, + ) + + def _make_loader(self, enum: Enum, value_loader: Loader): def enum_loader(data): loaded_value = value_loader(data) try: @@ -155,18 +168,23 @@ def enum_loader(data): except ValueError: raise MsgLoadError("Bad enum value", data) - return mediator.cached_call(lambda: enum_loader) + return enum_loader def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: value_dumper = mediator.mandatory_provide( request.append_loc(TypeHintLoc(type=self._value_type)), ) + return mediator.cached_call( + self._make_dumper, + value_dumper=value_dumper, + ) + + def _make_dumper(self, value_dumper: Dumper): def enum_dumper(data): return value_dumper(data.value) - return mediator.cached_call(lambda: enum_dumper) - + return enum_dumper class EnumExactValueProvider(BaseEnumProvider): """This provider represents enum members to the outside world @@ -174,9 +192,13 @@ class EnumExactValueProvider(BaseEnumProvider): """ def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: - enum = request.last_loc.type - variants = [case.value for case in enum] + return mediator.cached_call( + self._make_loader, + enum=request.last_loc.type, + ) + def _make_loader(self, enum): + variants = [case.value for case in enum] value_to_member = self._get_exact_value_to_member(enum) if value_to_member is None: def enum_exact_loader(data): @@ -199,7 +221,8 @@ def enum_exact_loader_v2m(data): except TypeError: raise BadVariantLoadError(variants, data) - return mediator.cached_call(lambda: enum_exact_loader_v2m) + return enum_exact_loader_v2m + def _get_exact_value_to_member(self, enum: Type[Enum]) -> Optional[Mapping[Any, Any]]: try: @@ -213,17 +236,28 @@ def _get_exact_value_to_member(self, enum: Type[Enum]) -> Optional[Mapping[Any, return value_to_member def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: - member_to_value = {member: member.value for member in request.last_loc.type} + return mediator.cached_call( + self._make_dumper, + enum=request.last_loc.type, + ) + + def _make_dumper(self, enum): + member_to_value = {member: member.value for member in enum} def enum_exact_value_dumper(data): return member_to_value[data] - return mediator.cached_call(lambda: enum_exact_value_dumper) + return enum_exact_value_dumper class FlagByExactValueProvider(BaseFlagProvider): def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: - enum = request.last_loc.type + return mediator.cached_call( + self._make_loader, + enum=request.last_loc.type, + ) + + def _make_loader(self, enum): flag_mask = reduce(or_, enum.__members__.values()).value if flag_mask < 0: @@ -252,13 +286,16 @@ def flag_loader(data): # so enum lookup cannot raise an error return enum(data) - return mediator.cached_call(lambda: flag_loader) + return flag_loader def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: + return mediator.cached_call(self._make_dumper) + + def _make_dumper(self): def flag_exact_value_dumper(data): return data.value - return mediator.cached_call(lambda: flag_exact_value_dumper) + return flag_exact_value_dumper def _extract_non_compound_cases_from_flag(enum: Type[FlagT]) -> Sequence[FlagT]: @@ -288,6 +325,13 @@ def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: enum = request.last_loc.type strict_coercion = mediator.mandatory_provide(StrictCoercionRequest(loc_stack=request.loc_stack)) + return mediator.cached_call( + self._make_loader, + enum=enum, + strict_coercion=strict_coercion, + ) + + def _make_loader(self, enum, *, strict_coercion: bool): allow_single_value = self._allow_single_value allow_duplicates = self._allow_duplicates @@ -332,11 +376,15 @@ def flag_loader(data) -> Flag: return result - return mediator.cached_call(lambda: flag_loader) + return flag_loader def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: - enum = request.last_loc.type + return mediator.cached_call( + self._make_dumper, + enum=request.last_loc.type, + ) + def _make_dumper(self, enum): cases = self._get_cases(enum) need_to_reverse = self._allow_compound and cases != _extract_non_compound_cases_from_flag(enum) if need_to_reverse: @@ -355,4 +403,4 @@ def flag_dumper(value: Flag) -> Sequence[str]: result.append(mapping[case]) return list(reversed(result)) if need_to_reverse else result - return mediator.cached_call(lambda: flag_dumper) + return flag_dumper diff --git a/src/adaptix/_internal/morphing/generic_provider.py b/src/adaptix/_internal/morphing/generic_provider.py index b8b42891..df1b1dd1 100644 --- a/src/adaptix/_internal/morphing/generic_provider.py +++ b/src/adaptix/_internal/morphing/generic_provider.py @@ -191,6 +191,14 @@ def literal_loader(data): def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: norm = try_normalize_type(request.last_loc.type) + return mediator.cached_call( + self._make_dumper, + norm=norm, + mediator=mediator, + request=request, + ) + + def _make_dumper(self, norm: BaseNormType, mediator: Mediator, request: DumperRequest): enum_cases = [arg for arg in norm.args if isinstance(arg, Enum)] if not enum_cases: @@ -213,8 +221,7 @@ def literal_dumper_with_enums(data): return enum_dumpers[type(data)](data) return data - return mediator.cached_call(lambda: literal_dumper_with_enums) - + return literal_dumper_with_enums @for_predicate(Union) class UnionProvider(LoaderProvider, DumperProvider): @@ -222,6 +229,15 @@ def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: norm = try_normalize_type(request.last_loc.type) debug_trail = mediator.mandatory_provide(DebugTrailRequest(loc_stack=request.loc_stack)) + return mediator.cached_call( + self._make_loader, + norm=norm, + debug_trail=debug_trail, + mediator=mediator, + request=request, + ) + + def _make_loader(self, norm: BaseNormType, debug_trail: DebugTrail, mediator: Mediator, request: LoaderRequest): if self._is_single_optional(norm): not_none = next(case for case in norm.args if case.origin is not None) not_none_loader = mediator.mandatory_provide( @@ -234,14 +250,12 @@ def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: lambda x: "Cannot create loader for union. Loaders for some union cases cannot be created", ) if debug_trail in (DebugTrail.ALL, DebugTrail.FIRST): - return mediator.cached_call( - self._single_optional_dt_loader, + return self._single_optional_dt_loader( tp=norm.source, loader=not_none_loader, ) if debug_trail == DebugTrail.DISABLE: - return mediator.cached_call( - self._single_optional_dt_disable_loader, + return self._single_optional_dt_disable_loader( loader=not_none_loader, ) raise ValueError @@ -259,11 +273,11 @@ def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: lambda: "Cannot create loader for union. Loaders for some union cases cannot be created", ) if debug_trail == DebugTrail.DISABLE: - return mediator.cached_call(self._get_loader_dt_disable, loader_iter=tuple(loaders)) + return self._get_loader_dt_disable(loader_iter=tuple(loaders)) if debug_trail == DebugTrail.FIRST: - return mediator.cached_call(self._get_loader_dt_first, tp=norm.source, loader_iter=tuple(loaders)) + return self._get_loader_dt_first(tp=norm.source, loader_iter=tuple(loaders)) if debug_trail == DebugTrail.ALL: - return mediator.cached_call(self._get_loader_dt_all, tp=norm.source, loader_iter=tuple(loaders)) + return self._get_loader_dt_all(tp=norm.source, loader_iter=tuple(loaders)) raise ValueError def _single_optional_dt_disable_loader(self, loader: Loader) -> Loader: @@ -341,6 +355,14 @@ def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: request_type = request.last_loc.type norm = try_normalize_type(request_type) + return mediator.cached_call( + self._make_dumper, + norm=norm, + mediator=mediator, + request=request, + ) + + def _make_dumper(self, norm: BaseNormType, mediator: Mediator, request: DumperRequest): if self._is_single_optional(norm): not_none = next(case for case in norm.args if case.origin is not None) not_none_dumper = mediator.mandatory_provide( @@ -353,9 +375,8 @@ def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: lambda x: "Cannot create dumper for union. Dumpers for some union cases cannot be created", ) if not_none_dumper == as_is_stub: - return mediator.cached_call(lambda: as_is_stub) - return mediator.cached_call( - self._get_single_optional_dumper, + return as_is_stub + return self._get_single_optional_dumper( dumper=not_none_dumper, ) @@ -385,7 +406,7 @@ def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: lambda: "Cannot create dumper for union. Dumpers for some union cases cannot be created", ) if all(dumper == as_is_stub for dumper in dumpers): - return mediator.cached_call(lambda: as_is_stub) + return as_is_stub dumper_type_dispatcher = ClassDispatcher( {type(None) if case.origin is None else case.origin: dumper for case, dumper in zip(norm.args, dumpers)}, @@ -394,10 +415,9 @@ def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: literal_dumper = self._get_dumper_for_literal(norm, dumpers, dumper_type_dispatcher) if literal_dumper: - return mediator.cached_call(lambda: literal_dumper) + return literal_dumper - return mediator.cached_call( - self._produce_dumper, + return self._produce_dumper( dumper_type_dispatcher=dumper_type_dispatcher, ) @@ -464,4 +484,7 @@ def provide_loader(self, mediator: Mediator, request: LoaderRequest) -> Loader: ) def provide_dumper(self, mediator: Mediator, request: DumperRequest) -> Dumper: - return mediator.cached_call(lambda: path_like_dumper) + return mediator.cached_call(self._make_dumper) + + def _make_dumper(self): + return path_like_dumper