Title TypeError: unbound compiled_method __new__() must be called with NuitkaIntEnumTest instance as first argument (got EnumMeta instance instead)
Priority bug Status testing
Superseder Nosy List desowin, kayhayen
Assigned To desowin Keywords wrong_execution

Created on 2018-03-01.14:13:48 by desowin, last changed by kayhayen.

File name Uploaded Type Edit Remove
nuitka-enum-bug.tar.bz2 desowin, 2018-03-01.14:13:48 application/octet-stream
msg2308 (view) Author: kayhayen Date: 2018-03-12.18:06:06
In typeobject.c of CPython this happens in the type class:

    /* Special-case __new__: if it's a plain function,
       make it a static function */
    tmp = PyDict_GetItemString(dict, "__new__");
    if (tmp != NULL && PyFunction_Check(tmp)) {
        tmp = PyStaticMethod_New(tmp);
        if (tmp == NULL) {
            return NULL;
        PyDict_SetItemString(dict, "__new__", tmp);

This makes a staticmethod out of uncompiled functions named "__new__". For Nuitka we 
migitate this by adding a "staticmethod" decorator to "__new__" functions, also to 
make it visible to optimization how it's used.

An assignment from the outside is largely invisible here.

A general fix is near impossible. Adding a staticmethod() will likely help with this 
enum module.

temp_enum_dict['__new__'] = __new__
temp_enum_dict['__new__'] = staticmethod(__new__)

The solution is doing that through a plugin that fixes up "enum" module right after it 
was loaded, and before it can be used. When you use current factory branch it will 
warn you about plugin "enum_compat" and when you enable it, things just work.

msg2307 (view) Author: kayhayen Date: 2018-03-12.17:20:46

there is a strangely hacked __new__ in the "enum" module. It does give me this for new:

<function __new__ at 0x7f1b4dd9d758>
<function __new__ at 0x7f1b4dd9d758>
<function __new__ at 0x7f1b4dd9d758>
<unbound method NuitkaIntEnumTest.f>

First output is in module, second in meta class IntEnum, third the NuitkaIntEnumTest, and 
last is a normal function declared in the body.

And here is what Nuitka makes out of it:

<compiled_function __new__ at 0x7f7c4d8b0460>
<unbound compiled_method IntEnum.__new__>
<unbound compiled_method NuitkaIntEnumTest.__new__>
<unbound compiled_method NuitkaIntEnumTest.f>

So, when creating the class, Nuitka allows for the "__new__" to become an unbound method, 
although it normally is a "staticmethod" rather.

So some form of incompatibility is happening here. I am a bit surprised, and need to check if 
the descriptor lookup needs to be more clever or what this is caused by.

It definitely doesn't seem to be about type checks or so in the enum module, although there 
are some, but for staticmethod, which shouldn't strike.

msg2306 (view) Author: kayhayen Date: 2018-03-12.16:52:51

I can reproduce this, but it is baffling, there is no "__new__" method in your 
class. So this is impossible to be a compiled method, yet it is somehow.

msg2303 (view) Author: desowin Date: 2018-03-01.14:13:47
Enclosed is a minimal code that shows a bug in Nuitka

This is Python 2.7 code that uses enum34 library.

$ python

$ nuitka --recurse-all
$ ./test.exe
Traceback (most recent call last):
  File "/tmp/nuitka-enum-bug/", line 10, in <module>
  File "/tmp/nuitka-enum-bug/", line 5, in main
    while NuitkaIntEnumTest.isKnown(i):
  File "/tmp/nuitka-enum-bug/", line 10, in isKnown
  File "/usr/local/lib/python2.7/dist-packages/enum/", line 347, 
in __call__
    return cls.__new__(cls, value)
TypeError: unbound compiled_method __new__() must be called with 
NuitkaIntEnumTest instance as first argument (got EnumMeta instance instead)
Date User Action Args
2018-03-12 18:07:08kayhayensetstatus: chatting -> testing
assignedto: kayhayen -> desowin
keyword: + wrong_execution
2018-03-12 18:06:06kayhayensetmessages: + msg2308
2018-03-12 17:20:46kayhayensetmessages: + msg2307
2018-03-12 16:52:54kayhayensetstatus: unread -> chatting
assignedto: kayhayen
messages: + msg2306
nosy: + kayhayen
2018-03-01 14:13:48desowincreate