dotted-notation 0.44.6__tar.gz → 0.44.7__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.6 → dotted_notation-0.44.7}/CHANGELOG.md +19 -0
- {dotted_notation-0.44.6/dotted_notation.egg-info → dotted_notation-0.44.7}/PKG-INFO +12 -1
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/README.md +11 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/api.py +8 -2
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/base.py +6 -5
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/groups.py +16 -4
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/recursive.py +1 -1
- {dotted_notation-0.44.6 → dotted_notation-0.44.7/dotted_notation.egg-info}/PKG-INFO +12 -1
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/pyproject.toml +1 -1
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/LICENSE +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/MANIFEST.in +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/__init__.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/__main__.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/access.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/cli/__init__.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/cli/_compat.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/cli/formats.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/cli/main.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/containers.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/engine.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/filters.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/grammar.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/matchers.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/predicates.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/results.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/sql/__init__.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/sql/core.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/sql/pg.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/transforms.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/utils.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/utypes.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted/wrappers.py +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted_notation.egg-info/SOURCES.txt +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted_notation.egg-info/dependency_links.txt +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted_notation.egg-info/entry_points.txt +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted_notation.egg-info/requires.txt +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted_notation.egg-info/top_level.txt +0 -0
- {dotted_notation-0.44.6 → dotted_notation-0.44.7}/setup.cfg +0 -0
|
@@ -3,6 +3,25 @@
|
|
|
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.7]
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- `groups='patterns'` capture positions for variadic patterns: literals
|
|
10
|
+
are now correctly excluded when the pattern contains a group or
|
|
11
|
+
recursive op, so `translate`'s `$N` numbering counts pattern segments
|
|
12
|
+
only, as documented. Previously `a.(x,y).*` numbered `$0='a'` (a
|
|
13
|
+
literal), and `**.c` captured the literal `c`.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- A group is one pattern segment: it captures the path segments its
|
|
17
|
+
matching branch consumed as a single group, keeping `$N` positions
|
|
18
|
+
stable across branches of different lengths. `x.(a.b,c)` matching
|
|
19
|
+
`x.a.b` now captures `('x', 'a.b')` instead of `('x', 'a', 'b')`.
|
|
20
|
+
Parentheses thereby act as a regex-like capture group: `x.(a.b)`
|
|
21
|
+
captures `'a.b'` as one group where `x.a.b` captures `'a', 'b'`.
|
|
22
|
+
Nested patterns inside a branch fold into the group's capture, as
|
|
23
|
+
with `**`.
|
|
24
|
+
|
|
6
25
|
## [0.44.6]
|
|
7
26
|
|
|
8
27
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotted_notation
|
|
3
|
-
Version: 0.44.
|
|
3
|
+
Version: 0.44.7
|
|
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
|
|
@@ -508,6 +508,17 @@ excluding literals:
|
|
|
508
508
|
>>> dotted.match('hello.*', 'hello.there.bye', groups=GroupMode.patterns)
|
|
509
509
|
('hello.there.bye', ('there.bye',))
|
|
510
510
|
|
|
511
|
+
Op groups match like regex alternation, and parentheses act as a capture
|
|
512
|
+
group: a group captures the segments its matching branch consumed as a
|
|
513
|
+
single group, and counts as one pattern position:
|
|
514
|
+
|
|
515
|
+
>>> dotted.match('a.(x,y).*', 'a.x.z', groups=GroupMode.patterns, partial=False)
|
|
516
|
+
('a.x.z', ('x', 'z'))
|
|
517
|
+
>>> dotted.match('x.(a.b,c)', 'x.a.b', groups=True)
|
|
518
|
+
('x.a.b', ('x', 'a.b'))
|
|
519
|
+
>>> dotted.match('x.(a.b)', 'x.a.b', groups=True)
|
|
520
|
+
('x.a.b', ('x', 'a.b'))
|
|
521
|
+
|
|
511
522
|
<a id="replace"></a>
|
|
512
523
|
### Replace
|
|
513
524
|
|
|
@@ -468,6 +468,17 @@ excluding literals:
|
|
|
468
468
|
>>> dotted.match('hello.*', 'hello.there.bye', groups=GroupMode.patterns)
|
|
469
469
|
('hello.there.bye', ('there.bye',))
|
|
470
470
|
|
|
471
|
+
Op groups match like regex alternation, and parentheses act as a capture
|
|
472
|
+
group: a group captures the segments its matching branch consumed as a
|
|
473
|
+
single group, and counts as one pattern position:
|
|
474
|
+
|
|
475
|
+
>>> dotted.match('a.(x,y).*', 'a.x.z', groups=GroupMode.patterns, partial=False)
|
|
476
|
+
('a.x.z', ('x', 'z'))
|
|
477
|
+
>>> dotted.match('x.(a.b,c)', 'x.a.b', groups=True)
|
|
478
|
+
('x.a.b', ('x', 'a.b'))
|
|
479
|
+
>>> dotted.match('x.(a.b)', 'x.a.b', groups=True)
|
|
480
|
+
('x.a.b', ('x', 'a.b'))
|
|
481
|
+
|
|
471
482
|
<a id="replace"></a>
|
|
472
483
|
### Replace
|
|
473
484
|
|
|
@@ -762,6 +762,13 @@ def match(pattern, path, groups=False, partial=True, strict=False):
|
|
|
762
762
|
'b'
|
|
763
763
|
>>> match('(!a)', 'a')
|
|
764
764
|
|
|
765
|
+
A group is one pattern segment: it captures the segments its branch
|
|
766
|
+
consumed as a single group, and counts as one pattern position:
|
|
767
|
+
>>> match('x.(a.b,c)', 'x.a.b', groups=True)
|
|
768
|
+
('x.a.b', ('x', 'a.b'))
|
|
769
|
+
>>> match('a.(x,y).*', 'a.x.z', groups='patterns', partial=False)
|
|
770
|
+
('a.x.z', ('x', 'z'))
|
|
771
|
+
|
|
765
772
|
Recursive patterns:
|
|
766
773
|
>>> match('**.c', 'a.b.c')
|
|
767
774
|
'a.b.c'
|
|
@@ -789,8 +796,7 @@ def match(pattern, path, groups=False, partial=True, strict=False):
|
|
|
789
796
|
result = base.match_ops(list(pats), list(path_ops), partial)
|
|
790
797
|
if result is None:
|
|
791
798
|
return returns(None, [])
|
|
792
|
-
|
|
793
|
-
return returns(path, result)
|
|
799
|
+
return returns(path, [v for v, _ in result], [p for _, p in result])
|
|
794
800
|
|
|
795
801
|
# Original non-recursive match logic
|
|
796
802
|
_matches = []
|
|
@@ -45,9 +45,9 @@ def has_any(gen):
|
|
|
45
45
|
def match_ops(pats, path_ops, partial):
|
|
46
46
|
"""
|
|
47
47
|
Match a list of pattern ops against a list of path ops.
|
|
48
|
-
Returns a list of
|
|
49
|
-
Dispatches to each op's do_match, which decides how
|
|
50
|
-
segments it consumes.
|
|
48
|
+
Returns a list of (value, is_pattern) capture pairs on success, None
|
|
49
|
+
on failure. Dispatches to each op's do_match, which decides how
|
|
50
|
+
many path segments it consumes.
|
|
51
51
|
"""
|
|
52
52
|
if pats:
|
|
53
53
|
return pats[0].do_match(pats[1:], path_ops, partial)
|
|
@@ -221,9 +221,10 @@ class TraversalOp(Op):
|
|
|
221
221
|
rest = match_ops(rest_pats, path_ops[1:], partial)
|
|
222
222
|
if rest is None:
|
|
223
223
|
return None
|
|
224
|
+
is_pat = self.is_pattern()
|
|
224
225
|
if isinstance(m, (tuple, list)):
|
|
225
|
-
return [_m.val for _m in m] + rest
|
|
226
|
-
return [m.val] + rest
|
|
226
|
+
return [(_m.val, is_pat) for _m in m] + rest
|
|
227
|
+
return [(m.val, is_pat)] + rest
|
|
227
228
|
|
|
228
229
|
|
|
229
230
|
class MatchOp(Op):
|
|
@@ -109,11 +109,23 @@ class OpGroup(base.TraversalOp):
|
|
|
109
109
|
concrete path can only be produced by one branch at a time, so
|
|
110
110
|
disjunction, first-match, and conjunction all reduce to "any branch
|
|
111
111
|
matches"; cut markers don't constrain matching either.
|
|
112
|
+
|
|
113
|
+
The group is one pattern segment: it contributes a single capture —
|
|
114
|
+
the path segments its branch consumed, assembled — flagged as a
|
|
115
|
+
pattern match (like Recursive).
|
|
112
116
|
"""
|
|
117
|
+
from . import results
|
|
113
118
|
for branch in base.branches_only(self.branches):
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
branch_ops = list(branch)
|
|
120
|
+
for n in range(len(path_ops) + 1):
|
|
121
|
+
consumed = base.match_ops(branch_ops, path_ops[:n], False)
|
|
122
|
+
if consumed is None:
|
|
123
|
+
continue
|
|
124
|
+
rest = base.match_ops(list(rest_pats), path_ops[n:], partial)
|
|
125
|
+
if rest is None:
|
|
126
|
+
continue
|
|
127
|
+
combined = results.assemble(path_ops[:n])
|
|
128
|
+
return [(combined, True)] + rest
|
|
117
129
|
return None
|
|
118
130
|
|
|
119
131
|
def _render(self, top=True):
|
|
@@ -552,7 +564,7 @@ class OpGroupNot(OpGroup):
|
|
|
552
564
|
if rest is None:
|
|
553
565
|
return None
|
|
554
566
|
seg_val = getattr(getattr(kop, 'op', kop), 'value', kop)
|
|
555
|
-
return [seg_val] + rest
|
|
567
|
+
return [(seg_val, True)] + rest
|
|
556
568
|
|
|
557
569
|
def do_update(self, ops, node, val, has_defaults, _path, nop, nop_from_unwrap=False, **kwargs):
|
|
558
570
|
inner = self.inner
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotted_notation
|
|
3
|
-
Version: 0.44.
|
|
3
|
+
Version: 0.44.7
|
|
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
|
|
@@ -508,6 +508,17 @@ excluding literals:
|
|
|
508
508
|
>>> dotted.match('hello.*', 'hello.there.bye', groups=GroupMode.patterns)
|
|
509
509
|
('hello.there.bye', ('there.bye',))
|
|
510
510
|
|
|
511
|
+
Op groups match like regex alternation, and parentheses act as a capture
|
|
512
|
+
group: a group captures the segments its matching branch consumed as a
|
|
513
|
+
single group, and counts as one pattern position:
|
|
514
|
+
|
|
515
|
+
>>> dotted.match('a.(x,y).*', 'a.x.z', groups=GroupMode.patterns, partial=False)
|
|
516
|
+
('a.x.z', ('x', 'z'))
|
|
517
|
+
>>> dotted.match('x.(a.b,c)', 'x.a.b', groups=True)
|
|
518
|
+
('x.a.b', ('x', 'a.b'))
|
|
519
|
+
>>> dotted.match('x.(a.b)', 'x.a.b', groups=True)
|
|
520
|
+
('x.a.b', ('x', 'a.b'))
|
|
521
|
+
|
|
511
522
|
<a id="replace"></a>
|
|
512
523
|
### Replace
|
|
513
524
|
|
|
@@ -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.7"
|
|
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
|
{dotted_notation-0.44.6 → dotted_notation-0.44.7}/dotted_notation.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|