pytrilogy 0.0.3.18__tar.gz → 0.0.3.19__tar.gz

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.
Files changed (133) hide show
  1. {pytrilogy-0.0.3.18/pytrilogy.egg-info → pytrilogy-0.0.3.19}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/__init__.py +1 -1
  4. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/models/author.py +72 -1
  5. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/models/environment.py +10 -2
  6. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parsing/parse_engine.py +6 -18
  7. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/LICENSE.md +0 -0
  8. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/README.md +0 -0
  9. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/pyproject.toml +0 -0
  10. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/pytrilogy.egg-info/SOURCES.txt +0 -0
  11. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/pytrilogy.egg-info/dependency_links.txt +0 -0
  12. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/pytrilogy.egg-info/entry_points.txt +0 -0
  13. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/pytrilogy.egg-info/requires.txt +0 -0
  14. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/pytrilogy.egg-info/top_level.txt +0 -0
  15. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/setup.cfg +0 -0
  16. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/setup.py +0 -0
  17. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_datatypes.py +0 -0
  18. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_declarations.py +0 -0
  19. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_derived_concepts.py +0 -0
  20. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_discovery_nodes.py +0 -0
  21. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_enums.py +0 -0
  22. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_environment.py +0 -0
  23. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_executor.py +0 -0
  24. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_functions.py +0 -0
  25. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_imports.py +0 -0
  26. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_metadata.py +0 -0
  27. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_models.py +0 -0
  28. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_multi_join_assignments.py +0 -0
  29. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_parse_engine.py +0 -0
  30. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_parsing.py +0 -0
  31. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_partial_handling.py +0 -0
  32. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_query_processing.py +0 -0
  33. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_query_render.py +0 -0
  34. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_select.py +0 -0
  35. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_show.py +0 -0
  36. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_statements.py +0 -0
  37. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_typing.py +0 -0
  38. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_undefined_concept.py +0 -0
  39. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_user_functions.py +0 -0
  40. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/tests/test_where_clause.py +0 -0
  41. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/authoring/__init__.py +0 -0
  42. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/compiler.py +0 -0
  43. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/constants.py +0 -0
  44. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/__init__.py +0 -0
  45. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/constants.py +0 -0
  46. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/enums.py +0 -0
  47. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/env_processor.py +0 -0
  48. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/environment_helpers.py +0 -0
  49. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/ergonomics.py +0 -0
  50. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/exceptions.py +0 -0
  51. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/functions.py +0 -0
  52. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/graph_models.py +0 -0
  53. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/internal.py +0 -0
  54. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/models/__init__.py +0 -0
  55. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/models/build.py +0 -0
  56. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/models/build_environment.py +0 -0
  57. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/models/core.py +0 -0
  58. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/models/datasource.py +0 -0
  59. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/models/execute.py +0 -0
  60. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/optimization.py +0 -0
  61. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/optimizations/__init__.py +0 -0
  62. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/optimizations/base_optimization.py +0 -0
  63. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/optimizations/inline_constant.py +0 -0
  64. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/optimizations/inline_datasource.py +0 -0
  65. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  66. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/__init__.py +0 -0
  67. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  68. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/graph_utils.py +0 -0
  69. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/__init__.py +0 -0
  70. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  71. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/common.py +0 -0
  72. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  73. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/group_node.py +0 -0
  74. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  75. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  76. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  77. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  78. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  79. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  80. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  81. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/select_node.py +0 -0
  82. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  83. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/union_node.py +0 -0
  84. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  85. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/node_generators/window_node.py +0 -0
  86. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/__init__.py +0 -0
  87. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/base_node.py +0 -0
  88. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/filter_node.py +0 -0
  89. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/group_node.py +0 -0
  90. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/merge_node.py +0 -0
  91. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  92. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/union_node.py +0 -0
  93. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  94. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/nodes/window_node.py +0 -0
  95. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/processing/utility.py +0 -0
  96. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/query_processor.py +0 -0
  97. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/statements/__init__.py +0 -0
  98. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/statements/author.py +0 -0
  99. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/statements/build.py +0 -0
  100. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/statements/common.py +0 -0
  101. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/core/statements/execute.py +0 -0
  102. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/__init__.py +0 -0
  103. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/base.py +0 -0
  104. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/bigquery.py +0 -0
  105. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/common.py +0 -0
  106. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/config.py +0 -0
  107. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/dataframe.py +0 -0
  108. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/duckdb.py +0 -0
  109. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/enums.py +0 -0
  110. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/postgres.py +0 -0
  111. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/presto.py +0 -0
  112. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/snowflake.py +0 -0
  113. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/dialect/sql_server.py +0 -0
  114. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/engine.py +0 -0
  115. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/executor.py +0 -0
  116. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/hooks/__init__.py +0 -0
  117. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/hooks/base_hook.py +0 -0
  118. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/hooks/graph_hook.py +0 -0
  119. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/hooks/query_debugger.py +0 -0
  120. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/metadata/__init__.py +0 -0
  121. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parser.py +0 -0
  122. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parsing/__init__.py +0 -0
  123. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parsing/common.py +0 -0
  124. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parsing/config.py +0 -0
  125. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parsing/exceptions.py +0 -0
  126. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parsing/helpers.py +0 -0
  127. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parsing/render.py +0 -0
  128. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/parsing/trilogy.lark +0 -0
  129. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/py.typed +0 -0
  130. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/render.py +0 -0
  131. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/scripts/__init__.py +0 -0
  132. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/scripts/trilogy.py +0 -0
  133. {pytrilogy-0.0.3.18 → pytrilogy-0.0.3.19}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pytrilogy
3
- Version: 0.0.3.18
3
+ Version: 0.0.3.19
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pytrilogy
3
- Version: 0.0.3.18
3
+ Version: 0.0.3.19
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -4,6 +4,6 @@ from trilogy.dialect.enums import Dialects
4
4
  from trilogy.executor import Executor
5
5
  from trilogy.parser import parse
6
6
 
7
- __version__ = "0.0.3.18"
7
+ __version__ = "0.0.3.19"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -318,6 +318,21 @@ class Conditional(Mergeable, ConceptArgs, Namespaced, BaseModel):
318
318
  operator=self.operator,
319
319
  )
320
320
 
321
+ def with_reference_replacement(self, source, target):
322
+ return self.__class__.model_construct(
323
+ left=(
324
+ self.left.with_reference_replacement(source, target)
325
+ if isinstance(self.left, Mergeable)
326
+ else self.left
327
+ ),
328
+ right=(
329
+ self.right.with_reference_replacement(source, target)
330
+ if isinstance(self.right, Mergeable)
331
+ else self.right
332
+ ),
333
+ operator=self.operator,
334
+ )
335
+
321
336
  @property
322
337
  def concept_arguments(self) -> Sequence[ConceptRef]:
323
338
  """Return concepts directly referenced in where clause"""
@@ -2135,6 +2150,52 @@ class AlignItem(Namespaced, BaseModel):
2135
2150
  )
2136
2151
 
2137
2152
 
2153
+ class CustomFunctionFactory:
2154
+ def __init__(
2155
+ self, function: Expr, namespace: str, function_arguments: list[ArgBinding]
2156
+ ):
2157
+ self.namespace = namespace
2158
+ self.function = function
2159
+ self.function_arguments = function_arguments
2160
+
2161
+ def with_namespace(self, namespace: str):
2162
+ self.namespace = namespace
2163
+ self.function = (
2164
+ self.function.with_namespace(namespace)
2165
+ if isinstance(self.function, Namespaced)
2166
+ else self.function
2167
+ )
2168
+ self.function_arguments = [
2169
+ x.with_namespace(namespace) for x in self.function_arguments
2170
+ ]
2171
+ return self
2172
+
2173
+ def __call__(self, *creation_args: list[Expr]):
2174
+ nout = (
2175
+ self.function.model_copy(deep=True)
2176
+ if isinstance(self.function, BaseModel)
2177
+ else self.function
2178
+ )
2179
+ creation_arg_list: list[Expr] = list(creation_args)
2180
+ if len(creation_args) < len(self.function_arguments):
2181
+ for binding in self.function_arguments[len(creation_arg_list) :]:
2182
+ if binding.default is None:
2183
+ raise ValueError(f"Missing argument {binding.name}")
2184
+ creation_arg_list.append(binding.default)
2185
+ if isinstance(nout, Mergeable):
2186
+ for idx, x in enumerate(creation_arg_list):
2187
+ if self.namespace == DEFAULT_NAMESPACE:
2188
+ target = f"{DEFAULT_NAMESPACE}.{self.function_arguments[idx].name}"
2189
+ else:
2190
+ target = self.function_arguments[idx].name
2191
+ nout = (
2192
+ nout.with_reference_replacement(target, x)
2193
+ if isinstance(nout, Mergeable)
2194
+ else nout
2195
+ )
2196
+ return nout
2197
+
2198
+
2138
2199
  class Metadata(BaseModel):
2139
2200
  """Metadata container object.
2140
2201
  TODO: support arbitrary tags"""
@@ -2164,10 +2225,20 @@ class Comment(BaseModel):
2164
2225
  text: str
2165
2226
 
2166
2227
 
2167
- class ArgBinding(BaseModel):
2228
+ class ArgBinding(Namespaced, BaseModel):
2168
2229
  name: str
2169
2230
  default: Expr | None = None
2170
2231
 
2232
+ def with_namespace(self, namespace):
2233
+ return ArgBinding(
2234
+ name=address_with_namespace(self.name, namespace),
2235
+ default=(
2236
+ self.default.with_namespace(namespace)
2237
+ if isinstance(self.default, Namespaced)
2238
+ else self.default
2239
+ ),
2240
+ )
2241
+
2171
2242
 
2172
2243
  class CustomType(BaseModel):
2173
2244
  name: str
@@ -9,7 +9,6 @@ from typing import (
9
9
  TYPE_CHECKING,
10
10
  Annotated,
11
11
  Any,
12
- Callable,
13
12
  Dict,
14
13
  ItemsView,
15
14
  List,
@@ -40,6 +39,7 @@ from trilogy.core.exceptions import (
40
39
  from trilogy.core.models.author import (
41
40
  Concept,
42
41
  ConceptRef,
42
+ CustomFunctionFactory,
43
43
  CustomType,
44
44
  Function,
45
45
  SelectLineage,
@@ -207,7 +207,7 @@ class Environment(BaseModel):
207
207
  datasources: Annotated[
208
208
  EnvironmentDatasourceDict, PlainValidator(validate_datasources)
209
209
  ] = Field(default_factory=EnvironmentDatasourceDict)
210
- functions: Dict[str, Callable[..., Any]] = Field(default_factory=dict)
210
+ functions: Dict[str, CustomFunctionFactory] = Field(default_factory=dict)
211
211
  data_types: Dict[str, CustomType] = Field(default_factory=dict)
212
212
  named_statements: Dict[str, SelectLineage] = Field(default_factory=dict)
213
213
  imports: Dict[str, list[Import]] = Field(
@@ -434,6 +434,14 @@ class Environment(BaseModel):
434
434
  self.alias_origin_lookup[address_with_namespace(key, alias)] = (
435
435
  val.with_namespace(alias)
436
436
  )
437
+
438
+ for key, function in source.functions.items():
439
+ if same_namespace:
440
+ self.functions[key] = function
441
+ else:
442
+ self.functions[address_with_namespace(key, alias)] = (
443
+ function.with_namespace(alias)
444
+ )
437
445
  return self
438
446
 
439
447
  def add_file_import(
@@ -57,13 +57,13 @@ from trilogy.core.models.author import (
57
57
  Concept,
58
58
  ConceptRef,
59
59
  Conditional,
60
+ CustomFunctionFactory,
60
61
  CustomType,
61
62
  Expr,
62
63
  FilterItem,
63
64
  Function,
64
65
  Grain,
65
66
  HavingClause,
66
- Mergeable,
67
67
  Metadata,
68
68
  OrderBy,
69
69
  OrderItem,
@@ -1198,23 +1198,11 @@ class ParseToObjects(Transformer):
1198
1198
  function_arguments: list[ArgBinding] = args[1]
1199
1199
  output = args[2]
1200
1200
 
1201
- def function_factory(*creation_args: list[Expr]):
1202
- nout = output.copy(deep=True)
1203
- creation_arg_list: list[Expr] = list(creation_args)
1204
- if len(creation_args) < len(function_arguments):
1205
- for binding in function_arguments[len(creation_arg_list) :]:
1206
- if binding.default is None:
1207
- raise ValueError(f"Missing argument {binding.name}")
1208
- creation_arg_list.append(binding.default)
1209
- if isinstance(nout, Mergeable):
1210
- for idx, x in enumerate(creation_arg_list):
1211
- # these will always be local namespace
1212
- nout = nout.with_reference_replacement(
1213
- f"{DEFAULT_NAMESPACE}.{function_arguments[idx].name}", x
1214
- )
1215
- return nout
1216
-
1217
- self.environment.functions[identity] = function_factory
1201
+ self.environment.functions[identity] = CustomFunctionFactory(
1202
+ function=output,
1203
+ namespace=self.environment.namespace,
1204
+ function_arguments=function_arguments,
1205
+ )
1218
1206
  return FunctionDeclaration(name=identity, args=function_arguments, expr=output)
1219
1207
 
1220
1208
  def custom_function(self, args):
File without changes
File without changes
File without changes
File without changes