I am trying out a prototype for a language using the textx module for python that can interpret grammars. I am creating a model like this:
from textx import metamodel_from_str
funl_grammar = """
Model: statement *= Statement;
Statement: FunctionDefinition | Function;
FunctionDefinition: name=ID '=' function=Function;
Function: name=ID '(' params*=Param (',' params*=Param)* ')';
Param: Function | INT | ID | STRING;
Comment: /#.*$/;
ID: /[a-zA-Z_][a-zA-Z0-9_]*/;
INT: /[0-9]+/;
STRING: /".*"/;
"""
mm = metamodel_from_str(funl_grammar)
Now my question is, how can I typecheck for it using mypy?
If I create a function like this where I want to be sure that the parameter is part of my grammar and textx considers it a Param
:
def my_func(param: mm["Param"]):
...
I get the mypy error error: Name "Param" is not defined [name-defined]
.
Do you know how I could fix that? Googling and ChatGPT has not helped so far.
The library in question is creating these classes dynamically:
def _new_class(self, ...):
class TextXClass(metaclass=TextXMetaClass):
def __repr__(self): ...
cls = TextXClass
cls.__name__ = name
self._init_class(cls, ...)
return cls
They are created inside a closure, and only as instances of TextXMetaClass
. It is thus not possible to refer to them statically in any other ways than TextXMetaClass
, which itself doesn't have much information to begin with:
class TextXMetaClass(type):
def __repr__(cls): ...
# `param` must be a class created by TextXMetaClass
def my_func(param: TextXMetaClass): ...
my_func(mm["Param"]) # This is supposedly fine
my_func(mm["Param"]()) # This is not
TextX is also untyped, and a Mypy plugin for it doesn't seem to exist either, so your best bet is to forgo static type checking altogether.