informatica-python 1.5.1__tar.gz → 1.5.2__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 (29) hide show
  1. {informatica_python-1.5.1 → informatica_python-1.5.2}/PKG-INFO +1 -1
  2. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/__init__.py +1 -1
  3. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/converter.py +4 -0
  4. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/utils/expression_converter.py +41 -5
  5. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python.egg-info/PKG-INFO +1 -1
  6. {informatica_python-1.5.1 → informatica_python-1.5.2}/pyproject.toml +1 -1
  7. {informatica_python-1.5.1 → informatica_python-1.5.2}/tests/test_integration.py +9 -0
  8. {informatica_python-1.5.1 → informatica_python-1.5.2}/LICENSE +0 -0
  9. {informatica_python-1.5.1 → informatica_python-1.5.2}/README.md +0 -0
  10. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/cli.py +0 -0
  11. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/generators/__init__.py +0 -0
  12. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/generators/config_gen.py +0 -0
  13. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/generators/error_log_gen.py +0 -0
  14. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/generators/helper_gen.py +0 -0
  15. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/generators/mapping_gen.py +0 -0
  16. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/generators/sql_gen.py +0 -0
  17. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/generators/workflow_gen.py +0 -0
  18. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/models.py +0 -0
  19. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/parser.py +0 -0
  20. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/utils/__init__.py +0 -0
  21. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/utils/datatype_map.py +0 -0
  22. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python/utils/lib_adapters.py +0 -0
  23. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python.egg-info/SOURCES.txt +0 -0
  24. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python.egg-info/dependency_links.txt +0 -0
  25. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python.egg-info/entry_points.txt +0 -0
  26. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python.egg-info/requires.txt +0 -0
  27. {informatica_python-1.5.1 → informatica_python-1.5.2}/informatica_python.egg-info/top_level.txt +0 -0
  28. {informatica_python-1.5.1 → informatica_python-1.5.2}/setup.cfg +0 -0
  29. {informatica_python-1.5.1 → informatica_python-1.5.2}/tests/test_converter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: informatica-python
3
- Version: 1.5.1
3
+ Version: 1.5.2
4
4
  Summary: Convert Informatica PowerCenter workflow XML to Python/PySpark code
5
5
  Author: Nick
6
6
  License: MIT
@@ -7,7 +7,7 @@ Licensed under the MIT License.
7
7
 
8
8
  from informatica_python.converter import InformaticaConverter
9
9
 
10
- __version__ = "1.5.1"
10
+ __version__ = "1.5.2"
11
11
  __author__ = "Nick"
12
12
  __license__ = "MIT"
13
13
  __all__ = ["InformaticaConverter"]
@@ -90,6 +90,10 @@ class InformaticaConverter:
90
90
  def _convert_folder(self, folder: FolderDef, output_dir: str,
91
91
  output_zip: Optional[str] = None,
92
92
  param_file: Optional[str] = None) -> str:
93
+ if param_file:
94
+ from informatica_python.utils.expression_converter import parse_param_file
95
+ parse_param_file(param_file)
96
+
93
97
  files = {}
94
98
 
95
99
  files["helper_functions.py"] = generate_helper_functions(folder, self.data_lib)
@@ -295,8 +295,8 @@ def _vectorize_value(val, df_var="df"):
295
295
  return val
296
296
 
297
297
 
298
- def _vectorize_condition(cond, df_var="df"):
299
- c = cond.strip()
298
+ def _vectorize_simple(part, df_var):
299
+ c = part.strip()
300
300
 
301
301
  c = re.sub(r'\bISNULL\s*\(\s*([A-Za-z_]\w*)\s*\)',
302
302
  lambda m: f'{df_var}["{m.group(1)}"].isna()', c, flags=re.IGNORECASE)
@@ -305,9 +305,6 @@ def _vectorize_condition(cond, df_var="df"):
305
305
  c = re.sub(r'\b([A-Za-z_]\w*)\s*IS\s+NULL\b',
306
306
  lambda m: f'{df_var}["{m.group(1)}"].isna()', c, flags=re.IGNORECASE)
307
307
 
308
- c = re.sub(r'\bAND\b', ' & ', c, flags=re.IGNORECASE)
309
- c = re.sub(r'\bOR\b', ' | ', c, flags=re.IGNORECASE)
310
- c = re.sub(r'\bNOT\s+', ' ~', c, flags=re.IGNORECASE)
311
308
  c = re.sub(r'<>', '!=', c)
312
309
  c = re.sub(r'(?<![<>!=])=(?!=)', '==', c)
313
310
 
@@ -322,6 +319,45 @@ def _vectorize_condition(cond, df_var="df"):
322
319
  return c
323
320
 
324
321
 
322
+ def _vectorize_condition(cond, df_var="df"):
323
+ c = cond.strip()
324
+
325
+ tokens = re.split(r'\b(AND|OR)\b', c, flags=re.IGNORECASE)
326
+
327
+ parts = []
328
+ ops = []
329
+ for tok in tokens:
330
+ stripped = tok.strip()
331
+ if stripped.upper() in ('AND', 'OR'):
332
+ ops.append('&' if stripped.upper() == 'AND' else '|')
333
+ elif stripped:
334
+ parts.append(stripped)
335
+
336
+ if not parts:
337
+ return "True"
338
+
339
+ vectorized = []
340
+ for part in parts:
341
+ negate = False
342
+ inner = part.strip()
343
+ if re.match(r'^NOT\s+', inner, flags=re.IGNORECASE):
344
+ negate = True
345
+ inner = re.sub(r'^NOT\s+', '', inner, flags=re.IGNORECASE).strip()
346
+ v = _vectorize_simple(inner, df_var)
347
+ if negate:
348
+ v = f"~({v})"
349
+ vectorized.append(v)
350
+
351
+ if len(vectorized) == 1:
352
+ return vectorized[0]
353
+
354
+ result_parts = [f"({vectorized[0]})"]
355
+ for i, op in enumerate(ops):
356
+ result_parts.append(f" {op} ")
357
+ result_parts.append(f"({vectorized[i + 1]})")
358
+ return "".join(result_parts)
359
+
360
+
325
361
  def convert_filter_expression(expr):
326
362
  if not expr or not expr.strip():
327
363
  return "True"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: informatica-python
3
- Version: 1.5.1
3
+ Version: 1.5.2
4
4
  Summary: Convert Informatica PowerCenter workflow XML to Python/PySpark code
5
5
  Author: Nick
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "informatica-python"
7
- version = "1.5.1"
7
+ version = "1.5.2"
8
8
  description = "Convert Informatica PowerCenter workflow XML to Python/PySpark code"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -210,10 +210,18 @@ class TestFilterVectorized:
210
210
  assert 'df["A"]' in result
211
211
  assert 'df["B"]' in result
212
212
  assert "AND" not in result
213
+ assert "(df[" in result
213
214
 
214
215
  def test_or_condition(self):
215
216
  result = convert_filter_vectorized("STATUS = 'A' OR STATUS = 'B'", "df")
216
217
  assert "|" in result
218
+ assert "(df[" in result
219
+
220
+ def test_not_condition(self):
221
+ result = convert_filter_vectorized("NOT A = 1", "df")
222
+ assert "~(" in result
223
+ assert 'df["A"]' in result
224
+ assert "==" in result
217
225
 
218
226
  def test_is_null_filter(self):
219
227
  result = convert_filter_vectorized("NAME IS NULL", "df_src")
@@ -232,6 +240,7 @@ class TestFilterVectorized:
232
240
  result = convert_expression_vectorized("IIF(A > 1 AND B < 2, 1, 0)", "df")
233
241
  assert "np.where" in result
234
242
  assert "&" in result
243
+ assert "(" in result
235
244
 
236
245
 
237
246
  class TestLibAdapters: