I’m trying to provide Python type hinting using ForwardRef.
I am using Visual Studio Code editor and i’ve installed plugins python and pylance in order to provide type-hinting.
Code:
I’d prefer if i could write out a class that extends from TypedDict, such as demonstrated with class Filter2(TypedDict)
. The problem with that approuch is that Python class-syntax does not allow properties keys including a dollarsign symbol.
Therefore the only option is to define the Filter using TypedDict as constructor function and provide it with property keys that do allow using dollassign symbol.
Moving from class-syntax to TypedDict constructor produces yet another problem. Python ForwardRef and class-syntax work nicely together. Type-hinting can manage circular dependencies very well. Filter2 is used as a ForwardRef inside the query properties _and
, _or
and it provides Python type hinting as you’d expect.
However, when i write out a ForwardRef constructor as a option in a TypedDict constuctor, with as purpose to manage the type hinting circular dependency, type hinting does not provide hints for the ForwardRef’ed option.
The Query syntax is Mongo DB query syntax.
Who can provide type-hinting where circular dependencies and dollarsigns are both applied?
from typing import TypedDict, NewType, Literal, Union, ForwardRef
FilterRegex = TypedDict(
'FilterValue', {'$regex': str, '$options': Literal['i']})
FilterIn = TypedDict('FilterIn', {"$in": list[int, str, bool]})
FilterValue = Union[FilterIn, FilterRegex]
FilterEntry = NewType('FilterEntry', dict[str, FilterValue])
_Filters: Filters = ForwardRef('Filters')
FilterList = NewType('FilterList', list[Union[FilterEntry, _Filters]])
Filters = TypedDict('FilterList', {'$and': FilterList, '$or': FilterList})
class Filters2(TypedDict):
_and: list[Union[FilterEntry, 'Filters2']]
_or: list[Union[FilterEntry, 'Filters2']]
Filter = NewType('Filter', Union[FilterEntry, Filters])
class TypedParams(TypedDict):
filter: Union[FilterEntry, Filters]
TypedParams({'filter': {'$and': [
{'a': {'$in': []}},
{'b': {'$regex': '', '$options': 'i'}},
{''}
]}})