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 <[email protected]> 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 -- [email protected]
> To unsubscribe send an email to [email protected]
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/[email protected]/message/HATKS2TRWGA2XLDKEGMBSEO7FLLTLQKJ/
> Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/THU7JPWX5L7FEZPRDKSZJZGZJSKEKXVP/
Code of Conduct: http://python.org/psf/codeofconduct/