Skip to content

Method Resolution Order (MRO) is not compliant #525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
pfalcon opened this issue Apr 28, 2014 · 10 comments
Open

Method Resolution Order (MRO) is not compliant #525

pfalcon opened this issue Apr 28, 2014 · 10 comments
Labels
py-core Relates to py/ directory in source

Comments

@pfalcon
Copy link
Contributor

pfalcon commented Apr 28, 2014

uPy currently implements depth-first MRO, which is equivalent to one used pre-Python2.2.
References:

@pfalcon
Copy link
Contributor Author

pfalcon commented Apr 28, 2014

Unfortunately, those links don't give complete truth, because:

#class C(tuple, list):

class Foo1:
    pass
#    def __str__(self):
#        return "Foo1"

class Foo2:
    pass
    def __str__(self):
        return "Foo2"

class C(Foo1, tuple, Foo2):
    pass

t = C((1, 2, 3))
t.foo = "bar"
print(t)
print(t[0])
print(t.foo)

Foo2
1
bar

One would expect tuple's print to be used if real natural ordering is used. What logic CPython applies here? That builtin type's print used only if no user types provide it? (Supposedly to let user chance override it?) Is it applied only for special methods (like __str__ in this case), or for all methods? Questions, questions...

@pfalcon
Copy link
Contributor Author

pfalcon commented Apr 28, 2014

And that's exactly MRO non-compliance what hits:
https://mail.python.org/pipermail/python-dev/2014-April/134342.html

@dpgeorge
Copy link
Member

Righto. Well, if it's supposed to be that way, then it's going to be a hack to implement.

@dpgeorge
Copy link
Member

Seems that __add__ is correct (ie goes to built in).

Also seems that explicit t.__str__() calls Foo2's (so "incorrect").

@dpgeorge
Copy link
Member

And yet __repr__ will go to the tuple! (via both repr(t) and t.__repr__).

@pfalcon
Copy link
Contributor Author

pfalcon commented Apr 28, 2014

@dpgeorge , as reply to python-dev message above explains, this case is fully governed by C3 MRO algo. Then apparently CPy for a case where __str__ and __repr__ give the same result, implements just __repr__, and redirection __str__ -> __repr__ happens in object.__str__.

We surely don't need to either implement or emulate this __str__/__repr__ behavior, it's fair to call it impl-specific (those methods are "special", as we know). Other methods should not give such surprises. But the whole MRO issue of course would be (yet another) reason why Django isn't going to work anytime soon ;-).

@dpgeorge
Copy link
Member

I get:

>>> list.__str__
<slot wrapper '__str__' of 'object' objects>
>>> list.__repr__
<slot wrapper '__repr__' of 'list' objects>

@pfalcon
Copy link
Contributor Author

pfalcon commented Apr 28, 2014

Yup, my "apparently" is based on watching that.

@pfalcon
Copy link
Contributor Author

pfalcon commented Apr 28, 2014

Also, constructor resolution is a somewhat special matter, but I'll elaborate in #401.

@dpgeorge
Copy link
Member

Well, at least this means we can go ahead with a straight forward implementation of MRO, and get these details correct at the very end, if at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
py-core Relates to py/ directory in source
Projects
None yet
Development

No branches or pull requests

3 participants