dotted-notation 0.47.0__tar.gz → 0.47.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.
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/CHANGELOG.md +14 -0
- {dotted_notation-0.47.0/dotted_notation.egg-info → dotted_notation-0.47.2}/PKG-INFO +48 -1
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/README.md +47 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/grammar.py +4 -1
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/transforms.py +18 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2/dotted_notation.egg-info}/PKG-INFO +48 -1
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/pyproject.toml +1 -1
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/LICENSE +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/MANIFEST.in +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/__init__.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/__main__.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/access.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/access.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/api.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/base.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/base.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/cli/__init__.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/cli/_compat.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/cli/formats.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/cli/main.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/containers.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/engine.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/engine.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/filters.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/filters.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/groups.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/groups.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/matchers.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/matchers.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/native.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/predicates.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/recursive.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/recursive.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/results.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/sql/__init__.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/sql/core.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/sql/pg.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/utils.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/utypes.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/wrappers.pxd +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted/wrappers.py +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted_notation.egg-info/SOURCES.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted_notation.egg-info/dependency_links.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted_notation.egg-info/entry_points.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted_notation.egg-info/requires.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/dotted_notation.egg-info/top_level.txt +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/setup.cfg +0 -0
- {dotted_notation-0.47.0 → dotted_notation-0.47.2}/setup.py +0 -0
|
@@ -3,6 +3,20 @@
|
|
|
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.2]
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- `$str`, a `$` before a word, is a plain string wherever a key, guard
|
|
10
|
+
value or transform argument may stand, as `^str` already was. It was a
|
|
11
|
+
`ParseError`. `$0`, `$(name)` and `$$(path)` are unchanged.
|
|
12
|
+
|
|
13
|
+
## [0.47.1]
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- The `coalesce` transform: `n|coalesce:0` is `n`, or 0 when `n` is
|
|
17
|
+
`None`. Several fallbacks take the first that is not `None`, so a
|
|
18
|
+
reference may stand in first: `n|coalesce:$$(defaults.n):0`.
|
|
19
|
+
|
|
6
20
|
## [0.47.0]
|
|
7
21
|
|
|
8
22
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotted_notation
|
|
3
|
-
Version: 0.47.
|
|
3
|
+
Version: 0.47.2
|
|
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
|
|
@@ -1629,6 +1655,13 @@ Quoting also works — a quoted string is always literal:
|
|
|
1629
1655
|
To use a literal `$$` as a key, escape with backslash (`\$$`) or quote it
|
|
1630
1656
|
(`'$$(…)'`).
|
|
1631
1657
|
|
|
1658
|
+
A `$` before a word is not a substitution at all: `$str` is the plain string
|
|
1659
|
+
`$str`, in a segment, a guard value or a transform argument alike, just as
|
|
1660
|
+
`^str` is. Only `$0`, `$(name)` and `$$(path)` have meaning:
|
|
1661
|
+
|
|
1662
|
+
>>> dotted.get({'$amount': {'value': 2}}, '$amount.value')
|
|
1663
|
+
2
|
|
1664
|
+
|
|
1632
1665
|
<a id="type-restrictions"></a>
|
|
1633
1666
|
## Type Restrictions
|
|
1634
1667
|
|
|
@@ -2958,6 +2991,7 @@ decorator.
|
|
|
2958
2991
|
| `float` | `raises` | Convert to float |
|
|
2959
2992
|
| `decimal` | `raises` | Convert to `Decimal` |
|
|
2960
2993
|
| `none` | values... | Return `None` if falsy or matches values: `\|none::null:empty` |
|
|
2994
|
+
| `coalesce` | fallbacks... | The first of the value and the fallbacks that is not `None`: `\|coalesce:0` |
|
|
2961
2995
|
| `strip` | `chars`, `raises` | Strip whitespace or specified chars |
|
|
2962
2996
|
| `len` | `default` | Get length. Optional default if not sized: `\|len:0` |
|
|
2963
2997
|
| `lowercase` | `raises` | Convert string to lowercase |
|
|
@@ -3012,6 +3046,19 @@ Comparison and membership transforms return `True`/`False`:
|
|
|
3012
3046
|
>>> dotted.get({'n': 2}, 'n|in:[1, 2, 3]')
|
|
3013
3047
|
True
|
|
3014
3048
|
|
|
3049
|
+
`coalesce` stands in a fallback for `None`, as SQL's does; with several
|
|
3050
|
+
fallbacks the first that is not `None` wins, which matters when a fallback is
|
|
3051
|
+
a [reference](#references-in-transforms-and-guards) that may itself be `None`:
|
|
3052
|
+
|
|
3053
|
+
>>> d = {'n': None, 'defaults': {'n': 7}}
|
|
3054
|
+
>>> dotted.get(d, 'n|coalesce:0')
|
|
3055
|
+
0
|
|
3056
|
+
>>> dotted.get(d, 'n|coalesce:$$(defaults.n):0')
|
|
3057
|
+
7
|
|
3058
|
+
|
|
3059
|
+
A transform only runs on a value the path yields, so `coalesce` does not fill
|
|
3060
|
+
a missing key; `get(..., default=)` does that.
|
|
3061
|
+
|
|
3015
3062
|
<a id="container-transform-arguments"></a>
|
|
3016
3063
|
### Container transform arguments
|
|
3017
3064
|
|
|
@@ -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
|
|
@@ -1582,6 +1608,13 @@ Quoting also works — a quoted string is always literal:
|
|
|
1582
1608
|
To use a literal `$$` as a key, escape with backslash (`\$$`) or quote it
|
|
1583
1609
|
(`'$$(…)'`).
|
|
1584
1610
|
|
|
1611
|
+
A `$` before a word is not a substitution at all: `$str` is the plain string
|
|
1612
|
+
`$str`, in a segment, a guard value or a transform argument alike, just as
|
|
1613
|
+
`^str` is. Only `$0`, `$(name)` and `$$(path)` have meaning:
|
|
1614
|
+
|
|
1615
|
+
>>> dotted.get({'$amount': {'value': 2}}, '$amount.value')
|
|
1616
|
+
2
|
|
1617
|
+
|
|
1585
1618
|
<a id="type-restrictions"></a>
|
|
1586
1619
|
## Type Restrictions
|
|
1587
1620
|
|
|
@@ -2911,6 +2944,7 @@ decorator.
|
|
|
2911
2944
|
| `float` | `raises` | Convert to float |
|
|
2912
2945
|
| `decimal` | `raises` | Convert to `Decimal` |
|
|
2913
2946
|
| `none` | values... | Return `None` if falsy or matches values: `\|none::null:empty` |
|
|
2947
|
+
| `coalesce` | fallbacks... | The first of the value and the fallbacks that is not `None`: `\|coalesce:0` |
|
|
2914
2948
|
| `strip` | `chars`, `raises` | Strip whitespace or specified chars |
|
|
2915
2949
|
| `len` | `default` | Get length. Optional default if not sized: `\|len:0` |
|
|
2916
2950
|
| `lowercase` | `raises` | Convert string to lowercase |
|
|
@@ -2965,6 +2999,19 @@ Comparison and membership transforms return `True`/`False`:
|
|
|
2965
2999
|
>>> dotted.get({'n': 2}, 'n|in:[1, 2, 3]')
|
|
2966
3000
|
True
|
|
2967
3001
|
|
|
3002
|
+
`coalesce` stands in a fallback for `None`, as SQL's does; with several
|
|
3003
|
+
fallbacks the first that is not `None` wins, which matters when a fallback is
|
|
3004
|
+
a [reference](#references-in-transforms-and-guards) that may itself be `None`:
|
|
3005
|
+
|
|
3006
|
+
>>> d = {'n': None, 'defaults': {'n': 7}}
|
|
3007
|
+
>>> dotted.get(d, 'n|coalesce:0')
|
|
3008
|
+
0
|
|
3009
|
+
>>> dotted.get(d, 'n|coalesce:$$(defaults.n):0')
|
|
3010
|
+
7
|
|
3011
|
+
|
|
3012
|
+
A transform only runs on a value the path yields, so `coalesce` does not fill
|
|
3013
|
+
a missing key; `get(..., default=)` does that.
|
|
3014
|
+
|
|
2968
3015
|
<a id="container-transform-arguments"></a>
|
|
2969
3016
|
### Container transform arguments
|
|
2970
3017
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
"""
|
|
3
3
|
import decimal
|
|
4
|
+
import re
|
|
4
5
|
import pyparsing as pp
|
|
5
6
|
from pyparsing import pyparsing_common as ppc
|
|
6
7
|
|
|
@@ -275,7 +276,9 @@ def _paren_subst_action(t):
|
|
|
275
276
|
_paren_subst = pp.Regex(r'\$\([^)]+\)').set_parse_action(_paren_subst_action)
|
|
276
277
|
_raw_subst = pp.Regex(r'\$[0-9]+').set_parse_action(
|
|
277
278
|
lambda t: matchers.Subst(int(t[0][1:])))
|
|
278
|
-
|
|
279
|
+
# $str, a $ before a word: a plain string, as ^str is. Not $0, $(name) or $$(path).
|
|
280
|
+
_dollar_word = pp.Regex(r'\$(?![0-9($])[^' + re.escape(reserved) + r' \t\n\r]+').set_parse_action(matchers.Word)
|
|
281
|
+
var = _escaped_dollar | _reference | _paren_subst | _raw_subst | _dollar_word
|
|
279
282
|
slice = pp.Optional(integer | plus) + ':' + pp.Optional(integer | plus) \
|
|
280
283
|
+ pp.Optional(':') + pp.Optional(integer | plus)
|
|
281
284
|
|
|
@@ -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.2
|
|
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
|
|
@@ -1629,6 +1655,13 @@ Quoting also works — a quoted string is always literal:
|
|
|
1629
1655
|
To use a literal `$$` as a key, escape with backslash (`\$$`) or quote it
|
|
1630
1656
|
(`'$$(…)'`).
|
|
1631
1657
|
|
|
1658
|
+
A `$` before a word is not a substitution at all: `$str` is the plain string
|
|
1659
|
+
`$str`, in a segment, a guard value or a transform argument alike, just as
|
|
1660
|
+
`^str` is. Only `$0`, `$(name)` and `$$(path)` have meaning:
|
|
1661
|
+
|
|
1662
|
+
>>> dotted.get({'$amount': {'value': 2}}, '$amount.value')
|
|
1663
|
+
2
|
|
1664
|
+
|
|
1632
1665
|
<a id="type-restrictions"></a>
|
|
1633
1666
|
## Type Restrictions
|
|
1634
1667
|
|
|
@@ -2958,6 +2991,7 @@ decorator.
|
|
|
2958
2991
|
| `float` | `raises` | Convert to float |
|
|
2959
2992
|
| `decimal` | `raises` | Convert to `Decimal` |
|
|
2960
2993
|
| `none` | values... | Return `None` if falsy or matches values: `\|none::null:empty` |
|
|
2994
|
+
| `coalesce` | fallbacks... | The first of the value and the fallbacks that is not `None`: `\|coalesce:0` |
|
|
2961
2995
|
| `strip` | `chars`, `raises` | Strip whitespace or specified chars |
|
|
2962
2996
|
| `len` | `default` | Get length. Optional default if not sized: `\|len:0` |
|
|
2963
2997
|
| `lowercase` | `raises` | Convert string to lowercase |
|
|
@@ -3012,6 +3046,19 @@ Comparison and membership transforms return `True`/`False`:
|
|
|
3012
3046
|
>>> dotted.get({'n': 2}, 'n|in:[1, 2, 3]')
|
|
3013
3047
|
True
|
|
3014
3048
|
|
|
3049
|
+
`coalesce` stands in a fallback for `None`, as SQL's does; with several
|
|
3050
|
+
fallbacks the first that is not `None` wins, which matters when a fallback is
|
|
3051
|
+
a [reference](#references-in-transforms-and-guards) that may itself be `None`:
|
|
3052
|
+
|
|
3053
|
+
>>> d = {'n': None, 'defaults': {'n': 7}}
|
|
3054
|
+
>>> dotted.get(d, 'n|coalesce:0')
|
|
3055
|
+
0
|
|
3056
|
+
>>> dotted.get(d, 'n|coalesce:$$(defaults.n):0')
|
|
3057
|
+
7
|
|
3058
|
+
|
|
3059
|
+
A transform only runs on a value the path yields, so `coalesce` does not fill
|
|
3060
|
+
a missing key; `get(..., default=)` does that.
|
|
3061
|
+
|
|
3015
3062
|
<a id="container-transform-arguments"></a>
|
|
3016
3063
|
### Container transform arguments
|
|
3017
3064
|
|
|
@@ -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.2"
|
|
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
|
{dotted_notation-0.47.0 → dotted_notation-0.47.2}/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
|