Fix `__str__` call for all Python objects
https://github.com/bruderstein/PythonScript/blob/52f7d7b3745ebd629ff4549365b13aac4c813c95/PythonScript/src/ScintillaWrapper.cpp#L61
Naively calling __str__() on an object assumes it is bound, which is not the case for non-instantiated classes.
Would it be possible to use Python's str builtin?
Can you explain when this is a problem when using PythonScript?
Can you explain when this is a problem when using PythonScript?
Let's take editor.write for example. Its C++ signature expects a boost::python::api::object.
As I understand, we can pass any Python object and you convert it to string via ScintillaWrapper::getStringFromObject by calling o.__str__().
This works because you usually pass an instantiated class object, meaning you don't need to manually pass self to its methods (like __str__), so a call without arguments works.
But it breaks if you pass an uninstantiated class object (class itself). It doesn't bind self, so it expects you to pass something to the __str__ method.
>>> editor.write('text') # 'text'.__str__() == 'text'
>>> editor.write(42) # (42).__str__() == '42'
So far it looks fine with instances of str and int class (return values are omitted for brevity). Let's try a custom class.
>>> class Foo:
... def __str__(self):
... return __class__.__name__.lower()
...
>>> editor.write(Foo()) # Foo().__str__() == 'foo'
>>> editor.write(Foo) # There is no `self` to auto insert into the `__str__` call.
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: Foo.__str__() missing 1 required positional argument: 'self'
One might expect the value of str(Foo) to be written into the editor, but it wants us to pass something to __str__.
P.S. In this example str(Foo) == "<class '__main__.Foo'>". Not the most common use case, but you never know what the user is up to!
>>> class Meta(type):
... def __str__(cls):
... return cls.__name__.upper()
...
>>> class Bar(metaclass=Meta):
... pass
...
>>> str(Bar)
'BAR'
>>> editor.write(Bar)
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: descriptor '__str__' of 'object' object needs an argument
I understand what you mean, but usually PythonScript is used to manipulate Notepad++, Scintilla and the buffer content, but
but you never know what the user is up to!
I guess you're right
This isn't high priority, or might not even get addressed. Regardless, it is a bug so I had to bring it to your attention.