We try to do the same thing in various libraries. We've settled on using existing python and end up with syntax like:
class MyForm(Form): field = Field() or in your case class Colors(TokenContainer): red = Token() green = Token() blue = Token() (this is using tri.token). The discussion on creating namespaces seem to match this type of usage more than what you've suggested here. > On 20 Oct 2019, at 07:57, Steve Jorgensen <ste...@stevej.name> wrote: > > Several requests for a specific use case. This is something I have been > working on just to practice getting a deeper understanding of Python > metaprogramming, so whether this is something that someone should be trying > to do is, of course, a matter of opinion. > > The idea is to use a class as a singleton collection of choices where every > choice appears both as an attribute of the class/singleton and as a > value/label pair when treating it as a sequence. > > Usage example: > > class Colors(Choices): > with choices(): > RED > GREEN > BLUE > > Colors.RED -> 'Red' > Colors.GREEN -> 'Green' > Colors.BLUE -> 'Blue' > > tuple(Colors) -> (('RED', 'Red'), ('GREEN', 'Green'), ('BLUE', 'Blue')) > > This can be implemented using a mapping object (classdict) returned from the > metaclass' `__prepare__` class method. The classdict is checked prior to > checking the surrounding context and takes priority unless its `__getitem__` > method raises `KeyError`. > > The problem in this case is that the classdict generates results dynamically, > and it has no way of knowing whether a variable reference would have been > resolved in the surrounding context or not. Therefore, it will ALWAYS take > precedence, even masking builtins like `print`, `range`, etc. This is > surprising behavior and generally undesirable. > > As I mentioned already, it is possible to work around the problem for > builtins by having the classdict object specifically test for those, but that > doesn't solve the problem of masking other variables from the surrounding > context. Masking those is also surprising behavior. > > Steve Jorgensen wrote: >> When using a custom classdict to implement a DSL or use in the body of a >> class >> definition, from what I can tell by experiment, the classdict takes >> priority, and the >> surrounding context is only referenced if trying to get an item from the >> classdict raises >> KeyError. >> There is at least one case in which I would like to do the reverse, and have >> the >> classdict be secondary to (masked by) any variables defined in the context >> surrounding the >> execution of the class body. >> I have been able to at least unmask builtins by having the classdict object >> first try >> to get a result from __builtins__ and then fall back to itself. Also, in the >> actual class body, declaring a variable as global seems to be a workaround >> for global variables, but that has to be done explicitly in the body of any >> subclass that >> needs it. Also, that does not handle non-globals in its surrounding context. >> I'm not sure what the best way to deal with this would be, but my first >> thought is to >> maybe have a property that can be set on the metaclass type such as >> `metacls.reluctant_classdict = True` [typo corrected from original post]. > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/HATKS2TRWGA2XLDKEGMBSEO7FLLTLQKJ/ > Code of Conduct: http://python.org/psf/codeofconduct/ _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/THU7JPWX5L7FEZPRDKSZJZGZJSKEKXVP/ Code of Conduct: http://python.org/psf/codeofconduct/