dotted-notation 0.47.0__tar.gz → 0.47.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.
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/CHANGELOG.md +7 -0
- {dotted_notation-0.47.0/dotted_notation.egg-info → dotted_notation-0.47.1}/PKG-INFO +41 -1
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/README.md +40 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/transforms.py +18 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1/dotted_notation.egg-info}/PKG-INFO +41 -1
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/pyproject.toml +1 -1
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/LICENSE +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/MANIFEST.in +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/__init__.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/__main__.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/access.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/access.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/api.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/base.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/base.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/cli/__init__.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/cli/_compat.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/cli/formats.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/cli/main.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/containers.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/engine.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/engine.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/filters.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/filters.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/grammar.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/groups.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/groups.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/matchers.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/matchers.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/native.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/predicates.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/recursive.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/recursive.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/results.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/sql/__init__.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/sql/core.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/sql/pg.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/utils.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/utypes.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/wrappers.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted/wrappers.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted_notation.egg-info/SOURCES.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted_notation.egg-info/dependency_links.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted_notation.egg-info/entry_points.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted_notation.egg-info/requires.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted_notation.egg-info/top_level.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/setup.cfg +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.1}/setup.py +0 -0
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
All notable changes to `dotted` are recorded here. Versions prior to
|
|
4
4
|
the ones listed are omitted — browse git history for earlier entries.
|
|
5
5
|
|
|
6
|
+
## [0.47.1]
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- The `coalesce` transform: `n|coalesce:0` is `n`, or 0 when `n` is
|
|
10
|
+
`None`. Several fallbacks take the first that is not `None`, so a
|
|
11
|
+
reference may stand in first: `n|coalesce:$$(defaults.n):0`.
|
|
12
|
+
|
|
6
13
|
## [0.47.0]
|
|
7
14
|
|
|
8
15
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotted_notation
|
|
3
|
-
Version: 0.47.
|
|
3
|
+
Version: 0.47.1
|
|
4
4
|
Summary: Dotted notation for safe nested data traversal with optional chaining, pattern matching, and transforms
|
|
5
5
|
Author-email: Frey Waid <logophage1@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -273,6 +273,32 @@ Several Python libraries handle nested data access. Here's how dotted compares:
|
|
|
273
273
|
<a id="breaking-changes"></a>
|
|
274
274
|
## Breaking Changes
|
|
275
275
|
|
|
276
|
+
### v0.47.0
|
|
277
|
+
- **`!` binds tighter than guards, filters and transforms.** `!a=5` is now
|
|
278
|
+
`(!a)=5`, the values other than `a`'s that equal 5; the old meaning,
|
|
279
|
+
everything but an `a` equal to 5, is written `!(a=5)`. Likewise `!a&k=v`
|
|
280
|
+
filters what `!a` yields and `!a|int` transforms it. See
|
|
281
|
+
[Precedence](#precedence).
|
|
282
|
+
- **A guard, filter or transform after a group distributes to every branch.**
|
|
283
|
+
`(a,b)=5` is `(a=5,b=5)`, `(first&last)>5` is `(first>5&last>5)`,
|
|
284
|
+
`(a,b)|int` is `(a|int,b|int)`, and `assemble` writes the distributed form.
|
|
285
|
+
These used to fail to parse.
|
|
286
|
+
- **`a,b|int` transforms only `b`.** A transform binds to the expression on
|
|
287
|
+
its left before `,` and `&`; `(a,b)|int` transforms both.
|
|
288
|
+
- **`:type` tests the value a path yields, not the node it is applied to.**
|
|
289
|
+
`x:int` on `{'x': 3}` is `3`; it was `None`. Restrict a container one
|
|
290
|
+
segment earlier: `a.b:dict` → `a:dict.b`, and
|
|
291
|
+
`*[*]:!(str, bytes)` → `*:!(str, bytes)[*]`. `**:!(str, bytes)` and
|
|
292
|
+
`*(*, [*]):!(str, bytes)` now drop string values themselves, not only
|
|
293
|
+
their decomposition.
|
|
294
|
+
- **`!a.b` continues into `b`.** It yielded the complement of `a` and
|
|
295
|
+
ignored `.b`; it now yields `.b` of every key other than `a`, as
|
|
296
|
+
`match` always read it.
|
|
297
|
+
- **Ops own their transforms.** `Dotted.transforms` is read-only and
|
|
298
|
+
reflects the trailing op; `parse('a.b|int')` reprs as
|
|
299
|
+
`Dotted([a, b|int])`. A guard's or filter's match-only transforms,
|
|
300
|
+
`a|int=5`, are `guard_transforms`, not `transforms`.
|
|
301
|
+
|
|
276
302
|
### v0.44.0
|
|
277
303
|
- **Parameter renamed from `key` to `path`** across the public API to align with
|
|
278
304
|
the terminology used throughout the docs (a _path_ is the whole dotted
|
|
@@ -2958,6 +2984,7 @@ decorator.
|
|
|
2958
2984
|
| `float` | `raises` | Convert to float |
|
|
2959
2985
|
| `decimal` | `raises` | Convert to `Decimal` |
|
|
2960
2986
|
| `none` | values... | Return `None` if falsy or matches values: `\|none::null:empty` |
|
|
2987
|
+
| `coalesce` | fallbacks... | The first of the value and the fallbacks that is not `None`: `\|coalesce:0` |
|
|
2961
2988
|
| `strip` | `chars`, `raises` | Strip whitespace or specified chars |
|
|
2962
2989
|
| `len` | `default` | Get length. Optional default if not sized: `\|len:0` |
|
|
2963
2990
|
| `lowercase` | `raises` | Convert string to lowercase |
|
|
@@ -3012,6 +3039,19 @@ Comparison and membership transforms return `True`/`False`:
|
|
|
3012
3039
|
>>> dotted.get({'n': 2}, 'n|in:[1, 2, 3]')
|
|
3013
3040
|
True
|
|
3014
3041
|
|
|
3042
|
+
`coalesce` stands in a fallback for `None`, as SQL's does; with several
|
|
3043
|
+
fallbacks the first that is not `None` wins, which matters when a fallback is
|
|
3044
|
+
a [reference](#references-in-transforms-and-guards) that may itself be `None`:
|
|
3045
|
+
|
|
3046
|
+
>>> d = {'n': None, 'defaults': {'n': 7}}
|
|
3047
|
+
>>> dotted.get(d, 'n|coalesce:0')
|
|
3048
|
+
0
|
|
3049
|
+
>>> dotted.get(d, 'n|coalesce:$$(defaults.n):0')
|
|
3050
|
+
7
|
|
3051
|
+
|
|
3052
|
+
A transform only runs on a value the path yields, so `coalesce` does not fill
|
|
3053
|
+
a missing key; `get(..., default=)` does that.
|
|
3054
|
+
|
|
3015
3055
|
<a id="container-transform-arguments"></a>
|
|
3016
3056
|
### Container transform arguments
|
|
3017
3057
|
|
|
@@ -226,6 +226,32 @@ Several Python libraries handle nested data access. Here's how dotted compares:
|
|
|
226
226
|
<a id="breaking-changes"></a>
|
|
227
227
|
## Breaking Changes
|
|
228
228
|
|
|
229
|
+
### v0.47.0
|
|
230
|
+
- **`!` binds tighter than guards, filters and transforms.** `!a=5` is now
|
|
231
|
+
`(!a)=5`, the values other than `a`'s that equal 5; the old meaning,
|
|
232
|
+
everything but an `a` equal to 5, is written `!(a=5)`. Likewise `!a&k=v`
|
|
233
|
+
filters what `!a` yields and `!a|int` transforms it. See
|
|
234
|
+
[Precedence](#precedence).
|
|
235
|
+
- **A guard, filter or transform after a group distributes to every branch.**
|
|
236
|
+
`(a,b)=5` is `(a=5,b=5)`, `(first&last)>5` is `(first>5&last>5)`,
|
|
237
|
+
`(a,b)|int` is `(a|int,b|int)`, and `assemble` writes the distributed form.
|
|
238
|
+
These used to fail to parse.
|
|
239
|
+
- **`a,b|int` transforms only `b`.** A transform binds to the expression on
|
|
240
|
+
its left before `,` and `&`; `(a,b)|int` transforms both.
|
|
241
|
+
- **`:type` tests the value a path yields, not the node it is applied to.**
|
|
242
|
+
`x:int` on `{'x': 3}` is `3`; it was `None`. Restrict a container one
|
|
243
|
+
segment earlier: `a.b:dict` → `a:dict.b`, and
|
|
244
|
+
`*[*]:!(str, bytes)` → `*:!(str, bytes)[*]`. `**:!(str, bytes)` and
|
|
245
|
+
`*(*, [*]):!(str, bytes)` now drop string values themselves, not only
|
|
246
|
+
their decomposition.
|
|
247
|
+
- **`!a.b` continues into `b`.** It yielded the complement of `a` and
|
|
248
|
+
ignored `.b`; it now yields `.b` of every key other than `a`, as
|
|
249
|
+
`match` always read it.
|
|
250
|
+
- **Ops own their transforms.** `Dotted.transforms` is read-only and
|
|
251
|
+
reflects the trailing op; `parse('a.b|int')` reprs as
|
|
252
|
+
`Dotted([a, b|int])`. A guard's or filter's match-only transforms,
|
|
253
|
+
`a|int=5`, are `guard_transforms`, not `transforms`.
|
|
254
|
+
|
|
229
255
|
### v0.44.0
|
|
230
256
|
- **Parameter renamed from `key` to `path`** across the public API to align with
|
|
231
257
|
the terminology used throughout the docs (a _path_ is the whole dotted
|
|
@@ -2911,6 +2937,7 @@ decorator.
|
|
|
2911
2937
|
| `float` | `raises` | Convert to float |
|
|
2912
2938
|
| `decimal` | `raises` | Convert to `Decimal` |
|
|
2913
2939
|
| `none` | values... | Return `None` if falsy or matches values: `\|none::null:empty` |
|
|
2940
|
+
| `coalesce` | fallbacks... | The first of the value and the fallbacks that is not `None`: `\|coalesce:0` |
|
|
2914
2941
|
| `strip` | `chars`, `raises` | Strip whitespace or specified chars |
|
|
2915
2942
|
| `len` | `default` | Get length. Optional default if not sized: `\|len:0` |
|
|
2916
2943
|
| `lowercase` | `raises` | Convert string to lowercase |
|
|
@@ -2965,6 +2992,19 @@ Comparison and membership transforms return `True`/`False`:
|
|
|
2965
2992
|
>>> dotted.get({'n': 2}, 'n|in:[1, 2, 3]')
|
|
2966
2993
|
True
|
|
2967
2994
|
|
|
2995
|
+
`coalesce` stands in a fallback for `None`, as SQL's does; with several
|
|
2996
|
+
fallbacks the first that is not `None` wins, which matters when a fallback is
|
|
2997
|
+
a [reference](#references-in-transforms-and-guards) that may itself be `None`:
|
|
2998
|
+
|
|
2999
|
+
>>> d = {'n': None, 'defaults': {'n': 7}}
|
|
3000
|
+
>>> dotted.get(d, 'n|coalesce:0')
|
|
3001
|
+
0
|
|
3002
|
+
>>> dotted.get(d, 'n|coalesce:$$(defaults.n):0')
|
|
3003
|
+
7
|
|
3004
|
+
|
|
3005
|
+
A transform only runs on a value the path yields, so `coalesce` does not fill
|
|
3006
|
+
a missing key; `get(..., default=)` does that.
|
|
3007
|
+
|
|
2968
3008
|
<a id="container-transform-arguments"></a>
|
|
2969
3009
|
### Container transform arguments
|
|
2970
3010
|
|
|
@@ -104,6 +104,24 @@ def transform_none(val, *none_vals):
|
|
|
104
104
|
return None if val in none_vals else val
|
|
105
105
|
|
|
106
106
|
|
|
107
|
+
@transform('coalesce')
|
|
108
|
+
def transform_coalesce(val, *fallbacks):
|
|
109
|
+
"""
|
|
110
|
+
The first of val and the fallbacks that is not None
|
|
111
|
+
<dotted>|coalesce:<fallback> fallback if val is None else val
|
|
112
|
+
<dotted>|coalesce:<f1>:<f2> the first of val, f1, f2 not None
|
|
113
|
+
>>> import dotted
|
|
114
|
+
>>> dotted.get({'n': None}, 'n|coalesce:0')
|
|
115
|
+
0
|
|
116
|
+
>>> dotted.get({'n': 5}, 'n|coalesce:0')
|
|
117
|
+
5
|
|
118
|
+
"""
|
|
119
|
+
for v in (val, *fallbacks):
|
|
120
|
+
if v is not None:
|
|
121
|
+
return v
|
|
122
|
+
return None
|
|
123
|
+
|
|
124
|
+
|
|
107
125
|
@transform('strip')
|
|
108
126
|
def transform_strip(val, chars=None, *modes):
|
|
109
127
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotted_notation
|
|
3
|
-
Version: 0.47.
|
|
3
|
+
Version: 0.47.1
|
|
4
4
|
Summary: Dotted notation for safe nested data traversal with optional chaining, pattern matching, and transforms
|
|
5
5
|
Author-email: Frey Waid <logophage1@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -273,6 +273,32 @@ Several Python libraries handle nested data access. Here's how dotted compares:
|
|
|
273
273
|
<a id="breaking-changes"></a>
|
|
274
274
|
## Breaking Changes
|
|
275
275
|
|
|
276
|
+
### v0.47.0
|
|
277
|
+
- **`!` binds tighter than guards, filters and transforms.** `!a=5` is now
|
|
278
|
+
`(!a)=5`, the values other than `a`'s that equal 5; the old meaning,
|
|
279
|
+
everything but an `a` equal to 5, is written `!(a=5)`. Likewise `!a&k=v`
|
|
280
|
+
filters what `!a` yields and `!a|int` transforms it. See
|
|
281
|
+
[Precedence](#precedence).
|
|
282
|
+
- **A guard, filter or transform after a group distributes to every branch.**
|
|
283
|
+
`(a,b)=5` is `(a=5,b=5)`, `(first&last)>5` is `(first>5&last>5)`,
|
|
284
|
+
`(a,b)|int` is `(a|int,b|int)`, and `assemble` writes the distributed form.
|
|
285
|
+
These used to fail to parse.
|
|
286
|
+
- **`a,b|int` transforms only `b`.** A transform binds to the expression on
|
|
287
|
+
its left before `,` and `&`; `(a,b)|int` transforms both.
|
|
288
|
+
- **`:type` tests the value a path yields, not the node it is applied to.**
|
|
289
|
+
`x:int` on `{'x': 3}` is `3`; it was `None`. Restrict a container one
|
|
290
|
+
segment earlier: `a.b:dict` → `a:dict.b`, and
|
|
291
|
+
`*[*]:!(str, bytes)` → `*:!(str, bytes)[*]`. `**:!(str, bytes)` and
|
|
292
|
+
`*(*, [*]):!(str, bytes)` now drop string values themselves, not only
|
|
293
|
+
their decomposition.
|
|
294
|
+
- **`!a.b` continues into `b`.** It yielded the complement of `a` and
|
|
295
|
+
ignored `.b`; it now yields `.b` of every key other than `a`, as
|
|
296
|
+
`match` always read it.
|
|
297
|
+
- **Ops own their transforms.** `Dotted.transforms` is read-only and
|
|
298
|
+
reflects the trailing op; `parse('a.b|int')` reprs as
|
|
299
|
+
`Dotted([a, b|int])`. A guard's or filter's match-only transforms,
|
|
300
|
+
`a|int=5`, are `guard_transforms`, not `transforms`.
|
|
301
|
+
|
|
276
302
|
### v0.44.0
|
|
277
303
|
- **Parameter renamed from `key` to `path`** across the public API to align with
|
|
278
304
|
the terminology used throughout the docs (a _path_ is the whole dotted
|
|
@@ -2958,6 +2984,7 @@ decorator.
|
|
|
2958
2984
|
| `float` | `raises` | Convert to float |
|
|
2959
2985
|
| `decimal` | `raises` | Convert to `Decimal` |
|
|
2960
2986
|
| `none` | values... | Return `None` if falsy or matches values: `\|none::null:empty` |
|
|
2987
|
+
| `coalesce` | fallbacks... | The first of the value and the fallbacks that is not `None`: `\|coalesce:0` |
|
|
2961
2988
|
| `strip` | `chars`, `raises` | Strip whitespace or specified chars |
|
|
2962
2989
|
| `len` | `default` | Get length. Optional default if not sized: `\|len:0` |
|
|
2963
2990
|
| `lowercase` | `raises` | Convert string to lowercase |
|
|
@@ -3012,6 +3039,19 @@ Comparison and membership transforms return `True`/`False`:
|
|
|
3012
3039
|
>>> dotted.get({'n': 2}, 'n|in:[1, 2, 3]')
|
|
3013
3040
|
True
|
|
3014
3041
|
|
|
3042
|
+
`coalesce` stands in a fallback for `None`, as SQL's does; with several
|
|
3043
|
+
fallbacks the first that is not `None` wins, which matters when a fallback is
|
|
3044
|
+
a [reference](#references-in-transforms-and-guards) that may itself be `None`:
|
|
3045
|
+
|
|
3046
|
+
>>> d = {'n': None, 'defaults': {'n': 7}}
|
|
3047
|
+
>>> dotted.get(d, 'n|coalesce:0')
|
|
3048
|
+
0
|
|
3049
|
+
>>> dotted.get(d, 'n|coalesce:$$(defaults.n):0')
|
|
3050
|
+
7
|
|
3051
|
+
|
|
3052
|
+
A transform only runs on a value the path yields, so `coalesce` does not fill
|
|
3053
|
+
a missing key; `get(..., default=)` does that.
|
|
3054
|
+
|
|
3015
3055
|
<a id="container-transform-arguments"></a>
|
|
3016
3056
|
### Container transform arguments
|
|
3017
3057
|
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "dotted_notation"
|
|
9
|
-
version = "0.47.
|
|
9
|
+
version = "0.47.1"
|
|
10
10
|
description = "Dotted notation for safe nested data traversal with optional chaining, pattern matching, and transforms"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
requires-python = ">=3.6"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dotted_notation-0.47.0 → dotted_notation-0.47.1}/dotted_notation.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|