Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NSMapArg type definition is incorrect. #76

Open
dapper91 opened this issue Jan 8, 2023 · 3 comments
Open

NSMapArg type definition is incorrect. #76

dapper91 opened this issue Jan 8, 2023 · 3 comments

Comments

@dapper91
Copy link

dapper91 commented Jan 8, 2023

nsmap argument of Element function is of type Optional[_NSMapArg] where _NSMapArg is Mapping[str, str].

But according to the documentation here namespace key for the default namespace supposed to be None:

...
>>> NSMAP = {None : XHTML_NAMESPACE} # the default namespace (no prefix)

>>> xhtml = etree.Element(XHTML + "html", nsmap=NSMAP) # lxml only!
...

So it seems like _NSMapArg should be Mapping[Optional[str], str]

@ajnelson-nist
Copy link

I also just encountered this issue, and agree that the documentation disagrees with the type stubs.

@danpascu
Copy link

According to this comment:

# See https://github.com/python/typing/pull/273
# Due to Mapping having invariant key types, Mapping[Union[A, B], ...]
# would fail to validate against either Mapping[A, ...] or Mapping[B, ...]
# Try to settle for simpler solution, encouraging use of empty string ('')
# as default namespace prefix. If too many people complain, it can be
# back-paddled as Mapping[Any, ...]
_NSMapArg = Mapping[str, str]

Mapping[Optional[str], str] doesn't work because of Mapping being invariant in key and the recommendation is to use an empty string as default namespace prefix.

Which is fine by me, except it doesn't work:

In [78]: etree.Element('{foo}test', nsmap={'': 'pr'})
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[78], line 1
----> 1 etree.Element('{foo}test', nsmap={'': 'pr'})

File src/lxml/etree.pyx:3092, in lxml.etree.Element()

File src/lxml/apihelpers.pxi:138, in lxml.etree._makeElement()

File src/lxml/apihelpers.pxi:125, in lxml.etree._makeElement()

File src/lxml/apihelpers.pxi:226, in lxml.etree._setNodeNamespaces()

File src/lxml/apihelpers.pxi:1746, in lxml.etree._prefixValidOrRaise()

ValueError: Invalid namespace prefix ''

Apparently the empty string only works for the find* functions, but not for element creation.

@mschoettle
Copy link

I am having exactly this problem as @danpascu as well. For now I'll have to settle with ignoring this (type: ignore[dict-item]).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants