dotted-notation 0.44.0__tar.gz → 0.44.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.44.0 → dotted_notation-0.44.2}/CHANGELOG.md +18 -0
- {dotted_notation-0.44.0/dotted_notation.egg-info → dotted_notation-0.44.2}/PKG-INFO +31 -1
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/README.md +30 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/api.py +47 -11
- {dotted_notation-0.44.0 → dotted_notation-0.44.2/dotted_notation.egg-info}/PKG-INFO +31 -1
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/pyproject.toml +1 -1
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/LICENSE +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/MANIFEST.in +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/__init__.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/__main__.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/access.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/base.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/cli/__init__.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/cli/_compat.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/cli/formats.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/cli/main.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/containers.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/engine.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/filters.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/grammar.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/groups.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/matchers.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/predicates.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/recursive.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/results.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/sql/__init__.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/sql/core.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/sql/pg.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/transforms.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/utils.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/utypes.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted/wrappers.py +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted_notation.egg-info/SOURCES.txt +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted_notation.egg-info/dependency_links.txt +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted_notation.egg-info/entry_points.txt +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted_notation.egg-info/requires.txt +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted_notation.egg-info/top_level.txt +0 -0
- {dotted_notation-0.44.0 → dotted_notation-0.44.2}/setup.cfg +0 -0
|
@@ -3,6 +3,24 @@
|
|
|
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.44.2]
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- `unpack(obj, project=...)` keeps only the leaf paths selected by one or
|
|
10
|
+
more dotted patterns. Selection is directional (a leaf survives if it
|
|
11
|
+
`match`es a pattern), so projecting `a.b` never pulls in a shallower scalar
|
|
12
|
+
`a`. Matching defaults to `partial=True` (trailing segment is greedy); pass
|
|
13
|
+
`partial=False` for exact-depth matching, or override per field with a
|
|
14
|
+
`(pattern, partial)` tuple. `project=`/`partial=` also flow through `keys`,
|
|
15
|
+
`values`, and `items`.
|
|
16
|
+
|
|
17
|
+
## [0.44.1]
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- GitHub Actions: `tests.yml` runs pytest on push/PR; `publish.yml`
|
|
21
|
+
uses PyPI Trusted Publishing (OIDC) on GitHub Release, gated on
|
|
22
|
+
tests passing. Releases now show "Verified details" on PyPI.
|
|
23
|
+
|
|
6
24
|
## [0.44.0]
|
|
7
25
|
|
|
8
26
|
### Changed (breaking)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotted_notation
|
|
3
|
-
Version: 0.44.
|
|
3
|
+
Version: 0.44.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: MIT
|
|
@@ -729,6 +729,36 @@ For example:
|
|
|
729
729
|
|
|
730
730
|
Pass both to include all attributes: `attrs=[Attrs.standard, Attrs.special]`.
|
|
731
731
|
|
|
732
|
+
Pass `project=` to keep only the leaf paths selected by one or more dotted
|
|
733
|
+
patterns. Selection is *directional* — a leaf survives if it `match`es a
|
|
734
|
+
projection pattern — so projecting `a.b` never drags in a shallower scalar leaf
|
|
735
|
+
`a`:
|
|
736
|
+
|
|
737
|
+
>>> o = {'a': {'b': 1, 'c': 2}, 'x': {'y': {'z': 3}}, 'extra': 9}
|
|
738
|
+
>>> dotted.unpack(o, project='a')
|
|
739
|
+
{'a.b': 1, 'a.c': 2}
|
|
740
|
+
>>> dotted.unpack(o, project=['a', 'x.y.z'])
|
|
741
|
+
{'a.b': 1, 'a.c': 2, 'x.y.z': 3}
|
|
742
|
+
|
|
743
|
+
Matching uses `match`'s `partial=True` by default, so a trailing segment is
|
|
744
|
+
greedy (`a.*` also keeps `a.b.c`). Set `partial=False` for exact-depth matching,
|
|
745
|
+
where `a.*`, `a.*.*`, and `a.**` are all distinct:
|
|
746
|
+
|
|
747
|
+
>>> deep = {'a': {'b': {'c': 1}}, 'd': 9}
|
|
748
|
+
>>> dotted.unpack(deep, project='a.*', partial=False)
|
|
749
|
+
{}
|
|
750
|
+
>>> dotted.unpack(deep, project='a.**', partial=False)
|
|
751
|
+
{'a.b.c': 1}
|
|
752
|
+
|
|
753
|
+
Override `partial` per field with a `(pattern, partial)` tuple — bare patterns
|
|
754
|
+
inherit the global setting. This matters for mid-pattern matches that `**`
|
|
755
|
+
cannot express (e.g. `a.*.c` keeping both `a.x.c` and `a.x.c.d`):
|
|
756
|
+
|
|
757
|
+
>>> dotted.unpack(deep, project=[('a.*', True), 'd'], partial=False)
|
|
758
|
+
{'a.b.c': 1, 'd': 9}
|
|
759
|
+
|
|
760
|
+
`project=` and `partial=` also flow through `keys()`, `values()`, and `items()`.
|
|
761
|
+
|
|
732
762
|
<a id="pack"></a>
|
|
733
763
|
### Pack
|
|
734
764
|
|
|
@@ -689,6 +689,36 @@ For example:
|
|
|
689
689
|
|
|
690
690
|
Pass both to include all attributes: `attrs=[Attrs.standard, Attrs.special]`.
|
|
691
691
|
|
|
692
|
+
Pass `project=` to keep only the leaf paths selected by one or more dotted
|
|
693
|
+
patterns. Selection is *directional* — a leaf survives if it `match`es a
|
|
694
|
+
projection pattern — so projecting `a.b` never drags in a shallower scalar leaf
|
|
695
|
+
`a`:
|
|
696
|
+
|
|
697
|
+
>>> o = {'a': {'b': 1, 'c': 2}, 'x': {'y': {'z': 3}}, 'extra': 9}
|
|
698
|
+
>>> dotted.unpack(o, project='a')
|
|
699
|
+
{'a.b': 1, 'a.c': 2}
|
|
700
|
+
>>> dotted.unpack(o, project=['a', 'x.y.z'])
|
|
701
|
+
{'a.b': 1, 'a.c': 2, 'x.y.z': 3}
|
|
702
|
+
|
|
703
|
+
Matching uses `match`'s `partial=True` by default, so a trailing segment is
|
|
704
|
+
greedy (`a.*` also keeps `a.b.c`). Set `partial=False` for exact-depth matching,
|
|
705
|
+
where `a.*`, `a.*.*`, and `a.**` are all distinct:
|
|
706
|
+
|
|
707
|
+
>>> deep = {'a': {'b': {'c': 1}}, 'd': 9}
|
|
708
|
+
>>> dotted.unpack(deep, project='a.*', partial=False)
|
|
709
|
+
{}
|
|
710
|
+
>>> dotted.unpack(deep, project='a.**', partial=False)
|
|
711
|
+
{'a.b.c': 1}
|
|
712
|
+
|
|
713
|
+
Override `partial` per field with a `(pattern, partial)` tuple — bare patterns
|
|
714
|
+
inherit the global setting. This matters for mid-pattern matches that `**`
|
|
715
|
+
cannot express (e.g. `a.*.c` keeping both `a.x.c` and `a.x.c.d`):
|
|
716
|
+
|
|
717
|
+
>>> dotted.unpack(deep, project=[('a.*', True), 'd'], partial=False)
|
|
718
|
+
{'a.b.c': 1, 'd': 9}
|
|
719
|
+
|
|
720
|
+
`project=` and `partial=` also flow through `keys()`, `values()`, and `items()`.
|
|
721
|
+
|
|
692
722
|
<a id="pack"></a>
|
|
693
723
|
### Pack
|
|
694
724
|
|
|
@@ -1099,7 +1099,7 @@ def pack(pathvalues, apply_transforms=True, strict=False, bindings=None):
|
|
|
1099
1099
|
return update_multi(AUTO, pathvalues, apply_transforms=apply_transforms, strict=strict, bindings=bindings)
|
|
1100
1100
|
|
|
1101
1101
|
|
|
1102
|
-
def unpack(obj, attrs=None):
|
|
1102
|
+
def unpack(obj, attrs=None, project=None, partial=True):
|
|
1103
1103
|
"""
|
|
1104
1104
|
Convert obj to dotted normal form. A dict mapping dotted paths to leaf
|
|
1105
1105
|
values, which can be replayed to regenerate the obj (see `pack`).
|
|
@@ -1117,6 +1117,27 @@ def unpack(obj, attrs=None):
|
|
|
1117
1117
|
{'a.b': [1, 2, 3], 'x.y.z': [4, 5], 'extra': 'stuff'}
|
|
1118
1118
|
>>> pack(r) == d
|
|
1119
1119
|
True
|
|
1120
|
+
|
|
1121
|
+
Pass project= to keep only the leaf paths selected by one or more dotted
|
|
1122
|
+
patterns. A leaf survives if it `match`es any projection pattern, so
|
|
1123
|
+
selection is directional: projecting 'a.b' never pulls in a scalar leaf
|
|
1124
|
+
'a'. project= accepts a single pattern or an iterable of them:
|
|
1125
|
+
|
|
1126
|
+
>>> o = {'a': {'b': 1, 'c': 2}, 'x': {'y': {'z': 3}}, 'extra': 9}
|
|
1127
|
+
>>> unpack(o, project='a')
|
|
1128
|
+
{'a.b': 1, 'a.c': 2}
|
|
1129
|
+
>>> unpack(o, project=['a', 'x.y.z'])
|
|
1130
|
+
{'a.b': 1, 'a.c': 2, 'x.y.z': 3}
|
|
1131
|
+
|
|
1132
|
+
Matching uses match()'s `partial=True` by default, so a trailing segment
|
|
1133
|
+
is greedy ('a.*' also keeps 'a.b.c'). Set partial=False for exact-depth
|
|
1134
|
+
matching, or override it per-field with a (pattern, partial) tuple:
|
|
1135
|
+
|
|
1136
|
+
>>> deep = {'a': {'b': {'c': 1}}, 'd': 9}
|
|
1137
|
+
>>> unpack(deep, project='a.*', partial=False)
|
|
1138
|
+
{}
|
|
1139
|
+
>>> unpack(deep, project=[('a.*', True), 'd'])
|
|
1140
|
+
{'a.b.c': 1, 'd': 9}
|
|
1120
1141
|
"""
|
|
1121
1142
|
# Accept either `Attrs` enum members or their string values.
|
|
1122
1143
|
attr_values = {a.value if isinstance(a, Attrs) else a for a in (attrs or ())}
|
|
@@ -1128,43 +1149,58 @@ def unpack(obj, attrs=None):
|
|
|
1128
1149
|
extra = ', @/(?!__).*/'
|
|
1129
1150
|
else:
|
|
1130
1151
|
extra = ', @/__.*/'
|
|
1131
|
-
|
|
1152
|
+
result = dict(pluck(obj, f'*(*#, [*]:!(str, bytes){extra}):-2(.*, []{extra})##, (*, []{extra})'))
|
|
1153
|
+
if project is None:
|
|
1154
|
+
return result
|
|
1155
|
+
if isinstance(project, str):
|
|
1156
|
+
project = [project]
|
|
1157
|
+
# Normalize each entry to (pattern, partial); bare patterns inherit the
|
|
1158
|
+
# global `partial`, (pattern, partial) tuples override it per-field.
|
|
1159
|
+
specs = [(p, partial) if isinstance(p, str) else tuple(p) for p in project]
|
|
1160
|
+
return {k: v for k, v in result.items()
|
|
1161
|
+
if any(match(pat, k, partial=pp) for pat, pp in specs)}
|
|
1132
1162
|
|
|
1133
1163
|
|
|
1134
|
-
def items(obj, attrs=None):
|
|
1164
|
+
def items(obj, attrs=None, project=None, partial=True):
|
|
1135
1165
|
"""
|
|
1136
1166
|
Return (path, value) pairs of obj in normal form as a dict_items view.
|
|
1137
|
-
Internally calls unpack().
|
|
1167
|
+
Internally calls unpack(); accepts project=/partial= (see unpack).
|
|
1138
1168
|
|
|
1139
1169
|
>>> d = {'a': {'b': 1}, 'x': 2}
|
|
1140
1170
|
>>> sorted(items(d))
|
|
1141
1171
|
[('a.b', 1), ('x', 2)]
|
|
1172
|
+
>>> sorted(items(d, project='a'))
|
|
1173
|
+
[('a.b', 1)]
|
|
1142
1174
|
"""
|
|
1143
|
-
return unpack(obj, attrs=attrs).items()
|
|
1175
|
+
return unpack(obj, attrs=attrs, project=project, partial=partial).items()
|
|
1144
1176
|
|
|
1145
1177
|
|
|
1146
|
-
def keys(obj, attrs=None):
|
|
1178
|
+
def keys(obj, attrs=None, project=None, partial=True):
|
|
1147
1179
|
"""
|
|
1148
1180
|
Return the dotted paths of obj in normal form as dict_keys.
|
|
1149
|
-
Internally calls unpack().
|
|
1181
|
+
Internally calls unpack(); accepts project=/partial= (see unpack).
|
|
1150
1182
|
|
|
1151
1183
|
>>> d = {'a': {'b': 1}, 'x': 2}
|
|
1152
1184
|
>>> sorted(keys(d))
|
|
1153
1185
|
['a.b', 'x']
|
|
1186
|
+
>>> sorted(keys(d, project='a'))
|
|
1187
|
+
['a.b']
|
|
1154
1188
|
"""
|
|
1155
|
-
return unpack(obj, attrs=attrs).keys()
|
|
1189
|
+
return unpack(obj, attrs=attrs, project=project, partial=partial).keys()
|
|
1156
1190
|
|
|
1157
1191
|
|
|
1158
|
-
def values(obj, attrs=None):
|
|
1192
|
+
def values(obj, attrs=None, project=None, partial=True):
|
|
1159
1193
|
"""
|
|
1160
1194
|
Return the leaf values of obj in normal form.
|
|
1161
|
-
Internally calls unpack().
|
|
1195
|
+
Internally calls unpack(); accepts project=/partial= (see unpack).
|
|
1162
1196
|
|
|
1163
1197
|
>>> d = {'a': {'b': 1}, 'x': 2}
|
|
1164
1198
|
>>> sorted(values(d))
|
|
1165
1199
|
[1, 2]
|
|
1200
|
+
>>> sorted(values(d, project='a'))
|
|
1201
|
+
[1]
|
|
1166
1202
|
"""
|
|
1167
|
-
return unpack(obj, attrs=attrs).values()
|
|
1203
|
+
return unpack(obj, attrs=attrs, project=project, partial=partial).values()
|
|
1168
1204
|
|
|
1169
1205
|
|
|
1170
1206
|
#
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotted_notation
|
|
3
|
-
Version: 0.44.
|
|
3
|
+
Version: 0.44.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: MIT
|
|
@@ -729,6 +729,36 @@ For example:
|
|
|
729
729
|
|
|
730
730
|
Pass both to include all attributes: `attrs=[Attrs.standard, Attrs.special]`.
|
|
731
731
|
|
|
732
|
+
Pass `project=` to keep only the leaf paths selected by one or more dotted
|
|
733
|
+
patterns. Selection is *directional* — a leaf survives if it `match`es a
|
|
734
|
+
projection pattern — so projecting `a.b` never drags in a shallower scalar leaf
|
|
735
|
+
`a`:
|
|
736
|
+
|
|
737
|
+
>>> o = {'a': {'b': 1, 'c': 2}, 'x': {'y': {'z': 3}}, 'extra': 9}
|
|
738
|
+
>>> dotted.unpack(o, project='a')
|
|
739
|
+
{'a.b': 1, 'a.c': 2}
|
|
740
|
+
>>> dotted.unpack(o, project=['a', 'x.y.z'])
|
|
741
|
+
{'a.b': 1, 'a.c': 2, 'x.y.z': 3}
|
|
742
|
+
|
|
743
|
+
Matching uses `match`'s `partial=True` by default, so a trailing segment is
|
|
744
|
+
greedy (`a.*` also keeps `a.b.c`). Set `partial=False` for exact-depth matching,
|
|
745
|
+
where `a.*`, `a.*.*`, and `a.**` are all distinct:
|
|
746
|
+
|
|
747
|
+
>>> deep = {'a': {'b': {'c': 1}}, 'd': 9}
|
|
748
|
+
>>> dotted.unpack(deep, project='a.*', partial=False)
|
|
749
|
+
{}
|
|
750
|
+
>>> dotted.unpack(deep, project='a.**', partial=False)
|
|
751
|
+
{'a.b.c': 1}
|
|
752
|
+
|
|
753
|
+
Override `partial` per field with a `(pattern, partial)` tuple — bare patterns
|
|
754
|
+
inherit the global setting. This matters for mid-pattern matches that `**`
|
|
755
|
+
cannot express (e.g. `a.*.c` keeping both `a.x.c` and `a.x.c.d`):
|
|
756
|
+
|
|
757
|
+
>>> dotted.unpack(deep, project=[('a.*', True), 'd'], partial=False)
|
|
758
|
+
{'a.b.c': 1, 'd': 9}
|
|
759
|
+
|
|
760
|
+
`project=` and `partial=` also flow through `keys()`, `values()`, and `items()`.
|
|
761
|
+
|
|
732
762
|
<a id="pack"></a>
|
|
733
763
|
### Pack
|
|
734
764
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dotted_notation"
|
|
7
|
-
version = "0.44.
|
|
7
|
+
version = "0.44.2"
|
|
8
8
|
description = "Dotted notation for safe nested data traversal with optional chaining, pattern matching, and transforms"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
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
|
{dotted_notation-0.44.0 → dotted_notation-0.44.2}/dotted_notation.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|