mappingtools 0.2.2__tar.gz → 0.3.1__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.
- {mappingtools-0.2.2 → mappingtools-0.3.1}/.github/workflows/test-beta.yml +1 -1
- {mappingtools-0.2.2 → mappingtools-0.3.1}/.gitignore +2 -0
- {mappingtools-0.2.2 → mappingtools-0.3.1}/PKG-INFO +176 -136
- {mappingtools-0.2.2 → mappingtools-0.3.1}/README.md +173 -133
- {mappingtools-0.2.2 → mappingtools-0.3.1}/pyproject.toml +4 -4
- mappingtools-0.3.1/src/mappingtools/__init__.py +1 -0
- mappingtools-0.3.1/src/mappingtools/_tools.py +10 -0
- mappingtools-0.3.1/src/mappingtools/collectors.py +162 -0
- mappingtools-0.3.1/src/mappingtools/operators.py +157 -0
- mappingtools-0.3.1/src/mappingtools/transformers/__init__.py +7 -0
- mappingtools-0.3.1/src/mappingtools/transformers/listify.py +39 -0
- mappingtools-0.3.1/src/mappingtools/transformers/simplify.py +15 -0
- mappingtools-0.3.1/src/mappingtools/transformers/strictify.py +49 -0
- mappingtools-0.3.1/src/mappingtools/transformers/stringify.py +51 -0
- mappingtools-0.3.1/src/mappingtools/transformers/transformer.py +75 -0
- mappingtools-0.3.1/src/mappingtools/typing.py +7 -0
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/collectors}/test_category_counter.py +2 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/collectors}/test_mapping_collector.py +2 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/collectors}/test_mapping_collector_collect.py +2 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/collectors}/test_mapping_collector_repr.py +2 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/collectors}/test_nested_defaultdict.py +2 -2
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/operators}/test_distinct.py +1 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/operators}/test_flattened.py +16 -10
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/operators}/test_inverse.py +1 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/operators}/test_keep.py +2 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/operators}/test_remove.py +1 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/operators}/test_stream.py +1 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/operators}/test_stream_dict_records.py +2 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/operators}/test_stream_namedtuples.py +2 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/transformers}/test_listify.py +1 -1
- {mappingtools-0.2.2/tests → mappingtools-0.3.1/tests/transformers}/test_simplify.py +43 -13
- mappingtools-0.3.1/tests/transformers/test_stringify.py +257 -0
- mappingtools-0.2.2/src/mappingtools.py +0 -424
- {mappingtools-0.2.2 → mappingtools-0.3.1}/.github/dependabot.yml +0 -0
- {mappingtools-0.2.2 → mappingtools-0.3.1}/.github/workflows/publish.yml +0 -0
- {mappingtools-0.2.2 → mappingtools-0.3.1}/.github/workflows/test.yml +0 -0
- {mappingtools-0.2.2 → mappingtools-0.3.1}/LICENSE +0 -0
|
@@ -16,7 +16,7 @@ jobs:
|
|
|
16
16
|
fail-fast: false
|
|
17
17
|
matrix:
|
|
18
18
|
# https://github.com/actions/python-versions/blob/main/versions-manifest.json
|
|
19
|
-
python-version: [ "3.14.0-alpha.
|
|
19
|
+
python-version: [ "3.14.0-alpha.4" ]
|
|
20
20
|
steps:
|
|
21
21
|
- uses: actions/checkout@v4
|
|
22
22
|
- name: Set up Python ${{ matrix.python-version }}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: mappingtools
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: MappingTools. Do stuff with Mappings
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: MappingTools. Do stuff with Mappings and more
|
|
5
5
|
Project-URL: Homepage, https://erivlis.github.io/mappingtools
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/erivlis/mappingtools/issues
|
|
7
7
|
Project-URL: Source, https://github.com/erivlis/mappingtools
|
|
@@ -43,6 +43,10 @@ Description-Content-Type: text/markdown
|
|
|
43
43
|
|
|
44
44
|
# MappingTools
|
|
45
45
|
|
|
46
|
+
> Do stuff with Mappings and more!!!
|
|
47
|
+
|
|
48
|
+
## Introdcution
|
|
49
|
+
|
|
46
50
|
This library provides utility functions for manipulating and transforming data structures which have or include
|
|
47
51
|
Mapping-like characteristics. Including inverting dictionaries, converting class like objects to dictionaries, creating
|
|
48
52
|
nested defaultdicts, and unwrapping complex objects.
|
|
@@ -95,13 +99,79 @@ nested defaultdicts, and unwrapping complex objects.
|
|
|
95
99
|
<br>
|
|
96
100
|
<a href="https://app.codacy.com/gh/erivlis/mappingtools/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img alt="Codacy Quality" src="https://app.codacy.com/project/badge/Grade/8b83a99f939b4883ae2f37d7ec3419d1"></a>
|
|
97
101
|
<a href="https://app.codacy.com/gh/erivlis/mappingtools/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage"><img alt="Codacy Coverage" src="https://app.codacy.com/project/badge/Coverage/8b83a99f939b4883ae2f37d7ec3419d1"/></a>
|
|
102
|
+
<br>
|
|
103
|
+
<a href="https://www.codefactor.io/repository/github/erivlis/mappingtools/overview/main"><img src="https://www.codefactor.io/repository/github/erivlis/mappingtools/badge/main" alt="CodeFactor" /></a>
|
|
104
|
+
<br>
|
|
105
|
+
<a href="https://snyk.io/test/github/erivlis/mappingtools"><img alt="Snyk" src="https://snyk.io/test/github/erivlis/mappingtools/badge.svg"></a>
|
|
98
106
|
</td>
|
|
99
107
|
</tr>
|
|
100
108
|
</table>
|
|
101
109
|
|
|
102
110
|
## Usage
|
|
103
111
|
|
|
104
|
-
###
|
|
112
|
+
### Collectors
|
|
113
|
+
|
|
114
|
+
Collectors are classes that collect data items into a Mapping.
|
|
115
|
+
|
|
116
|
+
#### `CategoryCounter`
|
|
117
|
+
|
|
118
|
+
The CategoryCounter class extends a dictionary to count occurrences of data items categorized by multiple categories.
|
|
119
|
+
It maintains a total count of all data items and allows categorization using direct values or functions.
|
|
120
|
+
|
|
121
|
+
<!-- name: test_category_counter -->
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from mappingtools.collectors import CategoryCounter
|
|
125
|
+
|
|
126
|
+
counter = CategoryCounter()
|
|
127
|
+
|
|
128
|
+
for fruit in ['apple', 'banana', 'apple']:
|
|
129
|
+
counter.update({fruit: 1}, type='fruit', char_count=len(fruit), unique_char_count=len(set(fruit)))
|
|
130
|
+
|
|
131
|
+
print(counter.total)
|
|
132
|
+
# Output: Counter({'apple': 2, 'banana': 1})
|
|
133
|
+
|
|
134
|
+
print(counter)
|
|
135
|
+
# Output: CategoryCounter({'type': defaultdict(<class 'collections.Counter'>, {'fruit': Counter({'apple': 2, 'banana': 1})}), 'char_count': defaultdict(<class 'collections.Counter'>, {5: Counter({'apple': 2}), 6: Counter({'banana': 1})}), 'unique_char_count': defaultdict(<class 'collections.Counter'>, {4: Counter({'apple': 2}), 3: Counter({'banana': 1})})})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### `MappingCollector`
|
|
139
|
+
|
|
140
|
+
A class designed to collect key-value pairs into an internal mapping based on different modes.
|
|
141
|
+
It supports modes like ALL, COUNT, DISTINCT, FIRST, and LAST, each dictating how key-value pairs are
|
|
142
|
+
collected.
|
|
143
|
+
|
|
144
|
+
<!-- name: test_mapping_collector -->
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from mappingtools.collectors import MappingCollector, MappingCollectorMode
|
|
148
|
+
|
|
149
|
+
collector = MappingCollector(MappingCollectorMode.ALL)
|
|
150
|
+
collector.add('a', 1)
|
|
151
|
+
collector.add('a', 2)
|
|
152
|
+
collector.collect([('b', 3), ('b', 4)])
|
|
153
|
+
print(collector.mapping)
|
|
154
|
+
# Output: {'a': [1, 2], 'b': [3, 4]}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### `nested_defaultdict`
|
|
158
|
+
|
|
159
|
+
Creates a nested defaultdict with specified depth and factory.
|
|
160
|
+
|
|
161
|
+
<!-- name: test_nested_defaultdict -->
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from mappingtools.collectors import nested_defaultdict
|
|
165
|
+
|
|
166
|
+
nested_dd = nested_defaultdict(1, list)
|
|
167
|
+
nested_dd[0][1].append('value')
|
|
168
|
+
print(nested_dd)
|
|
169
|
+
# Output: defaultdict(<function nested_defaultdict.<locals>.factory at ...>, {0: defaultdict(<function nested_defaultdict.<locals>.factory at ...>, {1: ['value']})})
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Operators
|
|
173
|
+
|
|
174
|
+
Operators are functions that perform operations on Mappings.
|
|
105
175
|
|
|
106
176
|
#### `distinct`
|
|
107
177
|
|
|
@@ -110,7 +180,7 @@ Yields distinct values for a specified key across multiple mappings.
|
|
|
110
180
|
<!-- name: test_distinct -->
|
|
111
181
|
|
|
112
182
|
```python
|
|
113
|
-
from mappingtools import distinct
|
|
183
|
+
from mappingtools.operators import distinct
|
|
114
184
|
|
|
115
185
|
mappings = [
|
|
116
186
|
{'a': 1, 'b': 2},
|
|
@@ -129,7 +199,7 @@ Yields subsets of mappings by retaining only the specified keys.
|
|
|
129
199
|
<!-- name: test_keep -->
|
|
130
200
|
|
|
131
201
|
```python
|
|
132
|
-
from mappingtools import keep
|
|
202
|
+
from mappingtools.operators import keep
|
|
133
203
|
|
|
134
204
|
mappings = [
|
|
135
205
|
{'a': 1, 'b': 2, 'c': 3},
|
|
@@ -148,7 +218,7 @@ of mappings with those keys excluded.
|
|
|
148
218
|
<!-- name: test_remove -->
|
|
149
219
|
|
|
150
220
|
```python
|
|
151
|
-
from mappingtools import remove
|
|
221
|
+
from mappingtools.operators import remove
|
|
152
222
|
|
|
153
223
|
mappings = [
|
|
154
224
|
{'a': 1, 'b': 2, 'c': 3},
|
|
@@ -166,7 +236,7 @@ Swaps keys and values in a dictionary.
|
|
|
166
236
|
<!-- name: test_inverse -->
|
|
167
237
|
|
|
168
238
|
```python
|
|
169
|
-
from mappingtools import inverse
|
|
239
|
+
from mappingtools.operators import inverse
|
|
170
240
|
|
|
171
241
|
original_mapping = {'a': {1, 2}, 'b': {3}}
|
|
172
242
|
inverted_mapping = inverse(original_mapping)
|
|
@@ -182,7 +252,7 @@ keys into tuples.
|
|
|
182
252
|
<!-- name: test_flattened -->
|
|
183
253
|
|
|
184
254
|
```python
|
|
185
|
-
from mappingtools import flattened
|
|
255
|
+
from mappingtools.operators import flattened
|
|
186
256
|
|
|
187
257
|
nested_dict = {
|
|
188
258
|
'a': {'b': 1, 'c': {'d': 2}},
|
|
@@ -192,97 +262,6 @@ flat_dict = flattened(nested_dict)
|
|
|
192
262
|
# Expected output: {('a', 'b'): 1, ('a', 'c', 'd'): 2, ('e',): 3}
|
|
193
263
|
```
|
|
194
264
|
|
|
195
|
-
#### `strictify`
|
|
196
|
-
|
|
197
|
-
Strictify function applies a strict structural conversion to an object using optional converters for keys and values.
|
|
198
|
-
|
|
199
|
-
<!-- name: test_strictify -->
|
|
200
|
-
|
|
201
|
-
```python
|
|
202
|
-
from mappingtools import strictify
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
def uppercase_key(key):
|
|
206
|
-
return key.upper()
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
def double_value(value):
|
|
210
|
-
return value * 2
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
data = {'a': 1, 'b': 2}
|
|
214
|
-
result = strictify(data, key_converter=uppercase_key, value_converter=double_value)
|
|
215
|
-
print(result)
|
|
216
|
-
# Output: {'A': 2, 'B': 4}
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
#### `simplify`
|
|
220
|
-
|
|
221
|
-
Converts objects to strictly structured dictionaries.
|
|
222
|
-
|
|
223
|
-
<!-- name: test_simplify -->
|
|
224
|
-
|
|
225
|
-
```python
|
|
226
|
-
from collections import Counter
|
|
227
|
-
from dataclasses import dataclass
|
|
228
|
-
from datetime import datetime
|
|
229
|
-
from typing import Mapping
|
|
230
|
-
|
|
231
|
-
from mappingtools import simplify
|
|
232
|
-
|
|
233
|
-
data = {'key1': 'value1', 'key2': ['item1', 'item2']}
|
|
234
|
-
simplified_data = simplify(data)
|
|
235
|
-
print(simplified_data)
|
|
236
|
-
# Output: {'key1': 'value1', 'key2': ['item1', 'item2']}
|
|
237
|
-
|
|
238
|
-
counter = Counter({'a': 1, 'b': 2})
|
|
239
|
-
print(counter)
|
|
240
|
-
# Output: Counter({'b': 2, 'a': 1})
|
|
241
|
-
|
|
242
|
-
simplified_counter = simplify(counter)
|
|
243
|
-
print(simplified_counter)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
# Output: {'a': 1, 'b': 2}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
@dataclass
|
|
250
|
-
class SampleDataClass:
|
|
251
|
-
a: int
|
|
252
|
-
b: int
|
|
253
|
-
aa: str
|
|
254
|
-
bb: str
|
|
255
|
-
c: list[int]
|
|
256
|
-
d: Mapping
|
|
257
|
-
e: datetime
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
sample_datetime = datetime(2024, 7, 22, 21, 42, 17, 314159)
|
|
261
|
-
sample_dataclass = SampleDataClass(1, 2, '11', '22', [1, 2], {'aaa': 111, 'bbb': '222'}, sample_datetime)
|
|
262
|
-
|
|
263
|
-
print(sample_dataclass)
|
|
264
|
-
# Output: SampleDataClass(a=1, b=2, aa='11', bb='22', c=[1, 2], d={'aaa': 111, 'bbb': '222'}, e=datetime.datetime(2024, 7, 22, 21, 42, 17, 314159))
|
|
265
|
-
|
|
266
|
-
simplified_sample_dataclass = simplify(sample_dataclass)
|
|
267
|
-
print(simplified_sample_dataclass)
|
|
268
|
-
# Output: {'a': 1, 'aa': '11', 'b': 2, 'bb': '22', 'c': [1, 2], 'd': {'aaa': 111, 'bbb': '222'}, 'e': datetime.datetime(2024, 7, 22, 21, 42, 17, 314159)}
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
#### `listify`
|
|
272
|
-
|
|
273
|
-
Transforms complex objects into a list of dictionaries with key and value pairs.
|
|
274
|
-
|
|
275
|
-
<!-- name: test_listify -->
|
|
276
|
-
|
|
277
|
-
```python
|
|
278
|
-
from mappingtools import listify
|
|
279
|
-
|
|
280
|
-
wrapped_data = {'key1': {'subkey': 'value'}, 'key2': ['item1', 'item2']}
|
|
281
|
-
unwrapped_data = listify(wrapped_data)
|
|
282
|
-
print(unwrapped_data)
|
|
283
|
-
# Output: [{'key': 'key1', 'value': [{'key': 'subkey', 'value': 'value'}]}, {'key': 'key2', 'value': ['item1', 'item2']}]
|
|
284
|
-
```
|
|
285
|
-
|
|
286
265
|
#### `stream`
|
|
287
266
|
|
|
288
267
|
Takes a mapping and an optional item factory function, and generates items from the mapping.
|
|
@@ -293,7 +272,7 @@ If the item factory is provided, it applies the factory to each key-value pair b
|
|
|
293
272
|
```python
|
|
294
273
|
from collections import namedtuple
|
|
295
274
|
|
|
296
|
-
from mappingtools import stream
|
|
275
|
+
from mappingtools.operators import stream
|
|
297
276
|
|
|
298
277
|
|
|
299
278
|
def custom_factory(key, value):
|
|
@@ -341,7 +320,7 @@ customizable key and value names.
|
|
|
341
320
|
<!-- name: test_stream_dict_records -->
|
|
342
321
|
|
|
343
322
|
```python
|
|
344
|
-
from mappingtools import stream_dict_records
|
|
323
|
+
from mappingtools.operators import stream_dict_records
|
|
345
324
|
|
|
346
325
|
mapping = {'a': 1, 'b': 2}
|
|
347
326
|
records = stream_dict_records(mapping, key_name='letter', value_name='number')
|
|
@@ -352,62 +331,121 @@ for record in records:
|
|
|
352
331
|
# {'letter': 'b', 'number': 2}
|
|
353
332
|
```
|
|
354
333
|
|
|
355
|
-
###
|
|
334
|
+
### Transformers
|
|
356
335
|
|
|
357
|
-
|
|
336
|
+
Transformers are functions that reshape an object, while maintaining the consistency of the structure.
|
|
358
337
|
|
|
359
|
-
|
|
338
|
+
#### `listify`
|
|
360
339
|
|
|
361
|
-
|
|
340
|
+
Transforms complex objects into a list of dictionaries with key and value pairs.
|
|
341
|
+
|
|
342
|
+
<!-- name: test_listify -->
|
|
362
343
|
|
|
363
344
|
```python
|
|
364
|
-
from mappingtools import
|
|
345
|
+
from mappingtools.transformers import listify
|
|
365
346
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
print(
|
|
369
|
-
# Output:
|
|
347
|
+
wrapped_data = {'key1': {'subkey': 'value'}, 'key2': ['item1', 'item2']}
|
|
348
|
+
unwrapped_data = listify(wrapped_data)
|
|
349
|
+
print(unwrapped_data)
|
|
350
|
+
# Output: [{'key': 'key1', 'value': [{'key': 'subkey', 'value': 'value'}]}, {'key': 'key2', 'value': ['item1', 'item2']}]
|
|
370
351
|
```
|
|
371
352
|
|
|
372
|
-
#### `
|
|
353
|
+
#### `simplify`
|
|
373
354
|
|
|
374
|
-
|
|
375
|
-
It maintains a total count of all data items and allows categorization using direct values or functions.
|
|
355
|
+
Converts objects to strictly structured dictionaries.
|
|
376
356
|
|
|
377
|
-
<!-- name:
|
|
357
|
+
<!-- name: test_simplify -->
|
|
378
358
|
|
|
379
359
|
```python
|
|
380
|
-
from
|
|
381
|
-
|
|
382
|
-
|
|
360
|
+
from collections import Counter
|
|
361
|
+
from dataclasses import dataclass
|
|
362
|
+
from datetime import datetime
|
|
363
|
+
from typing import Mapping
|
|
383
364
|
|
|
384
|
-
|
|
385
|
-
counter.update({fruit: 1}, type='fruit', char_count=len(fruit), unique_char_count=len(set(fruit)))
|
|
365
|
+
from mappingtools.transformers import simplify
|
|
386
366
|
|
|
387
|
-
|
|
388
|
-
|
|
367
|
+
data = {'key1': 'value1', 'key2': ['item1', 'item2']}
|
|
368
|
+
simplified_data = simplify(data)
|
|
369
|
+
print(simplified_data)
|
|
370
|
+
# Output: {'key1': 'value1', 'key2': ['item1', 'item2']}
|
|
389
371
|
|
|
372
|
+
counter = Counter({'a': 1, 'b': 2})
|
|
390
373
|
print(counter)
|
|
391
|
-
# Output:
|
|
374
|
+
# Output: Counter({'b': 2, 'a': 1})
|
|
375
|
+
|
|
376
|
+
simplified_counter = simplify(counter)
|
|
377
|
+
print(simplified_counter)
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
# Output: {'a': 1, 'b': 2}
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
@dataclass
|
|
384
|
+
class SampleDataClass:
|
|
385
|
+
a: int
|
|
386
|
+
b: int
|
|
387
|
+
aa: str
|
|
388
|
+
bb: str
|
|
389
|
+
c: list[int]
|
|
390
|
+
d: Mapping
|
|
391
|
+
e: datetime
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
sample_datetime = datetime(2024, 7, 22, 21, 42, 17, 314159)
|
|
395
|
+
sample_dataclass = SampleDataClass(1, 2, '11', '22', [1, 2], {'aaa': 111, 'bbb': '222'}, sample_datetime)
|
|
396
|
+
|
|
397
|
+
print(sample_dataclass)
|
|
398
|
+
# Output: SampleDataClass(a=1, b=2, aa='11', bb='22', c=[1, 2], d={'aaa': 111, 'bbb': '222'}, e=datetime.datetime(2024, 7, 22, 21, 42, 17, 314159))
|
|
399
|
+
|
|
400
|
+
simplified_sample_dataclass = simplify(sample_dataclass)
|
|
401
|
+
print(simplified_sample_dataclass)
|
|
402
|
+
# Output: {'a': 1, 'aa': '11', 'b': 2, 'bb': '22', 'c': [1, 2], 'd': {'aaa': 111, 'bbb': '222'}, 'e': datetime.datetime(2024, 7, 22, 21, 42, 17, 314159)}
|
|
392
403
|
```
|
|
393
404
|
|
|
394
|
-
#### `
|
|
405
|
+
#### `strictify`
|
|
395
406
|
|
|
396
|
-
|
|
397
|
-
It supports modes like ALL, COUNT, DISTINCT, FIRST, and LAST, each dictating how key-value pairs are
|
|
398
|
-
collected.
|
|
407
|
+
Applies a strict structural conversion to an object using optional converters for keys and values.
|
|
399
408
|
|
|
400
|
-
<!-- name:
|
|
409
|
+
<!-- name: test_strictify -->
|
|
401
410
|
|
|
402
411
|
```python
|
|
403
|
-
from mappingtools import
|
|
412
|
+
from mappingtools.transformers import strictify
|
|
404
413
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
414
|
+
|
|
415
|
+
def uppercase_key(key):
|
|
416
|
+
return key.upper()
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def double_value(value):
|
|
420
|
+
return value * 2
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
data = {'a': 1, 'b': 2}
|
|
424
|
+
result = strictify(data, key_converter=uppercase_key, value_converter=double_value)
|
|
425
|
+
print(result)
|
|
426
|
+
# Output: {'A': 2, 'B': 4}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### `stringify`
|
|
430
|
+
|
|
431
|
+
Converts an object into a string representation by recursively processing it based on its type.
|
|
432
|
+
|
|
433
|
+
<!-- Name: test_stringify -->
|
|
434
|
+
|
|
435
|
+
```python
|
|
436
|
+
from mappingtools.transformers import stringify
|
|
437
|
+
|
|
438
|
+
data = {'key1': 'value1', 'key2': 'value2'}
|
|
439
|
+
result = stringify(data)
|
|
440
|
+
|
|
441
|
+
print(result)
|
|
442
|
+
# Output: "key1=value1, key2=value2"
|
|
443
|
+
|
|
444
|
+
data = [1, 2, 3]
|
|
445
|
+
result = stringify(data)
|
|
446
|
+
|
|
447
|
+
print(result)
|
|
448
|
+
# Output: "[1, 2, 3]"
|
|
411
449
|
```
|
|
412
450
|
|
|
413
451
|
## Development
|
|
@@ -416,6 +454,8 @@ print(collector.mapping)
|
|
|
416
454
|
|
|
417
455
|
```shell
|
|
418
456
|
ruff check src
|
|
457
|
+
|
|
458
|
+
ruff check tests
|
|
419
459
|
```
|
|
420
460
|
|
|
421
461
|
### Test
|
|
@@ -430,4 +470,4 @@ python -m pytest tests -n auto --cov=src --cov-branch --doctest-modules --cov-re
|
|
|
430
470
|
|
|
431
471
|
```shell
|
|
432
472
|
python -m pytest tests -n auto --cov=src --cov-branch --doctest-modules --cov-report=html
|
|
433
|
-
```
|
|
473
|
+
```
|