This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author veky
Recipients gone, veky
Date 2017-08-26.11:23:09
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1503746591.58.0.740156869438.issue31283@psf.upfronthosting.co.za>
In-reply-to
Content
Yes, they are obviously not equivalent if you execute

    object = int

before that. :-D

And (like I said) "received wisdom" is also that "except:" is equivalent to "except BaseException:", but of course it isn't equivalent if you execute

    BaseException = NameError

before.

Rebinding the names for fundamental objects in Python doesn't change the semantics of these objects. Python interpreter is an external thing: it doesn't exist "in-universe". It doesn't refer to these objects by names in some currently-executing-Python-instance namespace, it refers to them externally. And, mostly, so do we when explaining how Python works.

Let me give you an analogy: In the old days, you could rebind True and False, for example by saying

    True, False = False, True

But of course, you would trivially understand that after such rebinding,

    if 6 > 4:
        print(1)
    else:
        print(2)

would print 1, not 2. Although we might say "(6>4) is True" while giving the semantics of "if" statement, we _don't_ mean "the object referred by the internal name 'True'". We mean the object _externally_ referred by the name 'True'.

Same as with your "hierarchy question": if you _give_ the explicit list of bases, you give it as a list of names. Those names can be rebound and if the class definition is executed in such a changed namespace, the bases will differ. But you can't rebind anything if you haven't given any explicit base names in the first place. It doesn't matter whether a class is "at the top" or somewhere else; it matters whether its name is explicitly given.

An illustration: Let's say you have executed

    class A: pass
    class B(A): pass

so now A refers to some class, and B refers to another class, inherited from A. If you now execute

    class C(B): pass  # *

you will have a new class C, inherited from B. Of course, if you now change B somehow, and then execute (*) again, you will have another class C, inherited from changed B - because (*) refers to B explicitly. But if you change _A_ somehow, and then execute (*) again, you will have C inherited from the same old B - because (*) doesn't refer to A explicitly. As you see, it doesn't matter whether A is "on the top" (in fact object is on the top, above A), what matters is whether the statement (*) that you re-execute in the changed namespace refers to it by name or not.
History
Date User Action Args
2017-08-26 11:23:11vekysetrecipients: + veky, gone
2017-08-26 11:23:11vekysetmessageid: <1503746591.58.0.740156869438.issue31283@psf.upfronthosting.co.za>
2017-08-26 11:23:11vekylinkissue31283 messages
2017-08-26 11:23:09vekycreate