classification
Title: iteration over attrs in metaclass' __new__ affects class' __name__
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.6, Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: eric.smith, tkhyn
Priority: normal Keywords:

Created on 2018-04-12 09:55 by tkhyn, last changed 2018-04-12 10:47 by tkhyn. This issue is now closed.

Messages (3)
msg315218 - (view) Author: (tkhyn) Date: 2018-04-12 09:55
The following script, run with python 3.6.5, highlights an issue with the class' __name__ attribute being set incorrectly just because of a loop in the metaclass' __new__ method:

class MC(type):
    def __new__(mcs, name, bases, attrs):
        for name, attr in attrs.items():
            pass
        return super(MC, mcs).__new__(mcs, name, bases, attrs)

class C(metaclass=MC):
    a = None

print(C.__name__)


Expected output: "C"
Actual output: "a"

Comment the for loop and you get the expected output!

On Python 2.7.13, the amended code exposes the same bug:

class MC(type):
    def __new__(mcs, name, bases, attrs):
        for name, attr in attrs.items():
            pass
        return super(MC, mcs).__new__(mcs, name, bases, attrs)

class C(object):
    __metaclass__ = MC
    a = None

print C.__name__

output is "__metaclass__" and should be "C"
msg315219 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2018-04-12 10:45
In the loop, you're reassigning the value of name, then using it in the super call. If you change the name of the loop variable, your code works.
msg315220 - (view) Author: (tkhyn) Date: 2018-04-12 10:47
oops,  indeed. Sometimes the obvious things are not so obvious ..
Sorry for the noise!
History
Date User Action Args
2018-04-12 10:47:54tkhynsetmessages: + msg315220
2018-04-12 10:45:23eric.smithsetstatus: open -> closed

type: behavior

nosy: + eric.smith
messages: + msg315219
resolution: not a bug
stage: resolved
2018-04-12 09:55:09tkhyncreate