# docparse.py # # Support doc-string parsing classes __all__ = [ 'DocParseMeta' ] class DocParseMeta(type): ''' Metaclass that processes the class docstring through a parser and incorporates the result into the resulting class definition. This allows Python classes to be defined with alternative syntax. To use this class, you first need to define a lexer and parser: from sly import Lexer, Parser class MyLexer(Lexer): ... class MyParser(Parser): ... You then need to define a metaclass that inherits from DocParseMeta. This class must specify the associated lexer and parser classes. For example: class MyDocParseMeta(DocParseMeta): lexer = MyLexer parser = MyParser This metaclass is then used as a base for processing user-defined classes: class Base(metaclass=MyDocParseMeta): pass class Spam(Base): """ doc string is parsed ... """ It is expected that the MyParser() class would return a dictionary. This dictionary is used to create the final class Spam in this example. ''' @staticmethod def __new__(meta, clsname, bases, clsdict): if '__doc__' in clsdict: lexer = meta.lexer() parser = meta.parser() lexer.cls_name = parser.cls_name = clsname lexer.cls_qualname = parser.cls_qualname = clsdict['__qualname__'] lexer.cls_module = parser.cls_module = clsdict['__module__'] parsedict = parser.parse(lexer.tokenize(clsdict['__doc__'])) assert isinstance(parsedict, dict), 'Parser must return a dictionary' clsdict.update(parsedict) return super().__new__(meta, clsname, bases, clsdict) @classmethod def __init_subclass__(cls): assert hasattr(cls, 'parser') and hasattr(cls, 'lexer')