pytrilogy 0.0.2.33__tar.gz → 0.0.2.34__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.

Potentially problematic release.


This version of pytrilogy might be problematic. Click here for more details.

Files changed (109) hide show
  1. {pytrilogy-0.0.2.33/pytrilogy.egg-info → pytrilogy-0.0.2.34}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/pytrilogy.egg-info/SOURCES.txt +1 -0
  4. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_environment.py +16 -0
  5. pytrilogy-0.0.2.34/tests/test_parse_engine.py +30 -0
  6. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_undefined_concept.py +1 -1
  7. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/__init__.py +1 -1
  8. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/models.py +8 -4
  9. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parsing/parse_engine.py +18 -13
  10. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/LICENSE.md +0 -0
  11. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/README.md +0 -0
  12. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/pyproject.toml +0 -0
  13. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/pytrilogy.egg-info/dependency_links.txt +0 -0
  14. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/pytrilogy.egg-info/entry_points.txt +0 -0
  15. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/pytrilogy.egg-info/requires.txt +0 -0
  16. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/pytrilogy.egg-info/top_level.txt +0 -0
  17. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/setup.cfg +0 -0
  18. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/setup.py +0 -0
  19. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_datatypes.py +0 -0
  20. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_declarations.py +0 -0
  21. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_derived_concepts.py +0 -0
  22. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_discovery_nodes.py +0 -0
  23. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_executor.py +0 -0
  24. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_functions.py +0 -0
  25. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_imports.py +0 -0
  26. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_metadata.py +0 -0
  27. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_models.py +0 -0
  28. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_multi_join_assignments.py +0 -0
  29. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_parsing.py +0 -0
  30. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_partial_handling.py +0 -0
  31. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_query_processing.py +0 -0
  32. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_select.py +0 -0
  33. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_show.py +0 -0
  34. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_statements.py +0 -0
  35. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/tests/test_where_clause.py +0 -0
  36. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/compiler.py +0 -0
  37. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/constants.py +0 -0
  38. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/__init__.py +0 -0
  39. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/constants.py +0 -0
  40. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/enums.py +0 -0
  41. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/env_processor.py +0 -0
  42. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/environment_helpers.py +0 -0
  43. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/ergonomics.py +0 -0
  44. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/exceptions.py +0 -0
  45. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/functions.py +0 -0
  46. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/graph_models.py +0 -0
  47. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/internal.py +0 -0
  48. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/optimization.py +0 -0
  49. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/optimizations/__init__.py +0 -0
  50. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/optimizations/base_optimization.py +0 -0
  51. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/optimizations/inline_constant.py +0 -0
  52. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/optimizations/inline_datasource.py +0 -0
  53. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  54. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/__init__.py +0 -0
  55. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  56. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/graph_utils.py +0 -0
  57. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/__init__.py +0 -0
  58. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  59. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/common.py +0 -0
  60. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  61. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/group_node.py +0 -0
  62. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  63. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  64. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  65. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  66. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  67. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/select_node.py +0 -0
  68. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  69. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/node_generators/window_node.py +0 -0
  70. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/nodes/__init__.py +0 -0
  71. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/nodes/base_node.py +0 -0
  72. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/nodes/filter_node.py +0 -0
  73. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/nodes/group_node.py +0 -0
  74. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/nodes/merge_node.py +0 -0
  75. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  76. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  77. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/nodes/window_node.py +0 -0
  78. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/processing/utility.py +0 -0
  79. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/core/query_processor.py +0 -0
  80. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/__init__.py +0 -0
  81. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/base.py +0 -0
  82. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/bigquery.py +0 -0
  83. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/common.py +0 -0
  84. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/config.py +0 -0
  85. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/duckdb.py +0 -0
  86. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/enums.py +0 -0
  87. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/postgres.py +0 -0
  88. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/presto.py +0 -0
  89. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/snowflake.py +0 -0
  90. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/dialect/sql_server.py +0 -0
  91. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/engine.py +0 -0
  92. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/executor.py +0 -0
  93. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/hooks/__init__.py +0 -0
  94. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/hooks/base_hook.py +0 -0
  95. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/hooks/graph_hook.py +0 -0
  96. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/hooks/query_debugger.py +0 -0
  97. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/metadata/__init__.py +0 -0
  98. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parser.py +0 -0
  99. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parsing/__init__.py +0 -0
  100. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parsing/common.py +0 -0
  101. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parsing/config.py +0 -0
  102. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parsing/exceptions.py +0 -0
  103. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parsing/helpers.py +0 -0
  104. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parsing/render.py +0 -0
  105. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/parsing/trilogy.lark +0 -0
  106. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/py.typed +0 -0
  107. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/scripts/__init__.py +0 -0
  108. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/scripts/trilogy.py +0 -0
  109. {pytrilogy-0.0.2.33 → pytrilogy-0.0.2.34}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytrilogy
3
- Version: 0.0.2.33
3
+ Version: 0.0.2.34
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.1
2
2
  Name: pytrilogy
3
- Version: 0.0.2.33
3
+ Version: 0.0.2.34
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -19,6 +19,7 @@ tests/test_imports.py
19
19
  tests/test_metadata.py
20
20
  tests/test_models.py
21
21
  tests/test_multi_join_assignments.py
22
+ tests/test_parse_engine.py
22
23
  tests/test_parsing.py
23
24
  tests/test_partial_handling.py
24
25
  tests/test_query_processing.py
@@ -1,6 +1,7 @@
1
1
  from trilogy.core.models import Environment
2
2
  from pathlib import Path
3
3
  from trilogy.core.enums import Modifier
4
+ from trilogy.core.exceptions import UndefinedConceptException
4
5
 
5
6
 
6
7
  def test_environment_serialization(test_environment: Environment):
@@ -23,6 +24,21 @@ def test_environment_from_path():
23
24
  assert "local.id" in env.concepts
24
25
 
25
26
 
27
+ def test_environment_invalid():
28
+
29
+ env = Environment()
30
+ env.concepts.fail_on_missing = False
31
+ x = env.concepts["abc"]
32
+ assert x.name == "abc"
33
+
34
+ env.concepts.fail_on_missing = True
35
+ try:
36
+ x = env.concepts["abc"]
37
+ assert 1 == 0
38
+ except Exception as e:
39
+ assert isinstance(e, UndefinedConceptException)
40
+
41
+
26
42
  def test_environment_merge():
27
43
  env1: Environment
28
44
  env1, _ = Environment().parse(
@@ -0,0 +1,30 @@
1
+ from trilogy.parsing.parse_engine import ParseToObjects, PARSER, unpack_visit_error
2
+ from trilogy import Environment
3
+ from trilogy.core.exceptions import UndefinedConceptException
4
+ from pytest import raises
5
+
6
+ TEXT = """
7
+ const a <- 1;
8
+
9
+ select
10
+ a,
11
+ b
12
+ ;
13
+ """
14
+
15
+
16
+ def test_parser():
17
+ env = Environment()
18
+ x = ParseToObjects(environment=env)
19
+ x.environment.concepts.fail_on_missing = False
20
+ x.set_text(TEXT)
21
+ tokens = PARSER.parse(TEXT)
22
+ x.transform(tokens)
23
+ failed = False
24
+ try:
25
+ x.hydrate_missing()
26
+ except Exception as e:
27
+ failed = True
28
+ with raises(UndefinedConceptException):
29
+ unpack_visit_error(e)
30
+ assert failed
@@ -32,6 +32,6 @@ def test_undefined_concept_dict():
32
32
  try:
33
33
  env["orid"]
34
34
  except UndefinedConceptException as e:
35
- assert e.suggestions == ["local.order_id"]
35
+ assert e.suggestions == ["order_id"]
36
36
  assert "suggestions" in e.message.lower()
37
37
  assert "order_id" in e.message.lower()
@@ -4,6 +4,6 @@ from trilogy.executor import Executor
4
4
  from trilogy.parser import parse
5
5
  from trilogy.constants import CONFIG
6
6
 
7
- __version__ = "0.0.2.33"
7
+ __version__ = "0.0.2.34"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -3218,7 +3218,7 @@ class EnvironmentConceptDict(dict):
3218
3218
  def __init__(self, *args, **kwargs) -> None:
3219
3219
  super().__init__(self, *args, **kwargs)
3220
3220
  self.undefined: dict[str, UndefinedConcept] = {}
3221
- self.fail_on_missing: bool = False
3221
+ self.fail_on_missing: bool = True
3222
3222
  self.populate_default_concepts()
3223
3223
 
3224
3224
  def populate_default_concepts(self):
@@ -3460,8 +3460,8 @@ class Environment(BaseModel):
3460
3460
 
3461
3461
  if not exists:
3462
3462
  self.imports[alias].append(imp_stm)
3463
- else:
3464
- return self
3463
+ # we can't exit early
3464
+ # as there may be new concepts
3465
3465
  for k, concept in source.concepts.items():
3466
3466
  if same_namespace:
3467
3467
  new = self.add_concept(concept, _ignore_cache=True)
@@ -3525,8 +3525,11 @@ class Environment(BaseModel):
3525
3525
  try:
3526
3526
  with open(target, "r", encoding="utf-8") as f:
3527
3527
  text = f.read()
3528
+ nenv = Environment(
3529
+ working_path=target.parent,
3530
+ )
3531
+ nenv.concepts.fail_on_missing = False
3528
3532
  nparser = ParseToObjects(
3529
- visit_tokens=True,
3530
3533
  environment=Environment(
3531
3534
  working_path=target.parent,
3532
3535
  ),
@@ -3535,6 +3538,7 @@ class Environment(BaseModel):
3535
3538
  )
3536
3539
  nparser.set_text(text)
3537
3540
  nparser.transform(PARSER.parse(text))
3541
+
3538
3542
  except Exception as e:
3539
3543
  raise ImportError(
3540
3544
  f"Unable to import file {target.parent}, parsing error: {e}"
@@ -227,7 +227,6 @@ def unwrap_transformation(
227
227
  class ParseToObjects(Transformer):
228
228
  def __init__(
229
229
  self,
230
- visit_tokens,
231
230
  environment: Environment,
232
231
  parse_address: str | None = None,
233
232
  token_address: Path | None = None,
@@ -235,7 +234,7 @@ class ParseToObjects(Transformer):
235
234
  tokens: dict[Path | str, ParseTree] | None = None,
236
235
  text_lookup: dict[Path | str, str] | None = None,
237
236
  ):
238
- Transformer.__init__(self, visit_tokens)
237
+ Transformer.__init__(self, True)
239
238
  self.environment: Environment = environment
240
239
  self.parse_address: str = parse_address or SELF_LABEL
241
240
  self.token_address: Path | str = token_address or SELF_LABEL
@@ -254,16 +253,20 @@ class ParseToObjects(Transformer):
254
253
  self.tokens[self.token_address] = tree
255
254
  return results
256
255
 
256
+ def prepare_parse(self):
257
+ self.pass_count = 1
258
+ self.environment.concepts.fail_on_missing = False
259
+ for _, v in self.parsed.items():
260
+ v.prepare_parse()
261
+
257
262
  def hydrate_missing(self):
258
263
  self.pass_count = 2
259
264
  for k, v in self.parsed.items():
260
-
261
265
  if v.pass_count == 2:
262
266
  continue
267
+ print(f"Hydrating {k}")
263
268
  v.hydrate_missing()
264
- # self.environment.concepts.fail_on_missing = True
265
- # if not self.environment.concepts.undefined:
266
- # return self._results_stash
269
+ self.environment.concepts.fail_on_missing = True
267
270
  reparsed = self.transform(self.tokens[self.token_address])
268
271
  self.environment.concepts.undefined = {}
269
272
  return reparsed
@@ -850,12 +853,12 @@ class ParseToObjects(Transformer):
850
853
  nparser = self.parsed[cache_lookup]
851
854
  else:
852
855
  try:
856
+ new_env = Environment(
857
+ working_path=dirname(target),
858
+ )
859
+ new_env.concepts.fail_on_missing = False
853
860
  nparser = ParseToObjects(
854
- visit_tokens=True,
855
- environment=Environment(
856
- working_path=dirname(target),
857
- # namespace=alias,
858
- ),
861
+ environment=new_env,
859
862
  parse_address=cache_lookup,
860
863
  token_address=token_lookup,
861
864
  parsed={**self.parsed, **{self.parse_address: self}},
@@ -1954,12 +1957,14 @@ def parse_text(text: str, environment: Optional[Environment] = None) -> Tuple[
1954
1957
  ],
1955
1958
  ]:
1956
1959
  environment = environment or Environment()
1957
- parser = ParseToObjects(visit_tokens=True, environment=environment)
1960
+ parser = ParseToObjects(environment=environment)
1958
1961
 
1959
1962
  try:
1960
1963
  parser.set_text(text)
1964
+ # disable fail on missing to allow for circular dependencies
1965
+ parser.prepare_parse()
1961
1966
  parser.transform(PARSER.parse(text))
1962
- # handle circular dependencies
1967
+ # this will reset fail on missing
1963
1968
  pass_two = parser.hydrate_missing()
1964
1969
  output = [v for v in pass_two if v]
1965
1970
  except VisitError as e:
File without changes
File without changes
File without changes
File without changes