pytrilogy 0.0.3.91__py3-none-any.whl → 0.0.3.93__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pytrilogy might be problematic. Click here for more details.
- {pytrilogy-0.0.3.91.dist-info → pytrilogy-0.0.3.93.dist-info}/METADATA +9 -6
- {pytrilogy-0.0.3.91.dist-info → pytrilogy-0.0.3.93.dist-info}/RECORD +20 -19
- trilogy/__init__.py +1 -1
- trilogy/core/env_processor.py +31 -9
- trilogy/core/graph_models.py +11 -1
- trilogy/core/models/author.py +49 -15
- trilogy/core/models/build.py +321 -185
- trilogy/core/models/build_environment.py +2 -6
- trilogy/core/models/core.py +12 -0
- trilogy/core/models/execute.py +3 -3
- trilogy/core/processing/node_generators/group_node.py +3 -7
- trilogy/core/processing/node_generators/node_merge_node.py +25 -23
- trilogy/core/processing/node_generators/select_merge_node_v2.py +792 -0
- trilogy/parsing/common.py +50 -29
- trilogy/parsing/parse_engine.py +22 -3
- trilogy/parsing/trilogy.lark +3 -1
- {pytrilogy-0.0.3.91.dist-info → pytrilogy-0.0.3.93.dist-info}/WHEEL +0 -0
- {pytrilogy-0.0.3.91.dist-info → pytrilogy-0.0.3.93.dist-info}/entry_points.txt +0 -0
- {pytrilogy-0.0.3.91.dist-info → pytrilogy-0.0.3.93.dist-info}/licenses/LICENSE.md +0 -0
- {pytrilogy-0.0.3.91.dist-info → pytrilogy-0.0.3.93.dist-info}/top_level.txt +0 -0
trilogy/parsing/common.py
CHANGED
|
@@ -309,7 +309,7 @@ def concepts_to_grain_concepts(
|
|
|
309
309
|
concepts: Iterable[Concept | ConceptRef | str],
|
|
310
310
|
environment: Environment | None,
|
|
311
311
|
local_concepts: dict[str, Concept] | None = None,
|
|
312
|
-
) ->
|
|
312
|
+
) -> set[str]:
|
|
313
313
|
preconcepts: list[Concept] = []
|
|
314
314
|
for c in concepts:
|
|
315
315
|
if isinstance(c, Concept):
|
|
@@ -329,7 +329,7 @@ def concepts_to_grain_concepts(
|
|
|
329
329
|
raise ValueError(
|
|
330
330
|
f"Unable to resolve input {c} without environment provided to concepts_to_grain call"
|
|
331
331
|
)
|
|
332
|
-
pconcepts = []
|
|
332
|
+
pconcepts: list[Concept] = []
|
|
333
333
|
for x in preconcepts:
|
|
334
334
|
if (
|
|
335
335
|
x.lineage
|
|
@@ -340,14 +340,16 @@ def concepts_to_grain_concepts(
|
|
|
340
340
|
pconcepts.append(environment.concepts[x.lineage.arguments[0].address]) # type: ignore
|
|
341
341
|
else:
|
|
342
342
|
pconcepts.append(x)
|
|
343
|
-
|
|
343
|
+
|
|
344
|
+
seen = set()
|
|
344
345
|
for sub in pconcepts:
|
|
346
|
+
if sub.address in seen:
|
|
347
|
+
continue
|
|
345
348
|
if not concept_is_relevant(sub, pconcepts, environment): # type: ignore
|
|
346
349
|
continue
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
return v2
|
|
350
|
+
seen.add(sub.address)
|
|
351
|
+
|
|
352
|
+
return seen
|
|
351
353
|
|
|
352
354
|
|
|
353
355
|
def _get_relevant_parent_concepts(arg) -> tuple[list[ConceptRef], bool]:
|
|
@@ -823,6 +825,40 @@ def rowset_to_concepts(rowset: RowsetDerivationStatement, environment: Environme
|
|
|
823
825
|
return pre_output
|
|
824
826
|
|
|
825
827
|
|
|
828
|
+
def generate_concept_name(
|
|
829
|
+
parent: (
|
|
830
|
+
AggregateWrapper
|
|
831
|
+
| FunctionCallWrapper
|
|
832
|
+
| WindowItem
|
|
833
|
+
| FilterItem
|
|
834
|
+
| Function
|
|
835
|
+
| ListWrapper
|
|
836
|
+
| MapWrapper
|
|
837
|
+
| int
|
|
838
|
+
| float
|
|
839
|
+
| str
|
|
840
|
+
| date
|
|
841
|
+
),
|
|
842
|
+
) -> str:
|
|
843
|
+
"""Generate a name for a concept based on its parent type and content."""
|
|
844
|
+
if isinstance(parent, AggregateWrapper):
|
|
845
|
+
return f"{VIRTUAL_CONCEPT_PREFIX}_agg_{parent.function.operator.value}_{string_to_hash(str(parent))}"
|
|
846
|
+
elif isinstance(parent, WindowItem):
|
|
847
|
+
return f"{VIRTUAL_CONCEPT_PREFIX}_window_{parent.type.value}_{string_to_hash(str(parent))}"
|
|
848
|
+
elif isinstance(parent, FilterItem):
|
|
849
|
+
if isinstance(parent.content, ConceptRef):
|
|
850
|
+
return f"{VIRTUAL_CONCEPT_PREFIX}_filter_{parent.content.name}_{string_to_hash(str(parent))}"
|
|
851
|
+
else:
|
|
852
|
+
return f"{VIRTUAL_CONCEPT_PREFIX}_filter_{string_to_hash(str(parent))}"
|
|
853
|
+
elif isinstance(parent, Function):
|
|
854
|
+
if parent.operator == FunctionType.GROUP:
|
|
855
|
+
return f"{VIRTUAL_CONCEPT_PREFIX}_group_to_{string_to_hash(str(parent))}"
|
|
856
|
+
else:
|
|
857
|
+
return f"{VIRTUAL_CONCEPT_PREFIX}_func_{parent.operator.value}_{string_to_hash(str(parent))}"
|
|
858
|
+
else: # ListWrapper, MapWrapper, or primitive types
|
|
859
|
+
return f"{VIRTUAL_CONCEPT_PREFIX}_{string_to_hash(str(parent))}"
|
|
860
|
+
|
|
861
|
+
|
|
826
862
|
def arbitrary_to_concept(
|
|
827
863
|
parent: (
|
|
828
864
|
AggregateWrapper
|
|
@@ -843,20 +879,22 @@ def arbitrary_to_concept(
|
|
|
843
879
|
metadata: Metadata | None = None,
|
|
844
880
|
) -> Concept:
|
|
845
881
|
namespace = namespace or environment.namespace
|
|
882
|
+
|
|
846
883
|
# this is purely for the parse tree, discard from derivation
|
|
847
884
|
if isinstance(parent, FunctionCallWrapper):
|
|
848
885
|
return arbitrary_to_concept(
|
|
849
886
|
parent.content, environment, namespace, name, metadata # type: ignore
|
|
850
887
|
)
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
888
|
+
|
|
889
|
+
# Generate name if not provided
|
|
890
|
+
if not name:
|
|
891
|
+
name = generate_concept_name(parent)
|
|
892
|
+
|
|
893
|
+
if isinstance(parent, AggregateWrapper):
|
|
854
894
|
return agg_wrapper_to_concept(
|
|
855
895
|
parent, namespace, name, metadata=metadata, environment=environment
|
|
856
896
|
)
|
|
857
897
|
elif isinstance(parent, WindowItem):
|
|
858
|
-
if not name:
|
|
859
|
-
name = f"{VIRTUAL_CONCEPT_PREFIX}_window_{parent.type.value}_{string_to_hash(str(parent))}"
|
|
860
898
|
return window_item_to_concept(
|
|
861
899
|
parent,
|
|
862
900
|
name,
|
|
@@ -865,11 +903,6 @@ def arbitrary_to_concept(
|
|
|
865
903
|
metadata=metadata,
|
|
866
904
|
)
|
|
867
905
|
elif isinstance(parent, FilterItem):
|
|
868
|
-
if not name:
|
|
869
|
-
if isinstance(parent.content, ConceptRef):
|
|
870
|
-
name = f"{VIRTUAL_CONCEPT_PREFIX}_filter_{parent.content.name}_{string_to_hash(str(parent))}"
|
|
871
|
-
else:
|
|
872
|
-
name = f"{VIRTUAL_CONCEPT_PREFIX}_filter_{string_to_hash(str(parent))}"
|
|
873
906
|
return filter_item_to_concept(
|
|
874
907
|
parent,
|
|
875
908
|
name,
|
|
@@ -878,14 +911,6 @@ def arbitrary_to_concept(
|
|
|
878
911
|
metadata=metadata,
|
|
879
912
|
)
|
|
880
913
|
elif isinstance(parent, Function):
|
|
881
|
-
if not name:
|
|
882
|
-
if parent.operator == FunctionType.GROUP:
|
|
883
|
-
name = (
|
|
884
|
-
f"{VIRTUAL_CONCEPT_PREFIX}_group_to_{string_to_hash(str(parent))}"
|
|
885
|
-
)
|
|
886
|
-
else:
|
|
887
|
-
name = f"{VIRTUAL_CONCEPT_PREFIX}_func_{parent.operator.value}_{string_to_hash(str(parent))}"
|
|
888
|
-
|
|
889
914
|
if parent.operator == FunctionType.GROUP:
|
|
890
915
|
return group_function_to_concept(
|
|
891
916
|
parent,
|
|
@@ -902,10 +927,6 @@ def arbitrary_to_concept(
|
|
|
902
927
|
namespace=namespace,
|
|
903
928
|
)
|
|
904
929
|
elif isinstance(parent, ListWrapper):
|
|
905
|
-
if not name:
|
|
906
|
-
name = f"{VIRTUAL_CONCEPT_PREFIX}_{string_to_hash(str(parent))}"
|
|
907
930
|
return constant_to_concept(parent, name, namespace, metadata)
|
|
908
931
|
else:
|
|
909
|
-
if not name:
|
|
910
|
-
name = f"{VIRTUAL_CONCEPT_PREFIX}_{string_to_hash(str(parent))}"
|
|
911
932
|
return constant_to_concept(parent, name, namespace, metadata)
|
trilogy/parsing/parse_engine.py
CHANGED
|
@@ -161,6 +161,11 @@ class WholeGrainWrapper:
|
|
|
161
161
|
where: WhereClause
|
|
162
162
|
|
|
163
163
|
|
|
164
|
+
@dataclass
|
|
165
|
+
class FunctionBindingType:
|
|
166
|
+
type: DataType | TraitDataType | None = None
|
|
167
|
+
|
|
168
|
+
|
|
164
169
|
with open(join(dirname(__file__), "trilogy.lark"), "r") as f:
|
|
165
170
|
PARSER = Lark(
|
|
166
171
|
f.read(),
|
|
@@ -1373,11 +1378,24 @@ class ParseToObjects(Transformer):
|
|
|
1373
1378
|
def function_binding_list(self, meta: Meta, args) -> list[ArgBinding]:
|
|
1374
1379
|
return args
|
|
1375
1380
|
|
|
1381
|
+
@v_args(meta=True)
|
|
1382
|
+
def function_binding_type(self, meta: Meta, args) -> FunctionBindingType:
|
|
1383
|
+
return FunctionBindingType(type=args[0])
|
|
1384
|
+
|
|
1385
|
+
@v_args(meta=True)
|
|
1386
|
+
def function_binding_default(self, meta: Meta, args):
|
|
1387
|
+
return args[1]
|
|
1388
|
+
|
|
1376
1389
|
@v_args(meta=True)
|
|
1377
1390
|
def function_binding_item(self, meta: Meta, args) -> ArgBinding:
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1391
|
+
default = None
|
|
1392
|
+
type = None
|
|
1393
|
+
for arg in args[1:]:
|
|
1394
|
+
if isinstance(arg, FunctionBindingType):
|
|
1395
|
+
type = arg.type
|
|
1396
|
+
else:
|
|
1397
|
+
default = arg
|
|
1398
|
+
return ArgBinding.model_construct(name=args[0], datatype=type, default=default)
|
|
1381
1399
|
|
|
1382
1400
|
@v_args(meta=True)
|
|
1383
1401
|
def raw_function(self, meta: Meta, args) -> FunctionDeclaration:
|
|
@@ -1389,6 +1407,7 @@ class ParseToObjects(Transformer):
|
|
|
1389
1407
|
function=output,
|
|
1390
1408
|
namespace=self.environment.namespace,
|
|
1391
1409
|
function_arguments=function_arguments,
|
|
1410
|
+
name=identity,
|
|
1392
1411
|
)
|
|
1393
1412
|
return FunctionDeclaration(name=identity, args=function_arguments, expr=output)
|
|
1394
1413
|
|
trilogy/parsing/trilogy.lark
CHANGED
|
@@ -91,7 +91,9 @@
|
|
|
91
91
|
|
|
92
92
|
// FUNCTION blocks
|
|
93
93
|
function: raw_function
|
|
94
|
-
|
|
94
|
+
function_binding_type: ":" data_type
|
|
95
|
+
function_binding_default: /=/ expr
|
|
96
|
+
function_binding_item: IDENTIFIER function_binding_type? function_binding_default?
|
|
95
97
|
function_binding_list: (function_binding_item ",")* function_binding_item ","?
|
|
96
98
|
raw_function: "def" IDENTIFIER "(" function_binding_list ")" "->" expr
|
|
97
99
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|