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.

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
- ) -> list[Concept]:
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
- final: List[Concept] = []
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
- final.append(sub)
348
- final = unique(final, "address")
349
- v2 = sorted(final, key=lambda x: x.name)
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
- elif isinstance(parent, AggregateWrapper):
852
- if not name:
853
- name = f"{VIRTUAL_CONCEPT_PREFIX}_agg_{parent.function.operator.value}_{string_to_hash(str(parent))}"
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)
@@ -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
- if len(args) == 2:
1379
- return ArgBinding.model_construct(name=args[0], default=args[1])
1380
- return ArgBinding.model_construct(name=args[0], default=None)
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
 
@@ -91,7 +91,9 @@
91
91
 
92
92
  // FUNCTION blocks
93
93
  function: raw_function
94
- function_binding_item: IDENTIFIER ("=" literal)?
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