Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #49368 > unrolled thread

Problems with subclassing enum34

Started byThomas Heller <theller@ctypes.org>
First post2013-06-28 12:48 +0200
Last post2013-06-28 10:09 -0700
Articles 8 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Problems with subclassing enum34 Thomas Heller <theller@ctypes.org> - 2013-06-28 12:48 +0200
    Re: Problems with subclassing enum34 Robert Kern <robert.kern@gmail.com> - 2013-06-28 12:16 +0100
    Re: Problems with subclassing enum34 88888 Dihedral <dihedral88888@gmail.com> - 2013-06-28 04:52 -0700
    Re: Problems with subclassing enum34 Ethan Furman <ethan@stoneleaf.us> - 2013-06-28 08:16 -0700
      Re: Problems with subclassing enum34 Thomas Heller <theller@ctypes.org> - 2013-06-28 17:25 +0200
        Re: Problems with subclassing enum34 Thomas Heller <theller@ctypes.org> - 2013-06-28 17:32 +0200
          Re: Problems with subclassing enum34 Robert Kern <robert.kern@gmail.com> - 2013-06-28 17:17 +0100
          Re: Problems with subclassing enum34 Ethan Furman <ethan@stoneleaf.us> - 2013-06-28 10:09 -0700

#49368 — Problems with subclassing enum34

FromThomas Heller <theller@ctypes.org>
Date2013-06-28 12:48 +0200
SubjectProblems with subclassing enum34
Message-ID<b357q6Fql37U1@mid.individual.net>
trying out the enum34 module.

What I want to create is a subclass of enum.Enum that is also
based on ctypes.c_int so that I can better use enum instances
in ctypes api calls.

When I do this, I get a metaclass conflict:


 >>> class MyEnum(ctypes.c_int, enum.Enum):
...    FOOBAR = 0
...
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
     metaclass conflict: the metaclass of a derived class must be a 
(non-strict) subclass of the metaclasses of all its bases
 >>>



When I do this, it does not work either:

 >>> class MyEnum_meta(type(ctypes.c_int), type(enum.Enum)):
...     pass
...
 >>> class MyEnum(ctypes.c_int, enum.Enum):
...     FOOBAR = 42
...     __metaclass__ = MyEnum_meta
...
 >>> MyEnum.FOOBAR
42
 >>>

It should have printed '<MyEnum.FOOBAR: 42>'.

Any ideas?

Thanks,
Thomas

[toc] | [next] | [standalone]


#49370

FromRobert Kern <robert.kern@gmail.com>
Date2013-06-28 12:16 +0100
Message-ID<mailman.3956.1372418213.3114.python-list@python.org>
In reply to#49368
On 2013-06-28 11:48, Thomas Heller wrote:
> trying out the enum34 module.
>
> What I want to create is a subclass of enum.Enum that is also
> based on ctypes.c_int so that I can better use enum instances
> in ctypes api calls.
>
> When I do this, I get a metaclass conflict:
>
>
>  >>> class MyEnum(ctypes.c_int, enum.Enum):
> ...    FOOBAR = 0
> ...
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: Error when calling the metaclass bases
>      metaclass conflict: the metaclass of a derived class must be a (non-strict)
> subclass of the metaclasses of all its bases
>  >>>
>
>
>
> When I do this, it does not work either:
>
>  >>> class MyEnum_meta(type(ctypes.c_int), type(enum.Enum)):
> ...     pass

enum.EnumMeta uses super() in its __new__() implementation but 
_ctypes.PyCSimpleType doesn't. Thus, only _ctypes.PyCSimpleType.__new__() gets a 
chance to run. Switching the order of the two might work.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco

[toc] | [prev] | [next] | [standalone]


#49372

From88888 Dihedral <dihedral88888@gmail.com>
Date2013-06-28 04:52 -0700
Message-ID<32ef33d5-fc45-44d0-ba97-d8f2fcb4d3ac@googlegroups.com>
In reply to#49368
Thomas Heller於 2013年6月28日星期五UTC+8下午6時48分38秒寫道:
> trying out the enum34 module.
> 
> 
> 
> What I want to create is a subclass of enum.Enum that is also
> 
> based on ctypes.c_int so that I can better use enum instances
> 
> in ctypes api calls.
> 
> 
> 
> When I do this, I get a metaclass conflict:
> 
> 
> 
> 
> 
>  >>> class MyEnum(ctypes.c_int, enum.Enum):
> 
> ...    FOOBAR = 0
> 
> ...
> 
> Traceback (most recent call last):
> 
>    File "<stdin>", line 1, in <module>
> 
> TypeError: Error when calling the metaclass bases
> 
>      metaclass conflict: the metaclass of a derived class must be a 
> 
> (non-strict) subclass of the metaclasses of all its bases
> 
>  >>>
> 
> 
> 
> 
> 
> 
> 
> When I do this, it does not work either:
> 
> 
> 
>  >>> class MyEnum_meta(type(ctypes.c_int), type(enum.Enum)):
> 
> ...     pass
> 
> ...
> 
>  >>> class MyEnum(ctypes.c_int, enum.Enum):
> 
> ...     FOOBAR = 42
> 
> ...     __metaclass__ = MyEnum_meta
> 
> ...
> 
>  >>> MyEnum.FOOBAR
> 
> 42
> 
>  >>>
> 
> 
> 
> It should have printed '<MyEnum.FOOBAR: 42>'.
> 
> 
> 
> Any ideas?
> 
> 
> 
> Thanks,
> 
> Thomas

Just use a dictionary for the job. Python i not c/c++.

[toc] | [prev] | [next] | [standalone]


#49377

FromEthan Furman <ethan@stoneleaf.us>
Date2013-06-28 08:16 -0700
Message-ID<mailman.3961.1372432574.3114.python-list@python.org>
In reply to#49368
On 06/28/2013 03:48 AM, Thomas Heller wrote:
> trying out the enum34 module.
>
> What I want to create is a subclass of enum.Enum that is also
> based on ctypes.c_int so that I can better use enum instances
> in ctypes api calls.

Have you tried using enum.IntEnum?  If you were able to pass ints in before, IntEnum should work.

--
~Ethan~

[toc] | [prev] | [next] | [standalone]


#49378

FromThomas Heller <theller@ctypes.org>
Date2013-06-28 17:25 +0200
Message-ID<b35o16Fu6l8U1@mid.individual.net>
In reply to#49377
Am 28.06.2013 17:16, schrieb Ethan Furman:
> On 06/28/2013 03:48 AM, Thomas Heller wrote:
>> trying out the enum34 module.
>>
>> What I want to create is a subclass of enum.Enum that is also based
>> on ctypes.c_int so that I can better use enum instances in ctypes
>> api calls.
>
> Have you tried using enum.IntEnum?  If you were able to pass ints in
>  before, IntEnum should work.

I'm sure that IntEnum works as expected, but I need enums that are
subclasses of ctypes.c_int (so that argument type checking and return
value conversions in ctypes api calls work).

Robert Kern:

>
> enum.EnumMeta uses super() in its __new__() implementation but
> _ctypes.PyCSimpleType doesn't. Thus, only
> _ctypes.PyCSimpleType.__new__() gets a chance to run. Switching the
> order of the two might work.
>

Robert found the problem but I'm unsure if there is a solution.
Also I'm unsure whether this is a bug in ctypes or in enum or if
they are simply incompatible.

Thomas

[toc] | [prev] | [next] | [standalone]


#49380

FromThomas Heller <theller@ctypes.org>
Date2013-06-28 17:32 +0200
Message-ID<b35odpFu8igU1@mid.individual.net>
In reply to#49378
Am 28.06.2013 17:25, schrieb Thomas Heller:
> Robert Kern:
>
>>
>> enum.EnumMeta uses super() in its __new__() implementation but
>> _ctypes.PyCSimpleType doesn't. Thus, only
>> _ctypes.PyCSimpleType.__new__() gets a chance to run. Switching the
>> order of the two might work.
>>
>
> Robert found the problem but I'm unsure if there is a solution.
> Also I'm unsure whether this is a bug in ctypes or in enum or if
> they are simply incompatible.

I forgot to mention that switching the order of metaclasses didn't work.

Thomas

[toc] | [prev] | [next] | [standalone]


#49382

FromRobert Kern <robert.kern@gmail.com>
Date2013-06-28 17:17 +0100
Message-ID<mailman.3964.1372436274.3114.python-list@python.org>
In reply to#49380
On 2013-06-28 16:32, Thomas Heller wrote:
> Am 28.06.2013 17:25, schrieb Thomas Heller:
>> Robert Kern:
>>
>>>
>>> enum.EnumMeta uses super() in its __new__() implementation but
>>> _ctypes.PyCSimpleType doesn't. Thus, only
>>> _ctypes.PyCSimpleType.__new__() gets a chance to run. Switching the
>>> order of the two might work.
>>>
>>
>> Robert found the problem but I'm unsure if there is a solution.
>> Also I'm unsure whether this is a bug in ctypes or in enum or if
>> they are simply incompatible.
>
> I forgot to mention that switching the order of metaclasses didn't work.

You may also need to manually deal with the conflict between Enum.__new__() and 
c_int.__new__().

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco

[toc] | [prev] | [next] | [standalone]


#49384

FromEthan Furman <ethan@stoneleaf.us>
Date2013-06-28 10:09 -0700
Message-ID<mailman.3966.1372440712.3114.python-list@python.org>
In reply to#49380
On 06/28/2013 08:32 AM, Thomas Heller wrote:
> Am 28.06.2013 17:25, schrieb Thomas Heller:
>> Robert Kern:
>>
>>>
>>> enum.EnumMeta uses super() in its __new__() implementation but
>>> _ctypes.PyCSimpleType doesn't. Thus, only
>>> _ctypes.PyCSimpleType.__new__() gets a chance to run. Switching the
>>> order of the two might work.
>>>
>>
>> Robert found the problem but I'm unsure if there is a solution.
>> Also I'm unsure whether this is a bug in ctypes or in enum or if
>> they are simply incompatible.
>
> I forgot to mention that switching the order of metaclasses didn't work.

Here's the traceback:

Traceback (most recent call last):
   File "ct.py", line 7, in <module>
     class MyEnum(ctypes.c_int, Enum):
   File "/home/ethan/source/enum/enum/py2_enum.py", line 149, in __new__
     enum_class = super(EnumMeta, metacls).__new__(metacls, cls, bases, classdict)
TypeError: Error when calling the metaclass bases
     _ctypes.PyCSimpleType.__new__(MyEnum_meta) is not safe, use type.__new__()

Not sure how to fix that.

--
~Ethan~

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web