Hm.
If I understand correctly what you want is to generate attributes at
compile-time and then get all the benefits of having statically declared
attributes at run-time.

This looks like a very interesting use-case. I guess it's a kind of
named tuples with custom methods. The syntax you propose is quite
pythonic and I would love that cython support something like that.
However, in the current state of the code you proposed as some weird
stuff going on.
First and foremost, it would be quite challenging to disentangle what
should be executed at compile-time and what should be left for the
run-time.
Second, you'd actually generate a different Base class for each of its
subclasses. Which is pretty weird from a typing perspective. Your Foo
and Bar wouldn't have a common base class beside Object. I guess what
you're trying to do is kind of a compile-time generated mixin.
I guess a better outline for this could be something like this:
```
cdef class Base:
    pass

def generate_mixin(attrs):
    cdef class C:
        # Generate content based on attrs
    return C

ctfe Foo = generate_mixin(["foo", "bar"])
ctfe Bar = generate_mixin(["bar", "baz"])
```
These Foo and Bar classes could then be subclassed to add whatever
specific method you want.

On the other hand, the syntax I proposed makes it very clear what's
executed at compile-time or run-time, but cannot support your use-case.
Especially declaring a varying number of cdef attributes.

I know D supports features like this. But it does so with a vastly
different set of concepts. Like the `mixin` keyword that inline a
compile-time string into the code.

I guess I'll think about it and see if I can come up with a small set of
concepts and syntaxes that support this use-case without having to
resort to full blown AST manipulation.


Le Fri, Feb 26, 2021 at 07:07:23PM -0800, Brock Mendel a écrit :
>    Would the following be a good use case for what you're discussing?
>    ```
>    cdef class Base:
>        cdef __cinit__(self, **kwargs):
>            for name in self.list_defined_on_subclass:
>                value = kwargs[name]
>                setattr(self, name, value)
>         cpdef copy(self):
>              kwargs = {name: getattr(self, name) for name
>    in self.list_defined_on_subclass}
>              return type(self)(**kwargs)
>    cdef class Foo(Base):
>        list_defined_on_subclass =  ["foo", "bar"]
>    cdef class Bar(Base):
>        list_defined_on_subclass =  ["bar", "baz"]
>    ```
>    and then at compile-time have the macro expand Foo to something like
> 
>    ```
>    cdef class Foo:
>        cdef:
>            something foo
>            something_else bar
>        def __cinit__(self, *, foo, bar):
>            self.foo = foo
>            self.bar = bar
>        cpdef copy(self):
>            return type(self)(foo=self.foo, bar=self.bar)
>    ```
_______________________________________________
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel

Reply via email to