fastcore 2.2.24__tar.gz → 2.2.26__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.
- {fastcore-2.2.24/fastcore.egg-info → fastcore-2.2.26}/PKG-INFO +1 -1
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/__init__.py +1 -1
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/_modidx.py +4 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/xml.py +28 -10
- {fastcore-2.2.24 → fastcore-2.2.26/fastcore.egg-info}/PKG-INFO +1 -1
- {fastcore-2.2.24 → fastcore-2.2.26}/CONTRIBUTING.md +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/LICENSE +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/README.md +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/aio.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/all.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/ansi.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/apisurface.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/basics.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/dispatch.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/docments.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/docscrape.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/editskill.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/foundation.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/funccall.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/imghdr.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/imports.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/meta.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/nb_imports.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/nbio.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/net.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/parallel.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/py2pyi.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/script.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/shutil.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/style.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/test.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/tools.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/transform.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/utils.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/xdg.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore/xtras.py +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore.egg-info/SOURCES.txt +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore.egg-info/dependency_links.txt +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore.egg-info/entry_points.txt +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore.egg-info/requires.txt +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/fastcore.egg-info/top_level.txt +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/pyproject.toml +0 -0
- {fastcore-2.2.24 → fastcore-2.2.26}/setup.cfg +0 -0
|
@@ -817,6 +817,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
817
817
|
'fastcore.xml.E.__getattr__': ('xml.html#e.__getattr__', 'fastcore/xml.py'),
|
|
818
818
|
'fastcore.xml.E.__init__': ('xml.html#e.__init__', 'fastcore/xml.py'),
|
|
819
819
|
'fastcore.xml.E._namespace': ('xml.html#e._namespace', 'fastcore/xml.py'),
|
|
820
|
+
'fastcore.xml.E.attr_value': ('xml.html#e.attr_value', 'fastcore/xml.py'),
|
|
820
821
|
'fastcore.xml.FT': ('xml.html#ft', 'fastcore/xml.py'),
|
|
821
822
|
'fastcore.xml.FT.__call__': ('xml.html#ft.__call__', 'fastcore/xml.py'),
|
|
822
823
|
'fastcore.xml.FT.__eq__': ('xml.html#ft.__eq__', 'fastcore/xml.py'),
|
|
@@ -839,12 +840,15 @@ d = { 'settings': { 'branch': 'main',
|
|
|
839
840
|
'fastcore.xml.Safe': ('xml.html#safe', 'fastcore/xml.py'),
|
|
840
841
|
'fastcore.xml.Safe.__html__': ('xml.html#safe.__html__', 'fastcore/xml.py'),
|
|
841
842
|
'fastcore.xml.XML': ('xml.html#xml', 'fastcore/xml.py'),
|
|
843
|
+
'fastcore.xml.XML.__call__': ('xml.html#xml.__call__', 'fastcore/xml.py'),
|
|
842
844
|
'fastcore.xml.XML.__init__': ('xml.html#xml.__init__', 'fastcore/xml.py'),
|
|
845
|
+
'fastcore.xml.XML.__repr__': ('xml.html#xml.__repr__', 'fastcore/xml.py'),
|
|
843
846
|
'fastcore.xml.XML.__str__': ('xml.html#xml.__str__', 'fastcore/xml.py'),
|
|
844
847
|
'fastcore.xml.XML._child': ('xml.html#xml._child', 'fastcore/xml.py'),
|
|
845
848
|
'fastcore.xml.XML._render': ('xml.html#xml._render', 'fastcore/xml.py'),
|
|
846
849
|
'fastcore.xml.XML._repr_markdown_': ('xml.html#xml._repr_markdown_', 'fastcore/xml.py'),
|
|
847
850
|
'fastcore.xml.XML.bytes': ('xml.html#xml.bytes', 'fastcore/xml.py'),
|
|
851
|
+
'fastcore.xml.XML.render': ('xml.html#xml.render', 'fastcore/xml.py'),
|
|
848
852
|
'fastcore.xml._attr2tag': ('xml.html#_attr2tag', 'fastcore/xml.py'),
|
|
849
853
|
'fastcore.xml._escape': ('xml.html#_escape', 'fastcore/xml.py'),
|
|
850
854
|
'fastcore.xml._fix_k': ('xml.html#_fix_k', 'fastcore/xml.py'),
|
|
@@ -8,7 +8,7 @@ test_eq(to_xml(t), '<div hx-get="/get">\n <p class="a">hi</p>\n</div>\n')
|
|
|
8
8
|
test_eq(to_xml(Div(id='x')('child')), '<div id="x">child</div>\n')
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
`E(prefix='', attr_ns=None, ns=None)` creates a namespace-bound XML factory. `e = E('w', attr_ns='w', ns={'w': uri})` supports expressions such as `e.tcW(type='dxa', w=2400)`. Tags and attributes preserve case. `prefix__name` selects an attribute namespace; `attrs_` accepts literal names. Expressions compose with text and ordered collections, retain their namespace bindings, and serialize as UTF-8 with `.bytes()`. XML text is escaped and booleans become `true`/`false
|
|
11
|
+
`E(prefix='', attr_ns=None, ns=None)` creates a namespace-bound XML factory. `e = E('w', attr_ns='w', ns={'w': uri})` supports expressions such as `e.tcW(type='dxa', w=2400)`. Tags and attributes preserve case. `prefix__name` selects an attribute namespace; `attrs_` accepts literal names. Expressions compose with text and ordered collections, retain their namespace bindings, and serialize as UTF-8 with `.bytes()`. XML text is escaped and booleans become `true`/`false`; subclasses override `attr_value` for vocabularies with other rules. The existing `ft` and `to_xml` APIs keep their HTML behavior.
|
|
12
12
|
|
|
13
13
|
Docs: https://fastcore.fast.ai/xml.html.md"""
|
|
14
14
|
|
|
@@ -319,7 +319,13 @@ class XML:
|
|
|
319
319
|
"A detached XML expression with fixed namespace bindings."
|
|
320
320
|
def __init__(self, tag, children, attrs, ns):
|
|
321
321
|
self.tag,self.attrs,self.ns = tag,attrs,ns
|
|
322
|
-
self.children =
|
|
322
|
+
self.children = ()
|
|
323
|
+
self(*children)
|
|
324
|
+
|
|
325
|
+
def __call__(self, *children):
|
|
326
|
+
"Append children and return this expression."
|
|
327
|
+
self.children += tuple(self._child(c) for c in _xml_flatten(children))
|
|
328
|
+
return self
|
|
323
329
|
|
|
324
330
|
def _child(self, child):
|
|
325
331
|
if isinstance(child, XML): return child
|
|
@@ -335,7 +341,7 @@ def _render(self:XML, inherited, output):
|
|
|
335
341
|
if inherited.get(prefix) != uri:
|
|
336
342
|
name = f'xmlns:{prefix}' if prefix else 'xmlns'
|
|
337
343
|
output.append(f' {name}={quoteattr(uri)}')
|
|
338
|
-
for name, value in self.attrs: output.append(f' {name}={quoteattr(value)}')
|
|
344
|
+
for name, value in self.attrs.items(): output.append(f' {name}={quoteattr(value)}')
|
|
339
345
|
if not self.children:
|
|
340
346
|
output.append('/>')
|
|
341
347
|
return
|
|
@@ -347,22 +353,29 @@ def _render(self:XML, inherited, output):
|
|
|
347
353
|
output.append(f'</{self.tag}>')
|
|
348
354
|
|
|
349
355
|
@patch
|
|
350
|
-
def
|
|
356
|
+
def render(self:XML, inherited=None):
|
|
357
|
+
"Serialize, declaring the bindings not already in scope: `inherited` maps the prefixes bound where the markup will be inserted, `{}` declares every binding, and `None` renders a standalone document"
|
|
351
358
|
output = []
|
|
352
|
-
self._render({'xml': _xml_uri}, output)
|
|
359
|
+
self._render({'xml': _xml_uri, **({'': ''} if inherited is None else inherited)}, output)
|
|
353
360
|
return ''.join(output)
|
|
354
361
|
|
|
362
|
+
@patch
|
|
363
|
+
def __str__(self:XML): return self.render()
|
|
364
|
+
|
|
355
365
|
@patch
|
|
356
366
|
def bytes(self:XML):
|
|
357
367
|
"Serialize as UTF-8, without formatting whitespace."
|
|
358
|
-
return
|
|
368
|
+
return self.render().encode('utf-8')
|
|
359
369
|
|
|
360
370
|
@patch
|
|
361
371
|
def _repr_markdown_(self:XML): return f'```xml\n{self}\n```'
|
|
362
372
|
|
|
373
|
+
@patch
|
|
374
|
+
def __repr__(self:XML): return str(self)
|
|
375
|
+
|
|
363
376
|
# %% ../nbs/09_xml.ipynb #335a7366
|
|
364
377
|
class E:
|
|
365
|
-
"Create a namespace-bound XML factory."
|
|
378
|
+
"Create a namespace-bound XML factory: `e.tag(...)` and `e('tag', ...)` build detached expressions"
|
|
366
379
|
_node_cls = XML
|
|
367
380
|
|
|
368
381
|
def __init__(
|
|
@@ -389,12 +402,17 @@ class E:
|
|
|
389
402
|
if name.startswith('_'): raise AttributeError(name)
|
|
390
403
|
if name.endswith('_') and iskeyword(name[:-1]): name = name[:-1]
|
|
391
404
|
return partial(self, name)
|
|
405
|
+
def attr_value(self, tag, name, value):
|
|
406
|
+
"Serialize attribute `value` of `name` on `tag`; override to apply vocabulary rules such as `on`/`off`"
|
|
407
|
+
return _xml_value(value)
|
|
408
|
+
|
|
392
409
|
|
|
393
410
|
def __call__(self, name, /, *children, attrs_=None, **attrs):
|
|
411
|
+
"Build `name` (qualified by `prefix` unless it already has one) with `children` and `attrs`; call this directly for a tag that is not a Python identifier, such as `e('custom-name')`"
|
|
394
412
|
tag = _xml_qualify(name, self._prefix)
|
|
395
413
|
pairs = [(_xml_qualify(_xml_keyword(k), self._attr_ns), v) for k,v in attrs.items()]
|
|
396
414
|
pairs += list((attrs_ or {}).items())
|
|
397
|
-
ns,seen,values = dict(self._ns),set(),
|
|
415
|
+
ns,seen,values = dict(self._ns),set(),{}
|
|
398
416
|
prefix, _ = _xml_name(tag)
|
|
399
417
|
if prefix: ns[prefix] = self._namespace(prefix)
|
|
400
418
|
for key, value in pairs:
|
|
@@ -404,6 +422,6 @@ class E:
|
|
|
404
422
|
expanded = (ns[prefix] if prefix else '', local)
|
|
405
423
|
if expanded in seen: raise ValueError(f'Duplicate XML attribute: {key!r}')
|
|
406
424
|
seen.add(expanded)
|
|
407
|
-
values.
|
|
408
|
-
return self._node_cls(tag, children,
|
|
425
|
+
values[key] = self.attr_value(tag, key, value)
|
|
426
|
+
return self._node_cls(tag, children, values, ns)
|
|
409
427
|
|
|
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
|
|
File without changes
|
|
File without changes
|