You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
StringIO (I'm talking about io.StringIO in python3 and python2 and StringIO.stringIO in python2) doesn't have an attribute called name.
>>> h.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: StringIO instance has no attribute 'name'
However, we can set that attribute and assign it any value
>>> h.name = 4
>>> h.name
4
But according to typeshed, StringIO.StringIO is a subclass of IO[str] and io.StringIO is a subclass of IO[Text]. In typeshed, IO defines name using @property. So there's a getter for it but no setter. So according to typeshed, StringIO.name is readable (which is false until it is set it), but not writeable. This doesn't correspond to what happens at run-time.
Maybe we can write a setter for it in StringIO. I don't know whether mypy currently supports setters.
In some of zulip's tests, we're passing StringIO objects to functions which accept file-like objects. Since those functions (which are probably part of django) read name of the file-like objects, we have to set a suitable value of name for those file-like objects. But when we do that, mypy complains:
error: Property "name" defined in "StringIO" is read-only
File objects don't have a writable name attribute, so the IO stub seems reasonable. What seems to be going on is that StringIO does not fully implement the IO interface, but we declare it as a subclass of IO for convenience, since in most respects it acts like an IO object.
A somewhat correct fix would be to 'undefine' name in StringIO, but there's no standard way to do that. Defining it as a regular attribute seems like a lie, if it actually isn't defined. You can assign to an arbitrary attribute such as asdfasdf and Python will not complain. We want to be able to catch assignments to undefined attributes.
My suggestion is to use setattr to set the attribute, or to cast the StringIO object to Any before performing the manipulations, as this feels like something a type checker can't easily support without allowing genuinely bad code to pass type checking. But perhaps this is special and I'm missing something?
I have a similar issuee. What I'm trying to do is treat a cx_Oracle.CLOB value like a stream (which seems quite natural, only the LOB API is a bit different).
Note: Actually I only need the read method in my code.
The constructor fails with the exception
AttributeError: attribute 'encoding' of '_io._TextIOBase' objects is not writable
Having non-writable attributes seems somewhat un-pythonic to me.
Any ideas how specifying the encoding (for when the stream has to be written to a byte stream) can be accomplished?
Activity
JukkaL commentedon Oct 11, 2016
File objects don't have a writable
nameattribute, so theIOstub seems reasonable. What seems to be going on is thatStringIOdoes not fully implement theIOinterface, but we declare it as a subclass ofIOfor convenience, since in most respects it acts like anIOobject.A somewhat correct fix would be to 'undefine'
nameinStringIO, but there's no standard way to do that. Defining it as a regular attribute seems like a lie, if it actually isn't defined. You can assign to an arbitrary attribute such asasdfasdfand Python will not complain. We want to be able to catch assignments to undefined attributes.My suggestion is to use
setattrto set the attribute, or to cast theStringIOobject toAnybefore performing the manipulations, as this feels like something a type checker can't easily support without allowing genuinely bad code to pass type checking. But perhaps this is special and I'm missing something?gvanrossum commentedon Oct 11, 2016
sharmaeklavya2 commentedon Oct 11, 2016
For now I'm using this workaround in zulip's code:
gvanrossum commentedon Oct 11, 2016
Add attribute 'name' to StringIO
Add attribute 'name' to StringIO (#600)
hvbtup commentedon Dec 21, 2017
I have a similar issuee. What I'm trying to do is treat a cx_Oracle.CLOB value like a stream (which seems quite natural, only the LOB API is a bit different).
My attempt is like this:
Note: Actually I only need the read method in my code.
The constructor fails with the exception
AttributeError: attribute 'encoding' of '_io._TextIOBase' objects is not writable
Having non-writable attributes seems somewhat un-pythonic to me.
Any ideas how specifying the encoding (for when the stream has to be written to a byte stream) can be accomplished?
Update `_caller()` implementation (python#598)