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

leaking internal exeptions #1402

Closed
arekm opened this issue Feb 3, 2019 · 7 comments
Closed

leaking internal exeptions #1402

arekm opened this issue Feb 3, 2019 · 7 comments
Labels

Comments

@arekm
Copy link

arekm commented Feb 3, 2019

The problem is that with psutil (5.4.2) I'm getting some, internal, I guess, exceptions which shouldn't be visible externally, right? For example I'm getting psutil._exceptions.NoSuchProcess while documented is psutil.NoSuchProcess

Traceback (most recent call last):
  File "/usr/lib64/python3.6/site-packages/psutil/_pslinux.py", line 1390, in wrapper
    return fun(self, *args, **kwargs)
  File "/usr/lib64/python3.6/site-packages/psutil/_pslinux.py", line 1965, in uids
    data = self._read_status_file()
  File "/usr/lib64/python3.6/site-packages/psutil/_common.py", line 337, in wrapper
    return fun(self)
  File "/usr/lib64/python3.6/site-packages/psutil/_pslinux.py", line 1445, in _read_status_file
    with open_binary("%s/%s/status" % (self._procfs_path, self.pid)) as f:
  File "/usr/lib64/python3.6/site-packages/psutil/_pslinux.py", line 187, in open_binary
    return open(fname, "rb", **kwargs)
FileNotFoundError: [Errno 2] No such file or directory: '/proc/27862/status'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "myscript.py", line 72, in <module>
    process_pureftpd(pureftpd_pid)
  File "myscript.py", line 55, in process_pureftpd
    r_uid, e_uid, s_uid = p.uids()
  File "/usr/lib64/python3.6/site-packages/psutil/_common.py", line 337, in wrapper
    return fun(self)
  File "/usr/lib64/python3.6/site-packages/psutil/__init__.py", line 722, in uids
    return self._proc.uids()
  File "/usr/lib64/python3.6/site-packages/psutil/_pslinux.py", line 1401, in wrapper
    raise NoSuchProcess(self.pid, self._name)
psutil._exceptions.NoSuchProcess: psutil.NoSuchProcess process no longer exists (pid=27862)
@giampaolo
Copy link
Owner

Yes, the __repr__ is incorrect, but catching psutil.NoSuchProcess works, so it's a cosmetic fix.

@giampaolo giampaolo added the bug label Feb 3, 2019
@giampaolo
Copy link
Owner

giampaolo commented Feb 3, 2019

Change was introduced in fe68b30.
It's weird because back then I remember having verified that __repr__ was OK. I'd rather keep those classes under psutil/_exceptions.py but if I can't come up with a solution to fix __repr__ then I'll just move them back into psutil/__init__.py

@giampaolo
Copy link
Owner

@wiggin15 any comment on this (it's related to #1174)?

@wiggin15
Copy link
Collaborator

wiggin15 commented Feb 4, 2019

I'm afraid I'm not sure where this (original) name of the exception is coming from. Our repr works on an instance, but not on the class:

>>> repr(psutil.Error())
'psutil.Error'
>>> repr(psutil.Error)
"<class 'psutil._exceptions.Error'>"

We can override the repr of the class too using a metaclass, but that doesn't appear to solve the problem.
We might be missing some other magic method where the name comes from?

In any case, I think we can simply rename _exceptions.py to exceptions.py - IMHO having psutil.exceptions.NoSuchProcess looks ok.

@giampaolo
Copy link
Owner

giampaolo commented Feb 4, 2019

I just moved the exceptions classes back into __init__.py.

@embray
Copy link
Contributor

embray commented Apr 10, 2019

The reason setting __repr__ doesn't work around this is that it doesn't factor into the way tracebacks are formatted in this way (since indeed it's using the class in traceback formatting and not the exception instance).

If it's really important for it to be displayed as psutil.Error one way to do that, which should work on both Python 2 and 3, would be:

class Error(Exception):
    __module__ = 'psutil'

it's a bit of a hack but perfectly well-supported (especially since the class is imported into the top-level module namespace anyways).

@embray
Copy link
Contributor

embray commented Apr 10, 2019

BTW the relevant logic for this can be seen in in traceback.format_exception_only():

>>> import traceback
>>> class Whatever(Exception): pass
...
>>> traceback.format_exception_only(Whatever, Whatever('oops'))
['Whatever: oops\n']
>>> class Whatever(Exception):
...     __module__ = 'psutil'
...
>>> traceback.format_exception_only(Whatever, Whatever('oops'))
['psutil.Whatever: oops\n']

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

No branches or pull requests

4 participants