Add ConversionPoint reference into a ConversionRenderData for a further deduplication and reuse of raw call sequence

This commit is contained in:
2025-08-20 00:31:42 +03:00
parent d68bb79a97
commit a256db0203
2 changed files with 24 additions and 13 deletions

View File

@@ -1,6 +1,6 @@
[project]
name = "breakshaft"
version = "0.1.5"
version = "0.1.6"
description = "Library for in-time codegen for type conversion"
authors = [
{ name = "nikto_b", email = "niktob560@yandex.ru" }

View File

@@ -7,7 +7,7 @@ import importlib.resources
import jinja2
from .models import ConversionPoint
from .util import hashname, get_tuple_types, is_basic_type_annot
from .util import hashname, get_tuple_types, is_basic_type_annot, universal_qualname
class ConvertorRenderer(Protocol):
@@ -51,6 +51,7 @@ class ConversionRenderData:
is_ctxmanager: bool
is_async: bool
unwrap_tuple_result: UnwprappedTuple
_injection: ConversionPoint
@classmethod
def from_inj(cls, inj: ConversionPoint, provided_types: set[type]):
@@ -74,7 +75,8 @@ class ConversionRenderData:
fnargs,
inj.is_ctx_manager,
inj.is_async,
unwrap_tuple_result)
unwrap_tuple_result,
inj)
@dataclass
@@ -106,6 +108,24 @@ def deduplicate_callseq(conversion_models: list[ConversionRenderData]) -> list[C
return deduplicated_conv_models
def render_data_from_callseq(from_types: Sequence[type],
fnmap: dict[int, Callable],
callseq: Sequence[ConversionPoint]):
conversion_models: list[ConversionRenderData] = []
ret_hash = 0
for call_id, call in enumerate(callseq):
provided_types = set(from_types)
for _call in callseq[:call_id]:
provided_types |= {_call.injects}
provided_types |= set(_call.requires)
fnmap[hash(call.fn)] = call.fn
conv = ConversionRenderData.from_inj(call, provided_types)
conversion_models.append(conv)
return conversion_models
class InTimeGenerationConvertorRenderer(ConvertorRenderer):
templateLoader: jinja2.BaseLoader
templateEnv: jinja2.Environment
@@ -128,19 +148,10 @@ class InTimeGenerationConvertorRenderer(ConvertorRenderer):
store_sources: bool = False) -> Callable:
fnmap = {}
conversion_models: list[ConversionRenderData] = []
conversion_models: list[ConversionRenderData] = render_data_from_callseq(from_types, fnmap, callseq)
ret_hash = 0
is_async = force_async
for call_id, call in enumerate(callseq):
provided_types = set(from_types)
for _call in callseq[:call_id]:
provided_types |= {_call.injects}
provided_types |= set(_call.requires)
fnmap[hash(call.fn)] = call.fn
conv = ConversionRenderData.from_inj(call, provided_types)
conversion_models.append(conv)
if call.is_async:
is_async = True