3

I ran across a weird situation using Brython and inheritance with the str method. Here's my test using the Brython console:

>>> class A(object):
...     def __str__(self):
...         return "A __str__ output."
... 
>>> class B(A):
...     def __str__(self):
...         return super().__str__() + " (from B)"
... 
>>> x = A()
>>> x
<__main__.A object>
>>> y = B()
>>> y
<__main__.B object>
>>> str(y)
"<super: <class 'B'>, <B object>> (from B)"

I was expecting that last line to return:

"A __str__ output. (from B)"

Am I doing something wrong here?

Kyle
  • 554
  • 3
  • 10
  • 1
    bu reported in https://github.com/brython-dev/brython/issues/1366 , and fixed in Fixed in https://github.com/brython-dev/brython/commit/35d0a51aac5b0e69f5fa817033d12f4b4fd843d8 – jsbueno Apr 24 '20 at 12:47

2 Answers2

4

The same code works fine in CPython, so it's probably a Brython bug.

Python 3.7.6 (default, Dec 30 2019, 19:38:26)
[Clang 11.0.0 (clang-1100.0.33.16)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class A(object):
...     def __str__(self):
...         return "A __str__ output."
...
>>> class B(A):
...     def __str__(self):
...         return super().__str__() + " (from B)"
...
>>> x = A()
>>> x
<__main__.A object at 0x1048de590>
>>> y = B()
>>> y
<__main__.B object at 0x1048de790>
>>> str(y)
'A __str__ output. (from B)'
>>>
AKX
  • 152,115
  • 15
  • 115
  • 172
  • I thought that might be the case. The tool I'm using uses Brython, so I can't just switch over. – Kyle Apr 23 '20 at 13:48
  • 2
    Best report this as a bug then. https://github.com/brython-dev/brython/issues – AKX Apr 23 '20 at 13:50
  • 1
    Issue submitted: https://github.com/brython-dev/brython/issues/1366 Thanks for the link. – Kyle Apr 23 '20 at 14:09
  • 1
    The maintainer lready addressed the issue and commited a fix in https://github.com/brython-dev/brython/commit/35d0a51aac5b0e69f5fa817033d12f4b4fd843d8 – jsbueno Apr 24 '20 at 12:47
-1

It's not neccessarily a bug, it could also be implementation-specific behaviour. The behaviour of super() function has changed in Pyhton too so you would have to make sure to use the right form, and to test against a compatible implementation.

What is happening in your case is that you are printing a string representation of the proxy object returned by super() instead of calling __str__ on the actual parent object.

See here for more: https://docs.python.org/3/library/functions.html#super

jurez
  • 4,436
  • 2
  • 12
  • 20
  • This is a good point. My local Python version is 3.6.9. Is there a better way to call the super class's version of __str__? – Kyle Apr 23 '20 at 14:05
  • 1
    No, super() is the right way to go, but you might have to add a parameters base class and/or instance, like in `super(A).__str__()` (check the docs, I'm not sure). – jurez Apr 23 '20 at 14:07
  • 1
    I don't think this is implementation-specific. Not being able to call an upstream `__str__` method would break the very use case for which `super` was created. – chepner Apr 23 '20 at 14:12
  • 1
    Adding explicit arguments to `super` doesn't help, so it's not just an issue of the magic argument-supplying behavior being broken. – chepner Apr 23 '20 at 14:17
  • 1
    What happens if you try to call another method using super, such as `def my_str(self): return self.__str__()` and try to call `super().my_str()` or `super(A).my_str()`? Does this work? – jurez Apr 23 '20 at 14:31
  • 1
    If it works with other methods, but not just with `__str__`, it smells like a bug indeed. The workaround should be trivial, but for all future generations try to at least report it. – jurez Apr 23 '20 at 15:13
  • 1
    it is a bug. This use case of super() is trivial, docuemnted, and deterministic. -1 – jsbueno Apr 24 '20 at 12:45