ponty / PyVirtualDisplay

Python wrapper for Xvfb, Xephyr and Xvnc
BSD 2-Clause "Simplified" License
714 stars 78 forks source link

`Display.__repr__` raises `AttributeError` if invoked before `Display.start()` #10

Closed anthonywu closed 10 years ago

anthonywu commented 10 years ago

Reproduce

display = Display()
  # ... truncated stacktrace ...
/lib/python2.7/site-packages/easyprocess/__init__.pyc in __repr__(self)
    135         msg = '<%s cmd_param=%s alias={alias} cmd=%s ({scmd}) oserror=%s returncode=%s stdout="%s" stderr="%s" timeout=%s>' % (
    136             self.__class__.__name__,
--> 137             self.cmd_param,
    138             self.cmd,
    139             self.oserror,
AttributeError: Display instance has no attribute 'cmd_param'

Cause:

AbstractDisplay, being an instance of EasyProcess, does not define EasyProcess.cmd_param until EasyProcess. __init__ is invoked

I understand why you do not want to call EasyProcess. __init__ until AbstractDisplay.start(), but that leaves this edge case.

Proposed solutions

  1. in AbstractDisplay.__init__, set a dummy cmd_param attribute
  2. implement AbstractDisplay.__repr__ and handle the case where start() has not been invoked
  3. encourage use of displays in a context manager, e.g.
import contextlib
import pyvirtualdisplay

@contextlib.contextmanager
def virtual_display(*display_pargs, **display_kwargs):
  display = pyvirtualdisplay.Display(*display_pargs, **display_kwargs)
  display.start()
  yield
  display.stop()
ponty commented 10 years ago

Thanks for the bug report!

anthonywu commented 10 years ago

You bet. Appreciate the fix!