python-table-processor 0.3.2__py3-none-any.whl → 0.3.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-table-processor
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: A table data processor
5
5
  Home-page: https://github.com/akivajp/python-table-processor
6
6
  License: MIT
@@ -1,8 +1,8 @@
1
- table_processor/__init__.py,sha256=TQqqDugVb2WjmgqPXyxUA42oi3QOxyPDqpr09kjKGlk,52
1
+ table_processor/__init__.py,sha256=7OSG5h81lLUUtcYTKQ2mDbsjJLsWCC6uFVXVJlfe8FE,52
2
2
  table_processor/cli.py,sha256=uluf_VsBzq3Ldxh3ePGseSrv8--lI7huu-6RjDaHPPg,2170
3
3
  table_processor/commands/convert_tables.py,sha256=j25KL0zRl5ikrBk73jAkKn4rPmDq7SecChZxecDpILQ,2123
4
4
  table_processor/commands/merge_tables.py,sha256=Uu-hjfPh69Of0_OZrY8sY0oscpLSdK4jwJ_t1qgfPMg,1485
5
- table_processor/core/actions.py,sha256=iCBm-tj_gTxeHxPaBSILdYAe8-75XaDtsCOTJp1jGfA,20264
5
+ table_processor/core/actions.py,sha256=GKUKzoPxUEuWSeuY-HsqFoS5Bdm99bjkRhuBgG1s_uk,23658
6
6
  table_processor/core/config.py,sha256=Z1s2r3y4oQXdbDCwIY_hYzoq6VRv7Sb3oUlfBCu13Lc,11646
7
7
  table_processor/core/constants.py,sha256=w-1TxtpXywb6Qh8M4YWuzcCHUvCjy5zJYxaXC3RQS6A,158
8
8
  table_processor/core/convert.py,sha256=cibzqJ5hHsfX_7qUz4kE2Gi-WH4UMqecBl3kSb4IVsY,11140
@@ -15,9 +15,9 @@ table_processor/core/functions/set_flat_field_value.py,sha256=7-BgD2yEUGyBaFaIJ1
15
15
  table_processor/core/functions/set_nested_field_value.py,sha256=csO0v_nW94q-M9bNL91xR-TLHPXDDxnLK8gN-0LLd6k,595
16
16
  table_processor/core/functions/set_row_value.py,sha256=wlF_nVGZY74XCzd6pBJJyti62m6y0s1kc5Q6uq9jn8o,641
17
17
  table_processor/core/merge.py,sha256=Yc5OV9n1xV9QtgY4srl6Susd5cOKbuYseEtYuBampDw,4672
18
- table_processor/core/types.py,sha256=rxmiWsUCEBkjveO84tbMJ1kVn_P13Ywl89wDHMWEej0,2580
19
- python_table_processor-0.3.2.dist-info/LICENSE,sha256=1_Gn0I1neLPxDLfLiHEyxjDg-pbAra1p2iHEqutGS_c,1068
20
- python_table_processor-0.3.2.dist-info/METADATA,sha256=PCCGEqAansu5aIrmLu4eaFl3HhD2DCbDuDt2ru0-nRs,1098
21
- python_table_processor-0.3.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
22
- python_table_processor-0.3.2.dist-info/entry_points.txt,sha256=lq97F6m51yZ93qmVIqkUHJfbILZuYLxrMWXSqrP4JpM,118
23
- python_table_processor-0.3.2.dist-info/RECORD,,
18
+ table_processor/core/types.py,sha256=xNvy1vL1ei87kt-MgSfRJSllYrNKRo23pHtJA15DyLQ,2895
19
+ python_table_processor-0.3.4.dist-info/LICENSE,sha256=1_Gn0I1neLPxDLfLiHEyxjDg-pbAra1p2iHEqutGS_c,1068
20
+ python_table_processor-0.3.4.dist-info/METADATA,sha256=c9BCBmEomxvkfcU2FpuhGvFT2TM183wdYiCcDy4yQQA,1098
21
+ python_table_processor-0.3.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
22
+ python_table_processor-0.3.4.dist-info/entry_points.txt,sha256=lq97F6m51yZ93qmVIqkUHJfbILZuYLxrMWXSqrP4JpM,118
23
+ python_table_processor-0.3.4.dist-info/RECORD,,
@@ -1,2 +1,2 @@
1
- __version__ = "0.3.2"
2
- __version_tuple__ = (0, 3, 2)
1
+ __version__ = "0.3.4"
2
+ __version_tuple__ = (0, 3, 4)
@@ -29,6 +29,7 @@ from . types import (
29
29
  AssignFormatConfig,
30
30
  AssignIdConfig,
31
31
  AssignLengthConfig,
32
+ CastConfig,
32
33
  FilterConfig,
33
34
  GlobalStatus,
34
35
  JoinConfig,
@@ -147,6 +148,31 @@ def setup_actions_with_args(
147
148
  source = source,
148
149
  ))
149
150
  continue
151
+ if action_name == 'cast':
152
+ required = options.get('required', False)
153
+ as_type = options.get('as', 'literal')
154
+ if as_type in ['boolean']:
155
+ as_type = 'bool'
156
+ if as_type not in ['bool', 'int', 'float', 'str']:
157
+ raise ValueError(
158
+ f'Unsupported as type: {as_type}'
159
+ )
160
+ assign_default = False
161
+ default_value = None
162
+ if 'default' in options:
163
+ assign_default = True
164
+ default_value = options['default']
165
+ if default_value in ['None', 'none', 'Null', 'null']:
166
+ default_value = None
167
+ config.actions.append(CastConfig(
168
+ target = target,
169
+ source = source,
170
+ as_type = as_type,
171
+ required = required,
172
+ assign_default = assign_default,
173
+ default_value = default_value,
174
+ ))
175
+ continue
150
176
  if action_name == 'filter-empty':
151
177
  config.actions.append(FilterConfig(
152
178
  field = target,
@@ -177,15 +203,26 @@ def setup_actions_with_args(
177
203
  if action_name == 'parse':
178
204
  as_type = options.get('as', 'literal')
179
205
  required = options.get('required', False)
180
- if as_type not in ['json', 'literal']:
206
+ if as_type in ['boolean']:
207
+ as_type = 'bool'
208
+ if as_type not in ['bool', 'json', 'literal']:
181
209
  raise ValueError(
182
210
  f'Unsupported as type: {as_type}'
183
211
  )
212
+ assign_default = False
213
+ default_value = None
214
+ if 'default' in options:
215
+ assign_default = True
216
+ default_value = options['default']
217
+ if default_value in ['None', 'none', 'Null', 'null']:
218
+ default_value = None
184
219
  config.actions.append(ParseConfig(
185
220
  target = target,
186
221
  source = source,
187
222
  as_type = as_type,
188
223
  required = required,
224
+ assign_default = assign_default,
225
+ default_value = default_value,
189
226
  ))
190
227
  continue
191
228
  if action_name == 'parse-json':
@@ -312,6 +349,8 @@ def do_action(
312
349
  return assign_id(status.id_context_map, row, action)
313
350
  if isinstance(action, AssignLengthConfig):
314
351
  return assign_length(row, action)
352
+ if isinstance(action, CastConfig):
353
+ return cast(row, action)
315
354
  if isinstance(action, FilterConfig):
316
355
  if filter_row(row, action):
317
356
  return row
@@ -599,27 +638,48 @@ def parse(
599
638
  f'Required field not found, field: {config.source}'
600
639
  )
601
640
  if found:
602
- if type(value) == str:
603
- if config.as_type == 'literal':
604
- try:
641
+ if config.as_type == 'literal':
642
+ try:
643
+ if type(value) is str:
605
644
  parsed = ast.literal_eval(value)
606
- except:
607
- raise ValueError(
608
- f'Failed to parse literal: {value}'
609
- )
610
- elif config.as_type == 'json':
611
- try:
645
+ else:
646
+ parsed = value
647
+ except:
648
+ raise ValueError(
649
+ f'Failed to parse literal: {value}'
650
+ )
651
+ elif config.as_type == 'json':
652
+ try:
653
+ if type(value) is str:
612
654
  parsed = json.loads(value)
613
- except:
655
+ else:
656
+ parsed = value
657
+ except:
658
+ raise ValueError(
659
+ f'Failed to parse JSON: {value}'
660
+ )
661
+ elif config.as_type == 'bool':
662
+ if config.assign_default and value in [None, '']:
663
+ value = config.default_value
664
+ if type(value) is bool:
665
+ parsed = value
666
+ elif type(value) is str:
667
+ if value.lower() in ['true', 'yes', 'on', '1']:
668
+ parsed = True
669
+ elif value.lower() in ['false', 'no', 'off', '0']:
670
+ parsed = False
671
+ else:
614
672
  raise ValueError(
615
- f'Failed to parse JSON: {value}'
673
+ f'Failed to parse bool: {value}'
616
674
  )
617
675
  else:
618
676
  raise ValueError(
619
- f'Unsupported as type: {config.as_type}'
677
+ f'Failed to parse bool: {value}'
620
678
  )
621
679
  else:
622
- parsed = value
680
+ raise ValueError(
681
+ f'Unsupported as type: {config.as_type}'
682
+ )
623
683
  set_row_staging_value(row, config.target, parsed)
624
684
  return row
625
685
 
@@ -653,3 +713,37 @@ def assign_length(
653
713
  if found:
654
714
  set_row_staging_value(row, config.target, len(value))
655
715
  return row
716
+
717
+ def cast(
718
+ row: Row,
719
+ config: CastConfig,
720
+ ):
721
+ value, found = search_column_value(row.nested, config.source)
722
+ if config.required:
723
+ if not found:
724
+ raise ValueError(
725
+ f'Required field not found, field: {config.source}'
726
+ )
727
+ if config.as_type == 'bool':
728
+ cast_func = bool
729
+ elif config.as_type == 'int':
730
+ cast_func = int
731
+ elif config.as_type == 'float':
732
+ cast_func = float
733
+ elif config.as_type == 'str':
734
+ cast_func = str
735
+ else:
736
+ raise ValueError(
737
+ f'Unsupported as type: {config.as_type}'
738
+ )
739
+ try:
740
+ casted = cast_func(value)
741
+ except:
742
+ if config.assign_default:
743
+ casted = config.default_value
744
+ else:
745
+ raise ValueError(
746
+ f'Failed to cast: {value}'
747
+ )
748
+ set_row_staging_value(row, config.target, casted)
749
+ return row
@@ -51,6 +51,17 @@ class AssignLengthConfig:
51
51
  target: str
52
52
  source: str
53
53
 
54
+ @dataclasses.dataclass
55
+ class CastConfig:
56
+ target: str
57
+ source: str
58
+ as_type: Literal[
59
+ 'bool', 'int', 'float', 'str'
60
+ ]
61
+ required: bool = False
62
+ assign_default: bool = False
63
+ default_value: Any = None
64
+
54
65
  @dataclasses.dataclass
55
66
  class FilterConfig:
56
67
  field: str
@@ -74,8 +85,12 @@ class OmitConfig:
74
85
  class ParseConfig:
75
86
  target: str
76
87
  source: str
77
- as_type: Literal['json', 'literal']
88
+ as_type: Literal[
89
+ 'bool', 'json', 'literal'
90
+ ]
78
91
  required: bool = False
92
+ assign_default: bool = False
93
+ default_value: Any = None
79
94
 
80
95
  @dataclasses.dataclass
81
96
  class PickConfig: