Skip to content
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

Overriding sys.stdin causes errors in processes that actually uses attributes of sys.stdin #21

Open
MarounMaroun opened this issue Jan 9, 2017 · 14 comments

Comments

@MarounMaroun
Copy link

In one of my projects I used sys.stdin.encoding, but since in this project we have:

sys.stdout = sys.stdin = handle

I got an exception during runtime.

Can we have a default values for that attribute (or even have the ability to pass its attribute in the constructor)?

(I can submit a PR if it's relevant)

@MarounMaroun MarounMaroun changed the title Overriding sys.stdin cause errors in processes that actually uses attributes of sys.stdin Overriding sys.stdin causes errors in processes that actually uses attributes of sys.stdin Jan 11, 2017
@dougszumski
Copy link

dougszumski commented May 2, 2017

+1 for a default. I'm using rpdb to debug an OpenStack service which uses oslo.utils. oslo.utils has the following:

> /usr/lib/python2.7/site-packages/oslo_utils/encodeutils.py(39)safe_decode() 
-> incoming = (sys.stdin.encoding or                                          
(Pdb) l                                                                       
 34                                                                           
 35         if isinstance(text, six.text_type):                               
 36             return text                                                   
 37                                                                           
 38         if not incoming:                                                  
 39  ->         incoming = (sys.stdin.encoding or                             
 40                         sys.getdefaultencoding())                         
 41                                                                           
 42         try:                                                              
 43             return text.decode(incoming, errors)                          
 44         except UnicodeDecodeError:                                        
(Pdb) type(sys.stdin)                                                         
<class 'rpdb.FileObjectWrapper'>

When this executes I see the following error:

AttributeError: "'_fileobject' object has no attribute 'encoding'"

The code runs fine outside rpdb because sys.stdin.encoding is defined.

@MarounMaroun
Copy link
Author

@dougszumski Well, that's exactly what I'm having now (also while debugging an OpenStack service). A workaround would be adding the encoding attribute to sys.stdin just a line before it breaks.

I'm still waiting for a response from OP before submitting my PR.

@tamentis
Copy link
Owner

tamentis commented May 3, 2017

Yes that makes sense, I'll gladly review that PR.

@tamentis
Copy link
Owner

I'm not sure how this is happening since the point of rpdb.FileObjectWrapper is to allow you to access properties such as encoding.

@MarounMaroun are you using 0.1.6?

@dougszumski could you check the type of sys.stdin._io and sys.stdin._obj?

@MarounMaroun
Copy link
Author

@tamentis Yes, I'm on 0.1.6.

@MarounMaroun
Copy link
Author

@tamentis The solution should look something like this, can you please take a look?

@dougszumski FYI.

@dougszumski
Copy link

dougszumski commented May 16, 2017

Here's a bit more info:

> /usr/lib/python2.7/site-packages/oslo_utils/encodeutils.py(38)safe_decode()
-> if not incoming:
(Pdb) l
 33             raise TypeError("%s can't be decoded" % type(text))
 34
 35         if isinstance(text, six.text_type):
 36             return text
 37         import rpdb; rpdb.set_trace()
 38  ->     if not incoming:
 39             incoming = (sys.stdin.encoding or
 40                         sys.getdefaultencoding())
 41
 42         try:
 43             return text.decode(incoming, errors)
(Pdb) rpdb.__version__
'0.1.6'
(Pdb) sys.stdin._io
<open file '<stdin>', mode 'r' at 0x7f2d6d3720c0>
(Pdb) sys.stdin._obj
<socket._fileobject object at 0x239d450>
(Pdb) sys.stdin.encoding
'UTF-8'
(Pdb) n
> /usr/lib/python2.7/site-packages/oslo_utils/encodeutils.py(39)safe_decode()
-> incoming = (sys.stdin.encoding or
(Pdb)
AttributeError: "'_fileobject' object has no attribute 'encoding'"
> /usr/lib/python2.7/site-packages/oslo_utils/encodeutils.py(39)safe_decode()
-> incoming = (sys.stdin.encoding or
(Pdb) sys.stdin.encoding
'UTF-8'
(Pdb) sys.getdefaultencoding()
'ascii'

@dougszumski
Copy link

dougszumski commented May 16, 2017

Ah, I think I see what's happening:

> /usr/lib/python2.7/site-packages/oslo_utils/encodeutils.py(38)safe_decode()
-> if not incoming:
(Pdb) l
 33             raise TypeError("%s can't be decoded" % type(text))
 34
 35         if isinstance(text, six.text_type):
 36             return text
 37         import rpdb; rpdb.set_trace()
 38  ->     if not incoming:
 39             incoming = (sys.stdin.encoding or
 40                         sys.getdefaultencoding())
 41
 42         try:
 43             return text.decode(incoming, errors)
(Pdb) sys.stdin._obj
<socket._fileobject object at 0x1a2a450>
(Pdb) sys.stdin._obj.encoding
*** AttributeError: '_fileobject' object has no attribute 'encoding'
(Pdb) sys.stdin._io.encoding
'UTF-8'

Looks like this happens in FileObjectWrapper:

class FileObjectWrapper(object):
    def __init__(self, fileobject, stdio):
        self._obj = fileobject
        self._io = stdio

    def __getattr__(self, attr):
        if hasattr(self._obj, attr):
            attr = getattr(self._obj, attr)
        elif hasattr(self._io, attr):
            attr = getattr(self._io, attr)
        else:
            raise AttributeError("Attribute %s is not found" % attr)
        return attr

@MarounMaroun
Copy link
Author

@dougszumski good point. So the solution I suggested didn't work for you?

@Boris-Barboris
Copy link

Why was stdin\out assignment needed in the first place? I just commented them out and everything worked fine.

@MarounMaroun
Copy link
Author

@Boris-Barboris Which lines did you comment out?

Akrog added a commit to Akrog/rpdb that referenced this issue Apr 19, 2018
On commit 9c9d4f4 we added a wrapper to
provide missing parameters (ie: `encoding`) in the object returned by
`makefile`, unfortunately this didn't resolve all problems, as there are
some cases, like in method oslo_utils.encodeutils.safe_decode where when
accessing sys.stdin.encoding we would still get an error:

  AttributeError: "'_fileobject' object has no attribute 'encoding'"

This patch fixes this issue and allows us to set the encoding when
instantiating the Rpdb object.

The way this has been fixed depends on the Python version:

- For python 2 we extend _fileobject and add `errors` and `encoding`
  variables as well as the `isatty` method.

- For python 3 we pass `encoding` to the `makefile` call and then create
  class attributes `errors` and `isatty` (since we cannot modify the
  instance itself).
@airborne007
Copy link

Hi, everyone, is this problem solved?
I also encountered this problem when debugging the OpenStack project.

@MarounMaroun
Copy link
Author

@airborne007 Not yet. The current solution is to add encoding attribute to sys.stdin just a line before it breaks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants