elastic / elasticsearch-dsl-py

High level Python client for Elasticsearch
http://elasticsearch-dsl.readthedocs.org
Apache License 2.0
3.84k stars 802 forks source link

[bug] Type hints are not working correctly when using python 3.12 #1928

Closed pySilver closed 3 weeks ago

pySilver commented 1 month ago

Documents declaration works when Optional is used:

class MyDocument(Document):
    label: Optional[str]

doc = MyDocument(label="test")
print(doc.full_clean()) # Prints no error ie. None

however more recent syntax for Optional is different:

class MyDocument(Document):
    label: str | None

doc = MyDocument(label="test")
print(doc.full_clean()) # prints errors

Errors:

Traceback (most recent call last):
  File "/Users/Silver/Projects/GitHub/mybaze/temp.py", line 77, in <module>
    main()
  File "/Users/Silver/Projects/GitHub/mybaze/temp.py", line 63, in main
    class MyDocument(Document):
  File "/Users/Silver/Projects/GitHub/mybaze/.venv/lib/python3.12/site-packages/elasticsearch_dsl/_sync/document.py", line 56, in __new__
    new_cls = super().__new__(cls, name, bases, attrs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/Silver/Projects/GitHub/mybaze/.venv/lib/python3.12/site-packages/elasticsearch_dsl/document_base.py", line 109, in __new__
    attrs["_doc_type"] = DocumentOptions(name, bases, attrs)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/Silver/Projects/GitHub/mybaze/.venv/lib/python3.12/site-packages/elasticsearch_dsl/document_base.py", line 236, in __init__
    raise TypeError(f"Cannot map field {name}")
TypeError: Cannot map field label
miguelgrinberg commented 1 month ago

We support Optional, as documented. The pipe syntax may or may not work, I did not attempt to support it at this time.

Also note that typing in this libray is a recent effort and we are making it better with every release, but it cannot be considered a completed effort at this time.

pySilver commented 1 month ago

@miguelgrinberg yeah, pipe is not working at the moment. It's a pity because formatters like ruff use it when target python version is >=3.12; I'd love to PR but at the moment I myself not very sophisticated with typing tooling (especially on the platform side).

So yeah, since it's a new thing it's totally fine that it does not work for every case.