moat-lib-path 0.3.7__tar.gz → 0.4.0__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.
- {moat_lib_path-0.3.7/src/moat_lib_path.egg-info → moat_lib_path-0.4.0}/PKG-INFO +1 -1
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/debian/changelog +6 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/pyproject.toml +1 -1
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/src/moat/lib/path/__init__.py +2 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/src/moat/lib/path/_impl.py +22 -80
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0/src/moat_lib_path.egg-info}/PKG-INFO +1 -1
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/LICENSE.txt +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/Makefile +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/README.md +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/debian/.gitignore +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/debian/control +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/debian/rules +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/setup.cfg +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/src/moat_lib_path.egg-info/SOURCES.txt +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/src/moat_lib_path.egg-info/dependency_links.txt +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/src/moat_lib_path.egg-info/requires.txt +0 -0
- {moat_lib_path-0.3.7 → moat_lib_path-0.4.0}/src/moat_lib_path.egg-info/top_level.txt +0 -0
|
@@ -22,7 +22,7 @@ name = "moat-lib-path"
|
|
|
22
22
|
maintainers = [{email = "matthias@urlichs.de",name = "Matthias Urlichs"}]
|
|
23
23
|
description='Hierarchical path representation and manipulation for MoaT'
|
|
24
24
|
readme = "README.md"
|
|
25
|
-
version = "0.
|
|
25
|
+
version = "0.4.0"
|
|
26
26
|
|
|
27
27
|
[project.urls]
|
|
28
28
|
homepage = "https://m-o-a-t.org"
|
|
@@ -78,13 +78,31 @@ _PartRE = re.compile("[^:._]+|_|:|\\.")
|
|
|
78
78
|
_RTagRE = re.compile("^:m[^:._]+:$")
|
|
79
79
|
|
|
80
80
|
|
|
81
|
+
def norm_root(root: Path) -> Path:
|
|
82
|
+
"""Flatten a possibly ``:R``-prefixed path into a plain one.
|
|
83
|
+
|
|
84
|
+
Constructing a path that equals the ambient root (e.g. ``P("a.b")``
|
|
85
|
+
while ``Root`` is ``a.b``) absorbs the root as a ``:R`` prefix.
|
|
86
|
+
Storing such a self-referential path as a root would serialize to
|
|
87
|
+
the empty string, so roots must always be normalized to plain
|
|
88
|
+
element tuples.
|
|
89
|
+
"""
|
|
90
|
+
if root._prefix is None: # noqa: SLF001
|
|
91
|
+
return root
|
|
92
|
+
pref = root._prefix # noqa: SLF001
|
|
93
|
+
if not isinstance(pref, RootPath):
|
|
94
|
+
# Explicitly-relative path (``:@``): not a root absorption.
|
|
95
|
+
return root
|
|
96
|
+
return Path(*pref._data, *root._data, _warn=False) # noqa: SLF001
|
|
97
|
+
|
|
98
|
+
|
|
81
99
|
def set_root(cfg) -> None:
|
|
82
100
|
"""
|
|
83
101
|
Utility to force-set the root global.
|
|
84
102
|
|
|
85
103
|
Used for testing without a "proper" context.
|
|
86
104
|
"""
|
|
87
|
-
Root.set(cfg.root)
|
|
105
|
+
Root.set(norm_root(cfg.root))
|
|
88
106
|
|
|
89
107
|
|
|
90
108
|
@total_ordering
|
|
@@ -1164,80 +1182,7 @@ path_eval = _eval.eval
|
|
|
1164
1182
|
# Here we declare our bunch of "root" variables.
|
|
1165
1183
|
|
|
1166
1184
|
|
|
1167
|
-
|
|
1168
|
-
"""Token returned by :meth:`Var.set`.
|
|
1169
|
-
|
|
1170
|
-
``Var`` has no context to restore, so unlike a real ``ContextVar`` token
|
|
1171
|
-
this carries no state: its only job is to be recognisable to
|
|
1172
|
-
:meth:`Var.reset` so the ``set``/``reset`` protocol driven by ``ctx_as``
|
|
1173
|
-
works uniformly for both ``ContextVar`` and ``Var``.
|
|
1174
|
-
"""
|
|
1175
|
-
|
|
1176
|
-
__slots__ = ()
|
|
1177
|
-
|
|
1178
|
-
def __repr__(self) -> str:
|
|
1179
|
-
return "<Var no-reset token>"
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
_VAR_SET_TOKEN = _NoResetToken()
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
class Var:
|
|
1186
|
-
"""
|
|
1187
|
-
This mimics a ContextVar but without the context.
|
|
1188
|
-
"""
|
|
1189
|
-
|
|
1190
|
-
def __init__(self, name, default=NotGiven) -> None:
|
|
1191
|
-
self.name = name
|
|
1192
|
-
self.default = default
|
|
1193
|
-
self.data = NotGiven
|
|
1194
|
-
|
|
1195
|
-
def get(self):
|
|
1196
|
-
"get current value"
|
|
1197
|
-
if self.data is NotGiven:
|
|
1198
|
-
raise ValueError("Not set")
|
|
1199
|
-
return self.data
|
|
1200
|
-
|
|
1201
|
-
def set(self, val, *, force: bool = False):
|
|
1202
|
-
"set current value"
|
|
1203
|
-
# If the root is a.b.c, a new identical value will arrive as an
|
|
1204
|
-
# empty path with a root of a.b.c. That's bad. Thus silently don't
|
|
1205
|
-
# update in that case.
|
|
1206
|
-
#
|
|
1207
|
-
# We detect that case structurally.
|
|
1208
|
-
#
|
|
1209
|
-
# Match by the RootPath's *key* ("R"), not by ``_var is self``:
|
|
1210
|
-
# the ``RootPath`` embedded in @val may hold a stale ``Var`` (a
|
|
1211
|
-
# second ``Root`` instance created, if the namespace-packaged
|
|
1212
|
-
# ``moat.lib.path._impl`` is loaded more than once), so identity
|
|
1213
|
-
# would fail even though @val denotes the same root.
|
|
1214
|
-
if (
|
|
1215
|
-
not force
|
|
1216
|
-
and self.data is not NotGiven
|
|
1217
|
-
and isinstance(val, Path)
|
|
1218
|
-
and isinstance(val._prefix, RootPath) # noqa:SLF001
|
|
1219
|
-
and val._prefix._key == "R" # noqa:SLF001
|
|
1220
|
-
and not len(val._data) # noqa:SLF001
|
|
1221
|
-
):
|
|
1222
|
-
return _VAR_SET_TOKEN
|
|
1223
|
-
if not force and self.data is not NotGiven:
|
|
1224
|
-
if self.data.slashed != val.slashed:
|
|
1225
|
-
raise ValueError("Already set", self.data, val)
|
|
1226
|
-
return _VAR_SET_TOKEN
|
|
1227
|
-
self.data = val
|
|
1228
|
-
return _VAR_SET_TOKEN
|
|
1229
|
-
|
|
1230
|
-
def __bool__(self) -> bool:
|
|
1231
|
-
"check if value is set"
|
|
1232
|
-
return self.data is not NotGiven
|
|
1233
|
-
|
|
1234
|
-
def reset(self, token) -> None:
|
|
1235
|
-
"reset value; no-op"
|
|
1236
|
-
if token is not _VAR_SET_TOKEN:
|
|
1237
|
-
raise ValueError(token)
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
Root = Var("Root", default=None)
|
|
1185
|
+
Root = ContextVar[Path | None]("Root", default=None)
|
|
1241
1186
|
|
|
1242
1187
|
|
|
1243
1188
|
class RootPath(Path):
|
|
@@ -1250,7 +1195,7 @@ class RootPath(Path):
|
|
|
1250
1195
|
|
|
1251
1196
|
_mark = ""
|
|
1252
1197
|
|
|
1253
|
-
def __init__(self, key: str, var: ContextVar[Path | None]
|
|
1198
|
+
def __init__(self, key: str, var: ContextVar[Path | None]) -> None:
|
|
1254
1199
|
self._key = key
|
|
1255
1200
|
self._var = var
|
|
1256
1201
|
|
|
@@ -1269,10 +1214,7 @@ class RootPath(Path):
|
|
|
1269
1214
|
|
|
1270
1215
|
def __bool__(self) -> bool:
|
|
1271
1216
|
"check if the contextvar is set"
|
|
1272
|
-
|
|
1273
|
-
return bool(self._var)
|
|
1274
|
-
p = self._var.get()
|
|
1275
|
-
return p is not None
|
|
1217
|
+
return self._var.get() is not None
|
|
1276
1218
|
|
|
1277
1219
|
@property
|
|
1278
1220
|
def _data(self) -> PathTuple: # pyright:ignore
|
|
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
|