pytrilogy 0.0.3.119__py3-none-any.whl → 0.0.3.121__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.119
3
+ Version: 0.0.3.121
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Classifier: Programming Language :: Python
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,5 +1,5 @@
1
- pytrilogy-0.0.3.119.dist-info/licenses/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
2
- trilogy/__init__.py,sha256=yAEhbbiEzNNNbrfLDM4oizZbA7BwdavMgSpAlAszpbk,304
1
+ pytrilogy-0.0.3.121.dist-info/licenses/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
2
+ trilogy/__init__.py,sha256=ioAcoV-BKlkqqPoHt2LnYLJorjamhK6uRkObUCvwA20,304
3
3
  trilogy/constants.py,sha256=_Tm7YGaAZuxH77X5ve0TajU0dQD7RcGV6ECrTHRL3qQ,2678
4
4
  trilogy/engine.py,sha256=v4TpNktM4zZ9OX7jZH2nde4dpX5uAH2U23ELfULTCSg,2280
5
5
  trilogy/executor.py,sha256=uKlCnPp4FHkgsa_dDcQJ4y-ObtvKat2KFx05c-z1mZo,17885
@@ -9,7 +9,7 @@ trilogy/render.py,sha256=qQWwduymauOlB517UtM-VGbVe8Cswa4UJub5aGbSO6c,1512
9
9
  trilogy/utility.py,sha256=euQccZLKoYBz0LNg5tzLlvv2YHvXh9HArnYp1V3uXsM,763
10
10
  trilogy/ai/__init__.py,sha256=H6gpzScruX2xgZNRDMjQ31Wy45irJbdebX1fU_gOwI8,581
11
11
  trilogy/ai/constants.py,sha256=Aj-_mFqskcXqIlBjX_A9eqH0V9M8mqX3uJwUhr9puak,5064
12
- trilogy/ai/conversation.py,sha256=I11xmUZikuKmh-W-jt38OvtyhpHwhpQ6Eeut6dkjI-c,3467
12
+ trilogy/ai/conversation.py,sha256=yei5iKsVCyo-GRmHtfto2grCjBs_TwAbGChD3w97pqg,3482
13
13
  trilogy/ai/enums.py,sha256=vghPPx0W-DioQSgq4T0MGL-8ekFh6O6d52dHo7KsKtg,118
14
14
  trilogy/ai/execute.py,sha256=DTARZxm_btCJq4Yd_jPRHJAcbsMLbjEsjR7KKyKBkTI,1335
15
15
  trilogy/ai/models.py,sha256=Au4QnTIlv7e-p3XgTJYZqTSndPMGRIbOvCUWlekE81A,683
@@ -35,12 +35,12 @@ trilogy/core/optimization.py,sha256=eKieOaWXUtoNTVQbThGA5tqrI06ZR6SUFOqGe4Jw0k4,
35
35
  trilogy/core/query_processor.py,sha256=rMrtLSQxVm7yeyh0nWjDNI9nnu4Xi0NgHvBJ14gvu4I,20384
36
36
  trilogy/core/utility.py,sha256=3VC13uSQWcZNghgt7Ot0ZTeEmNqs__cx122abVq9qhM,410
37
37
  trilogy/core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- trilogy/core/models/author.py,sha256=gsKPOwgnebnAs2HV72ZHdXYfoUzDs8jQNse8vEwtG3k,86081
38
+ trilogy/core/models/author.py,sha256=H6Jb6SzOdl3jY1P_P1NsPRW9ukUmxzDXB8RNd7Ieky0,85978
39
39
  trilogy/core/models/build.py,sha256=zVHD8jo8V8E0aGWtobzXG7hY3VjLChiW4s1QBx9sD5k,72938
40
40
  trilogy/core/models/build_environment.py,sha256=mpx7MKGc60fnZLVdeLi2YSREy7eQbQYycCrP4zF-rHU,5258
41
41
  trilogy/core/models/core.py,sha256=mv1QOxf-6uGoWpfwuucNAW3W_ZZGQuxtnPWAXhQsxSI,13290
42
42
  trilogy/core/models/datasource.py,sha256=wogTevZ-9CyUW2a8gjzqMCieircxi-J5lkI7EOAZnck,9596
43
- trilogy/core/models/environment.py,sha256=-r6_imqkJ10iPTbWGrdfeF2Th480UKLsG8ihACyqO8w,28823
43
+ trilogy/core/models/environment.py,sha256=m2NZ-UqmHQ1qJo6I-cVGG9Z24O6RTDkrvEd1IfVmWls,28889
44
44
  trilogy/core/models/execute.py,sha256=3fgEdho2e7S0outq91cCzb9jFwz6L1hTbsTrJwGvIFs,42311
45
45
  trilogy/core/optimizations/__init__.py,sha256=yspWc25M5SgAuvXYoSt5J8atyPbDlOfsKjIo5yGD9s4,368
46
46
  trilogy/core/optimizations/base_optimization.py,sha256=gzDOKImoFn36k7XBD3ysEYDnbnb6vdVIztUfFQZsGnM,513
@@ -50,7 +50,7 @@ trilogy/core/optimizations/predicate_pushdown.py,sha256=5ubatgq1IwWQ4L2FDt4--y16
50
50
  trilogy/core/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  trilogy/core/processing/concept_strategies_v3.py,sha256=MBQeJGBDW2w3xxwano43-5MVBqfbIU9M3K7RFbnSKNA,23367
52
52
  trilogy/core/processing/discovery_node_factory.py,sha256=llnLxZo1NqBRIuuPz0GUohym6LZFhVkPT3xSiORi3k4,15446
53
- trilogy/core/processing/discovery_utility.py,sha256=mO0npZMRlQSzxt3l4m8garKBAOrXFkzt3eiiUyUSoIU,13528
53
+ trilogy/core/processing/discovery_utility.py,sha256=FpCHCvGslHIJkMIOLBmTJRQKfUtwcwiNgzDxcOsJBIc,13532
54
54
  trilogy/core/processing/discovery_validation.py,sha256=eZ4HfHMpqZLI8MGG2jez8arS8THs6ceuVrQFIY6gXrU,5364
55
55
  trilogy/core/processing/graph_utils.py,sha256=8QUVrkE9j-9C1AyrCb1nQEh8daCe0u1HuXl-Te85lag,1205
56
56
  trilogy/core/processing/utility.py,sha256=ESs6pKqVP2c9eMdfB2JNjw7D7YnoezVwbLFx1D6OUYA,26088
@@ -74,7 +74,7 @@ trilogy/core/processing/node_generators/window_node.py,sha256=wNvmumGO6AIQ7C9bDU
74
74
  trilogy/core/processing/node_generators/select_helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
75
  trilogy/core/processing/node_generators/select_helpers/datasource_injection.py,sha256=m2YQ4OmG0N2O61a7NEq1ZzbTa7JsCC00lxB2ymjcYRI,8224
76
76
  trilogy/core/processing/nodes/__init__.py,sha256=zTge1EzwzEydlcMliIFO_TT7h7lS8l37lyZuQDir1h0,5487
77
- trilogy/core/processing/nodes/base_node.py,sha256=k4Z9qdL9BXxxHH66L5udQwSDcYeiaWEn3bRmy84SShs,18559
77
+ trilogy/core/processing/nodes/base_node.py,sha256=xrtijyy38xpTt3hzVdEVaDYhk1JWAuB8yGoDJ6R82Jg,18722
78
78
  trilogy/core/processing/nodes/filter_node.py,sha256=5VtRfKbCORx0dV-vQfgy3gOEkmmscL9f31ExvlODwvY,2461
79
79
  trilogy/core/processing/nodes/group_node.py,sha256=Ku8El9KQvRiTiHCZDS_jX0DjErSDNv7IIQMcd1Gsk7I,7449
80
80
  trilogy/core/processing/nodes/merge_node.py,sha256=4y_itKoipHKjpCIQjK9SHga-Fq-HqyeQLwAoSIFQ1hM,16567
@@ -100,7 +100,7 @@ trilogy/dialect/bigquery.py,sha256=XS3hpybeowgfrOrkycAigAF3NX2YUzTzfgE6f__2fT4,4
100
100
  trilogy/dialect/common.py,sha256=I5Ku_TR5MwJTB3ZhcQenrtvXhH2RvTQ8wQe9w5lfkfA,5708
101
101
  trilogy/dialect/config.py,sha256=olnyeVU5W5T6b9-dMeNAnvxuPlyc2uefb7FRME094Ec,3834
102
102
  trilogy/dialect/dataframe.py,sha256=nDTHMSd7GiGjEhjAobrZND0w4zjr-vgOalM2Cdxjets,1596
103
- trilogy/dialect/duckdb.py,sha256=Z_mxrfQXS3KP8PEbkKsCLolyjJgPEM-aBkVCdWiLph0,6312
103
+ trilogy/dialect/duckdb.py,sha256=Xycopzbfo6VyuNVrh2IdeL_HzWgyP0poKRbtoxNjDHA,6374
104
104
  trilogy/dialect/enums.py,sha256=FRNYQ5-w-B6-X0yXKNU5g9GowsMlERFogTC5u2nxL_s,4740
105
105
  trilogy/dialect/metadata.py,sha256=p_V-MYPQ2iR6fcTjagnptCIWtsZe4fTfoS_iXpavPzY,7098
106
106
  trilogy/dialect/postgres.py,sha256=el2PKwfyvWGk5EZtLudqAH5ewLitY1sFHJiocBSyxyM,3393
@@ -117,7 +117,7 @@ trilogy/parsing/common.py,sha256=GijDRpysULL6vQWpFcjgxVASuTWXUVUi5fILHvjzkbg,355
117
117
  trilogy/parsing/config.py,sha256=Z-DaefdKhPDmSXLgg5V4pebhSB0h590vI0_VtHnlukI,111
118
118
  trilogy/parsing/exceptions.py,sha256=Xwwsv2C9kSNv2q-HrrKC1f60JNHShXcCMzstTSEbiCw,154
119
119
  trilogy/parsing/helpers.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
120
- trilogy/parsing/parse_engine.py,sha256=j0lBbJGObcptw4S7xng2hy-Pv-u5aSfFuxYk6TZvciY,87661
120
+ trilogy/parsing/parse_engine.py,sha256=6oknUq7fibJAKMHUtC1cbBkWkU-r75XU20tfyjCQdes,87662
121
121
  trilogy/parsing/render.py,sha256=k7MNp8EBTqVBSVqFlgTHSwIhfSKLyJfSeb2fSbt9dVA,24307
122
122
  trilogy/parsing/trilogy.lark,sha256=_FW9Hq7Xo6KDrf1JUxD9NBM0Zn9OyoZzWHj97zFqy-M,17449
123
123
  trilogy/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -133,8 +133,8 @@ trilogy/std/net.preql,sha256=WZCuvH87_rZntZiuGJMmBDMVKkdhTtxeHOkrXNwJ1EE,416
133
133
  trilogy/std/ranking.preql,sha256=zDdmHcTerlCjaHDdVyjGTgcc2hAhnlDM_q5tiw0MPGE,108
134
134
  trilogy/std/report.preql,sha256=LbV-XlHdfw0jgnQ8pV7acG95xrd1-p65fVpiIc-S7W4,202
135
135
  trilogy/std/semantic.preql,sha256=k9_k672nUb5MKjSD1DW5jjn_odoYHl0yNeRPOjFabsE,95
136
- pytrilogy-0.0.3.119.dist-info/METADATA,sha256=VyzNM-tcKiVnWkJP1MRh61gk61nRWjcIn7I3yRKiSHU,12911
137
- pytrilogy-0.0.3.119.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
138
- pytrilogy-0.0.3.119.dist-info/entry_points.txt,sha256=ewBPU2vLnVexZVnB-NrVj-p3E-4vukg83Zk8A55Wp2w,56
139
- pytrilogy-0.0.3.119.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
140
- pytrilogy-0.0.3.119.dist-info/RECORD,,
136
+ pytrilogy-0.0.3.121.dist-info/METADATA,sha256=eNCGHIW6_9XmDhoM4CcLmCYjjEgVD9h8ltJk8jFexMM,12911
137
+ pytrilogy-0.0.3.121.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
138
+ pytrilogy-0.0.3.121.dist-info/entry_points.txt,sha256=ewBPU2vLnVexZVnB-NrVj-p3E-4vukg83Zk8A55Wp2w,56
139
+ pytrilogy-0.0.3.121.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
140
+ pytrilogy-0.0.3.121.dist-info/RECORD,,
trilogy/__init__.py CHANGED
@@ -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.119"
7
+ __version__ = "0.0.3.121"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -61,7 +61,7 @@ class Conversation:
61
61
  if "```" in content:
62
62
  parts = content.split("```")
63
63
  if len(parts) >= 3:
64
- return parts[1].strip()
64
+ return parts[-2].strip()
65
65
  return content
66
66
 
67
67
  def generate_query(
@@ -78,7 +78,7 @@ class Conversation:
78
78
  if not response.strip()[-1] == ";":
79
79
  response += ";"
80
80
  try:
81
- env, raw = environment.parse(response)
81
+ _, raw = environment.parse(response)
82
82
  process_query(statement=raw[-1], environment=environment)
83
83
  return response
84
84
  except (
@@ -90,10 +90,9 @@ class Conversation:
90
90
  ) as e2:
91
91
  e = e2
92
92
  self.add_message(
93
- f"The previous response could not be parsed due to the error: {str(e)}. Please generate a new query with the issues fixed. Use the same response format.",
93
+ f"Your extracted response - {response} - could not be parsed due to the error: {str(e)}. Please generate a new query with the issues fixed. Use the same response format.",
94
94
  role="user",
95
95
  )
96
-
97
96
  raise Exception(
98
97
  f"Failed to generate a valid query after {attempts} attempts. Last error: {str(e)}. Full conversation: {self.messages}"
99
98
  )
@@ -162,14 +162,13 @@ class ConceptRef(Addressable, Namespaced, DataTyped, Mergeable, BaseModel):
162
162
  )
163
163
 
164
164
  def with_reference_replacement(self, source: str, target: Expr | ArgBinding):
165
- if self.address == source:
166
- return target
167
-
168
165
  # a reference might be to an attribute of a struct that is bound late
169
166
  # if the replacement is a parent in the access path; replace reference
170
167
  # with an attribute access call
171
- candidates = [f"local.{self.address}", self.address]
168
+ candidates = [f"{DEFAULT_NAMESPACE}.{self.address}", self.address]
172
169
  for candidate in candidates:
170
+ if candidate == source:
171
+ return target
173
172
  if not candidate.startswith(f"{source}."):
174
173
  continue
175
174
  attribute = self.address.rsplit(".", 1)[1]
@@ -2535,11 +2534,7 @@ class CustomFunctionFactory:
2535
2534
  target = f"{DEFAULT_NAMESPACE}.{self.function_arguments[idx].name}"
2536
2535
  else:
2537
2536
  target = self.function_arguments[idx].name
2538
- nout = (
2539
- nout.with_reference_replacement(target, x)
2540
- if isinstance(nout, Mergeable)
2541
- else nout
2542
- )
2537
+ nout = nout.with_reference_replacement(target, x)
2543
2538
  return nout
2544
2539
 
2545
2540
 
@@ -215,7 +215,7 @@ class Environment(BaseModel):
215
215
  functions: Dict[str, CustomFunctionFactory] = Field(default_factory=dict)
216
216
  data_types: Dict[str, CustomType] = Field(default_factory=dict)
217
217
  named_statements: Dict[str, SelectLineage] = Field(default_factory=dict)
218
- imports: Dict[str, list[Import]] = Field(
218
+ imports: defaultdict[str, list[Import]] = Field(
219
219
  default_factory=lambda: defaultdict(list) # type: ignore
220
220
  )
221
221
  namespace: str = DEFAULT_NAMESPACE
@@ -252,7 +252,7 @@ class Environment(BaseModel):
252
252
  concepts=self.concepts.duplicate(),
253
253
  functions=dict(self.functions),
254
254
  data_types=dict(self.data_types),
255
- imports=dict(self.imports),
255
+ imports=defaultdict(list, self.imports),
256
256
  namespace=self.namespace,
257
257
  working_path=self.working_path,
258
258
  environment_config=self.config.model_copy(deep=True),
@@ -262,6 +262,7 @@ class Environment(BaseModel):
262
262
  alias_origin_lookup={
263
263
  k: v.duplicate() for k, v in self.alias_origin_lookup.items()
264
264
  },
265
+ env_file_path=self.env_file_path,
265
266
  )
266
267
 
267
268
  def _add_path_concepts(self):
@@ -40,15 +40,15 @@ def calculate_effective_parent_grain(
40
40
  pairs = join.concept_pairs or []
41
41
  for key in pairs:
42
42
  left = key.existing_datasource
43
- logger.info(f"adding left grain {left.grain} for join key {key.left}")
43
+ logger.debug(f"adding left grain {left.grain} for join key {key.left}")
44
44
  grain += left.grain
45
45
  seen.add(left.name)
46
46
  keys = [key.right for key in pairs]
47
47
  join_grain = BuildGrain.from_concepts(keys)
48
48
  if join_grain == join.right_datasource.grain:
49
- logger.info(f"irrelevant right join {join}, does not change grain")
49
+ logger.debug(f"irrelevant right join {join}, does not change grain")
50
50
  else:
51
- logger.info(
51
+ logger.debug(
52
52
  f"join changes grain, adding {join.right_datasource.grain} to {grain}"
53
53
  )
54
54
  grain += join.right_datasource.grain
@@ -68,7 +68,7 @@ def calculate_effective_parent_grain(
68
68
  ]
69
69
  )
70
70
  ):
71
- logger.info(f"adding unjoined grain {x.grain} for datasource {x.name}")
71
+ logger.debug(f"adding unjoined grain {x.grain} for datasource {x.name}")
72
72
  grain += x.grain
73
73
  return grain
74
74
  else:
@@ -258,10 +258,14 @@ class StrategyNode:
258
258
  self.partial_lcl = LooseBuildConceptList(concepts=partials)
259
259
  return partials
260
260
 
261
- def add_output_concepts(self, concepts: List[BuildConcept], rebuild: bool = True):
261
+ def add_output_concepts(
262
+ self, concepts: List[BuildConcept], rebuild: bool = True, unhide: bool = True
263
+ ):
262
264
  for concept in concepts:
263
265
  if concept.address not in self.output_lcl.addresses:
264
266
  self.output_concepts.append(concept)
267
+ if unhide and concept.address in self.hidden_concepts:
268
+ self.hidden_concepts.remove(concept.address)
265
269
  self.output_lcl = LooseBuildConceptList(concepts=self.output_concepts)
266
270
  if rebuild:
267
271
  self.rebuild_cache()
trilogy/dialect/duckdb.py CHANGED
@@ -104,6 +104,7 @@ FUNCTION_MAP = {
104
104
  FunctionType.CONCAT: lambda x: f"({' || '.join(x)})",
105
105
  FunctionType.DATE_LITERAL: lambda x: f"date '{x}'",
106
106
  FunctionType.DATETIME_LITERAL: lambda x: f"datetime '{x}'",
107
+ FunctionType.DAY_OF_WEEK: lambda x: f"dayofweek({x[0]})",
107
108
  # string
108
109
  FunctionType.CONTAINS: lambda x: f"CONTAINS(LOWER({x[0]}), LOWER({x[1]}))",
109
110
  # regexp
@@ -1516,6 +1516,7 @@ class ParseToObjects(Transformer):
1516
1516
  remapped = FunctionCallWrapper(
1517
1517
  content=self.environment.functions[name](*args), name=name, args=args
1518
1518
  )
1519
+
1519
1520
  return remapped
1520
1521
 
1521
1522
  @v_args(meta=True)