diff --git a/.gitignore b/.gitignore index 07faf391..189d19a9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ wingdbstub.py* mydbstub.py* .idea +.cache /build /tmp diff --git a/TODO.rst b/TODO.rst index ae196ad8..4e609bb0 100644 --- a/TODO.rst +++ b/TODO.rst @@ -209,5 +209,9 @@ Other Dev Stuff etc. work with properties? See: https://groups.google.com/d/msg/wxpython-dev/dMrpaKs_d0U/nVMY7lMvAwAJ + * In test_lib_agw_persist_persistencemanager.py change the tests to be + self-contained instead of some relying on files generated by others. This + won't work if we want to run tests in parallel. + diff --git a/build.py b/build.py index 13ee0024..04e35317 100755 --- a/build.py +++ b/build.py @@ -167,6 +167,10 @@ def main(args): msg('cfg.VERSION: %s' % cfg.VERSION) msg('') + # For collecting test names or files, to be run after all have been pulled + # off the command line + test_names = [] + while commands: # ensure that each command starts with the CWD being the phoenix dir. os.chdir(phoenixDir()) @@ -174,21 +178,21 @@ def main(args): if not cmd: continue # ignore empty command-line args (possible with the buildbot) elif cmd.startswith('test_'): - testOne(cmd, options, args) + test_names.append('unittests/%s.py' % cmd) elif cmd.startswith('unittests/test_'): - testOne(os.path.basename(cmd), options, args) + test_names.append(cmd) elif 'cmd_'+cmd in globals(): function = globals()['cmd_'+cmd] function(options, args) - if cmd == 'test': - # Any additional cmd-line args are assumed to be tests, which - # will have already been taken care of, so bail out of the - # loop. - break else: print('*** Unknown command: ' + cmd) usage() sys.exit(1) + + # Now run the collected tests names, if any + if test_names: + cmd_test(options, args, test_names) + msg("Done!") @@ -402,14 +406,15 @@ def makeOptionParser(): ("prefix", ("", "Prefix value to pass to the wx build.")), ("destdir", ("", "Installation root for wxWidgets, files will go to {destdir}/{prefix}")), - ("extra_setup", ("", "Extra args to pass on setup.py's command line.")), - ("extra_make", ("", "Extra args to pass on [n]make's command line.")), - ("extra_waf", ("", "Extra args to pass on waf's command line.")), + ("extra_setup", ("", "Extra args to pass on setup.py's command line.")), + ("extra_make", ("", "Extra args to pass on [n]make's command line.")), + ("extra_waf", ("", "Extra args to pass on waf's command line.")), + ("extra_pytest", ("", "Extra args to pass on py.test's command line.")), - ("jobs", ("", "Number of parallel compile jobs to do, if supported.")), + (("j","jobs"), ("", "Number of parallel compile jobs to do, if supported.")), ("both", (False, "Build both a debug and release version. (Only used on Windows)")), ("unicode", (True, "Build wxPython with unicode support (always on for wx2.9+)")), - ("verbose", (False, "Print out more information.")), + (("v", "verbose"), (False, "Print out more information during the build.")), ("nodoc", (False, "Do not run the default docs generator")), ("upload", (False, "Upload bdist and/or sdist packages to snapshot server.")), ("cairo", (False, "Allow Cairo use with wxGraphicsContext (Windows only)")), @@ -417,6 +422,8 @@ def makeOptionParser(): ("jom", (False, "Use jom instead of nmake for the wxMSW build")), ("relwithdebug", (False, "Turn on the generation of debug info for release builds on MSW.")), ("release_build", (False, "Turn off some development options for a release build.")), + ("pytest_timeout", ("0", "Timeout, in seconds, for stopping stuck test cases. (Currently not working as expected, so disabled by default.)")), + ("pytest_jobs", ("", "Number of parallel processes py.test should run")), ] parser = optparse.OptionParser("build options:") @@ -425,8 +432,14 @@ def makeOptionParser(): action = 'store' if type(default) == bool: action = 'store_true' - parser.add_option('--'+opt, default=default, action=action, - dest=opt, help=txt) + if isinstance(opt, str): + opts = ('--'+opt, ) + dest = opt + else: + opts = ('-'+opt[0], '--'+opt[1]) + dest = opt[1] + parser.add_option(*opts, default=default, action=action, + dest=dest, help=txt) return parser @@ -1043,28 +1056,37 @@ def cmd_touch(options, args): -def cmd_test(options, args): +def cmd_test(options, args, tests=None): + # Run all tests cmdTimer = CommandTimer('test') pwd = pushDir(phoenixDir()) - cmd = '"%s" unittests/runtests.py %s ' % (PYTHON, '-v' if options.verbose else '') - if len(args) > 1: - if options.verbose: - args.remove('--verbose') - cmd += ' '.join(args[1:]) + + # --boxed runs each test in a new process (only for posix *&##$#@$^!!) + # -n is the number of processes to run in parallel + # --timeout will kill the test process if it gets stuck + jobs = '-n{}'.format(options.pytest_jobs) if options.pytest_jobs else '' + boxed = '--boxed' if not isWindows else '' + sec = options.pytest_timeout + timeout = '--timeout={}'.format(sec) if sec and sec != "0" else '' + cmd = '"{}" -m pytest {} {} {} {} {} '.format( + PYTHON, + '-v' if options.verbose else '', + boxed, + jobs, + timeout, + options.extra_pytest) + + if not tests: + # let pytest find all tests in the unittest folder + cmd += 'unittests' + else: + # otherwise, run only the test modules given + cmd += ' '.join(tests) + runcmd(cmd, fatal=False) - - -def testOne(name, options, args): - cmdTimer = CommandTimer('test %s:' % name) - pwd = pushDir(phoenixDir()) - if name.endswith('.py') or name.endswith('.pyc'): - i = name.rfind('.') - name = name[:i] - runcmd('"%s" unittests/%s.py %s' % (PYTHON, name, '-v' if options.verbose else ''), fatal=True) - def cmd_build(options, args): cmdTimer = CommandTimer('build') cmd_build_wx(options, args) diff --git a/requirements.txt b/requirements.txt index 8a67b7d6..de941e58 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,10 @@ -# Phoenix build requirements -setuptools == 20.2.2 -six == 1.10.0 -wheel == 0.29.0 -twine==1.6.5 -Pygments == 2.1.3 -alabaster == 0.7.8 -babel == 2.3.4 -imagesize == 0.7.1 -pytz == 2016.4 -sphinx == 1.4.1 -docutils == 0.12 -Jinja2 == 2.8 -MarkupSafe == 0.23 -requests == 2.10.0 - +# Phoenix build and test requirements +setuptools +six +wheel +twine +sphinx +requests +pytest +pytest-xdist +pytest-timeout diff --git a/unittests/do-runtests.py b/unittests/do-runtests.py deleted file mode 100644 index 0f3adec1..00000000 --- a/unittests/do-runtests.py +++ /dev/null @@ -1,70 +0,0 @@ -#--------------------------------------------------------------------------- -# Name: unittests/do-runtests.py -# Author: Robin Dunn -# -# Created: 6-Aug-2012 -# Copyright: (c) 2013 by Total Control Software -# License: wxWindows License -#--------------------------------------------------------------------------- - -""" -Run the unittests given on the command line while using a custom TestResults -class, and output the results in a format that can be integrated into another -TestResults (in the calling process.) See runtests.py for more information -and also for the code that calls this script via subprocess. -""" - -import sys -import os -import unittest -import six -import pickle - -g_testResult = None - -# make sure the phoenix dir is on the path -if os.path.dirname(__file__): - phoenixDir = os.path.abspath(os.path.dirname(__file__)+'/..') -else: # run as main? - d = os.path.dirname(sys.argv[0]) - if not d: d = '.' - phoenixDir = os.path.abspath(d+'/..') -sys.path.insert(0, phoenixDir) - - -class MyTestResult(unittest.TextTestResult): - def stopTestRun(self): - self.output = self.stream.getvalue() - - def getResultsMsg(self): - def fixList(src): - return [(self.getDescription(test), err) for test, err in src] - msg = dict() - msg['output'] = self.output - msg['testsRun'] = self.testsRun - msg['failures'] = fixList(self.failures) - msg['errors'] = fixList(self.errors) - msg['skipped'] = fixList(self.skipped) - msg['expectedFailures'] = fixList(self.expectedFailures) - msg['unexpectedSuccesses'] = fixList(self.unexpectedSuccesses) - return msg - - -class MyTestRunner(unittest.TextTestRunner): - def _makeResult(self): - global g_testResult - if g_testResult is None: - self.stream = unittest.runner._WritelnDecorator(six.StringIO()) - g_testResult = MyTestResult(self.stream, self.descriptions, self.verbosity) - return g_testResult - - -if __name__ == '__main__': - unittest.main(module=None, exit=False, testRunner=MyTestRunner) - msg = g_testResult.getResultsMsg() - text = pickle.dumps(msg) - if six.PY3: - sys.stdout.buffer.write(text) - else: - sys.stdout.write(text) - \ No newline at end of file diff --git a/unittests/runtests.py b/unittests/runtests.py deleted file mode 100755 index 295f55ea..00000000 --- a/unittests/runtests.py +++ /dev/null @@ -1,164 +0,0 @@ -#--------------------------------------------------------------------------- -# Name: unittests/runtests.py -# Author: Robin Dunn -# -# Created: 3-Dec-2010 -# Copyright: (c) 2010 by Total Control Software -# License: wxWindows License -#--------------------------------------------------------------------------- - -""" -This script will find and run all of the Phoenix test cases. We use a custom -TestSuite and other customized unittest classes so we can run each test -module in a separate process. This helps to isolate the test cases from each -other so they don't stomp on each other too much. - -Currently the process granularity is the TestSuite created when the tests in -a single module are loaded, which makes it essentially the same as when -running that module standalone. More granularity is possible by using -separate processes for each TestCase.testMethod, but I haven't seen the need -for that yet. - -See do-runtests.py for the script that is run in the child processes. -""" - - -import sys -import os -import glob -import subprocess -import unittest - -# make sure the phoenix dir is on the path -if os.path.dirname(__file__): - phoenixDir = os.path.abspath(os.path.dirname(__file__)+'/..') -else: # run as main? - d = os.path.dirname(sys.argv[0]) - if not d: d = '.' - phoenixDir = os.path.abspath(d+'/..') -sys.path.insert(0, phoenixDir) - -import wx -import six -print("wx.version: " + wx.version()) -print("pid: " + str(os.getpid())) -#print("executable: " + sys.executable); raw_input("Press Enter...") - -from unittests import wtc - -#--------------------------------------------------------------------------- - -def getTestName(test): - cls = test.__class__ - return "%s.%s.%s" % (cls.__module__, cls.__name__, test._testMethodName) - - -class MyTestSuite(unittest.TestSuite): - """ - Override run() to run the TestCases in a new process. - """ - def run(self, result, debug=False): - if self._tests and isinstance(self._tests[0], unittest.TestSuite): - # self is a suite of suites, recurse down another level - return unittest.TestSuite.run(self, result, debug) - elif self._tests and not isinstance(self._tests[0], wtc.WidgetTestCase): - # we can run normal test cases in this process - return unittest.TestSuite.run(self, result, debug) - else: - # Otherwise we want to run these tests in a new process, - # get the names of all the test cases in this test suite - testNames = list() - for test in self: - name = getTestName(test) - testNames.append(name) - - # build the command to be run - PYTHON = os.environ.get('PYTHON', sys.executable) - runner = os.path.join(phoenixDir, 'unittests', 'do-runtests.py') - cmd = [PYTHON, '-u', runner] - if result.verbosity > 1: - cmd.append('--verbose') - elif result.verbosity < 1: - cmd.append('--quiet') - cmd += testNames - - # run it - sp = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE)#, stderr=subprocess.STDOUT) - output = sp.stdout.read() - #if sys.version_info > (3,): - # output = output.decode('ascii') - output = output.rstrip() - rval = sp.wait() - sp.stdout.close() - if rval: - print("Command '%s' failed with exit code %d." % (cmd, rval)) - sys.exit(rval) - - # Unpickle the output and copy it to result. It should be a - # dictionary with info from the TestResult class used in the - # child process. - import pickle - msg = pickle.loads(output) - result.stream.write(msg['output']) - result.stream.flush() - result.testsRun += msg['testsRun'] - result.failures += msg['failures'] - result.errors += msg['errors'] - result.skipped += msg['skipped'] - result.expectedFailures += msg['expectedFailures'] - result.unexpectedSuccesses += msg['unexpectedSuccesses'] - - return result - - - -class MyTestResult(unittest.TextTestResult): - def __init__(self, stream, descriptions, verbosity): - super(MyTestResult, self).__init__(stream, descriptions, verbosity) - self.verbosity = verbosity - - def getDescription(self, test): - """ - Override getDescription() to be able to deal with the test already - being converted to a string. - """ - if isinstance(test, six.string_types): - return test - return super(MyTestResult, self).getDescription(test) - - - -class MyTestLoader(unittest.TestLoader): - suiteClass = MyTestSuite - -class MyTestRunner(unittest.TextTestRunner): - resultclass = MyTestResult - -#--------------------------------------------------------------------------- - -if __name__ == '__main__': - if '--single-process' in sys.argv: - sys.argv.remove('--single-process') - args = sys.argv[:1] + 'discover -p test_*.py -s unittests -t .'.split() + sys.argv[1:] - unittest.main(argv=args) - - else: - # The discover option doesn't use my my custom loader or suite - # classes, so we'll do the finding of the test files in this case. If - # there aren't already some in argv then get all of them in unittests - # folder. - for arg in sys.argv[1:]: - if arg.startswith('unittests'): - names = sys.argv[1:] - sys.argv = sys.argv[:1] - break - else: - names = glob.glob(os.path.join('unittests', 'test_*.py')) - - names = [os.path.splitext(os.path.basename(n))[0] for n in names] - args = sys.argv + names - - unittest.main(argv=args, module=None, - testRunner=MyTestRunner, testLoader=MyTestLoader()) - - diff --git a/unittests/test_arraystring.py b/unittests/test_arraystring.py index a31b1506..4f250aa4 100644 --- a/unittests/test_arraystring.py +++ b/unittests/test_arraystring.py @@ -1,7 +1,5 @@ import unittest import wx -from unittests import wtc -import sys import six #--------------------------------------------------------------------------- diff --git a/unittests/test_dataview.py b/unittests/test_dataview.py index 4214ef9d..a34d6ebe 100644 --- a/unittests/test_dataview.py +++ b/unittests/test_dataview.py @@ -1,7 +1,7 @@ import unittest from unittests import wtc import wx -from wx.lib import six +import six import wx.dataview as dv import os diff --git a/unittests/test_eventfilter.py b/unittests/test_eventfilter.py index 060633d2..9b422bbe 100644 --- a/unittests/test_eventfilter.py +++ b/unittests/test_eventfilter.py @@ -1,4 +1,5 @@ -import unittest, wtc +import unittest +from unittests import wtc import wx diff --git a/unittests/test_lib_agw_persist_persistencemanager.py b/unittests/test_lib_agw_persist_persistencemanager.py index 9dcb4b11..88b162b5 100644 --- a/unittests/test_lib_agw_persist_persistencemanager.py +++ b/unittests/test_lib_agw_persist_persistencemanager.py @@ -10,14 +10,17 @@ import wx.lib.agw.persist as PM class lib_agw_persist_persistencemanager_Tests(wtc.WidgetTestCase): - def test_lib_agw_persist_persistencemanagerCtor(self): + def setUp(self): + super(lib_agw_persist_persistencemanager_Tests, self).setUp() + dirName = os.path.dirname(os.path.abspath(__file__)) + self._configFile1 = os.path.join(dirName, "PersistTest1") + + + def test_persistencemanagerCtor(self): self._persistMgr = PM.PersistenceManager.Get() self._persistMgr.SetManagerStyle(PM.PM_SAVE_RESTORE_AUI_PERSPECTIVES) - - dirName, fileName = os.path.split(os.path.abspath(__file__)) - _configFile1 = os.path.join(dirName, "PersistTest1") - self._persistMgr.SetPersistenceFile(_configFile1) + self._persistMgr.SetPersistenceFile(self._configFile1) # give the frame a Name for below self.frame.SetName('PersistTestFrame') @@ -30,13 +33,10 @@ class lib_agw_persist_persistencemanager_Tests(wtc.WidgetTestCase): self._persistMgr.SaveAndUnregister() - def test_lib_agw_persist_persistencemanagerRestore(self): + def test_persistencemanagerRestore(self): self._persistMgr = PM.PersistenceManager.Get() - - dirName, fileName = os.path.split(os.path.abspath(__file__)) - _configFile1 = os.path.join(dirName, "PersistTest1") - self._persistMgr.SetPersistenceFile(_configFile1) + self._persistMgr.SetPersistenceFile(self._configFile1) # give the frame a Name for below self.frame.SetName('PersistTestFrame') @@ -45,14 +45,12 @@ class lib_agw_persist_persistencemanager_Tests(wtc.WidgetTestCase): self.assertEqual(self._persistMgr.HasRestored(), True, "Persistence should be there, as it was created in CTOR test.") - def test_lib_agw_persist_persistencemanagerPersistValue(self): + + def test_persistencemanagerPersistValue(self): self._persistMgr = PM.PersistenceManager.Get() self._persistMgr.SetManagerStyle(PM.PM_SAVE_RESTORE_AUI_PERSPECTIVES) - - dirName, fileName = os.path.split(os.path.abspath(__file__)) - _configFile1 = os.path.join(dirName, "PersistTest1") - self._persistMgr.SetPersistenceFile(_configFile1) + self._persistMgr.SetPersistenceFile(self._configFile1) # give the frame a Name for below self.frame.SetName('PersistTestFrame') @@ -65,7 +63,14 @@ class lib_agw_persist_persistencemanager_Tests(wtc.WidgetTestCase): self.assertEqual(cb.GetValue(), False, "Should be False as set in CTOR test") - def test_lib_agw_persist_persistencemanagerConstantsExist(self): + def test_persistencemanagerZZZZCleanup(self): + # Just clean up the test file used by the other tests... + # TODO: Fix these tests to be self-contained and to clean up after themselves + if os.path.exists(self._configFile1): + os.unlink(self._configFile1) + + + def test_persistencemanagerConstantsExist(self): # PersistenceManager styles PM.PM_SAVE_RESTORE_AUI_PERSPECTIVES PM.PM_SAVE_RESTORE_TREE_LIST_SELECTIONS diff --git a/unittests/test_pyevent.py b/unittests/test_pyevent.py index 557c6b87..9726f1ab 100644 --- a/unittests/test_pyevent.py +++ b/unittests/test_pyevent.py @@ -1,5 +1,6 @@ import sys -import unittest, wtc +import unittest +from unittests import wtc import wx ##import os; print 'PID:', os.getpid(); raw_input('Ready to start, press enter...') diff --git a/unittests/test_uiaction.py b/unittests/test_uiaction.py index b7072c27..67e85a5d 100644 --- a/unittests/test_uiaction.py +++ b/unittests/test_uiaction.py @@ -19,7 +19,7 @@ class MouseEventsPanel(wx.Panel): def onMouseEvent(self, evt): self.events.append( (evt.EventType, evt.Position) ) - #print(self.events) + print( (evt.EventType, evt.Position) ) evt.Skip() @@ -56,7 +56,7 @@ class uiaction_MouseTests(wtc.WidgetTestCase): uia.MouseMove(p.ClientToScreen((10,10)).x, p.ClientToScreen((10,10)).y) self.waitFor(WAIT) self.waitFor(WAIT) - + self.assertEqual(len(p.events), 3) self.assertTrue(self.cmp(p.events[0], wx.wxEVT_MOTION, (1,1))) self.assertTrue(self.cmp(p.events[1], wx.wxEVT_MOTION, (5,5))) @@ -105,7 +105,6 @@ class uiaction_MouseTests(wtc.WidgetTestCase): self.assertTrue(len(p.events) == 2) self.assertTrue(self.cmp(p.events[0], wx.wxEVT_LEFT_DOWN, (10,10))) self.assertTrue(self.cmp(p.events[1], wx.wxEVT_LEFT_UP, (10,10))) - def test_uiactionMouseLeftDClick(self): @@ -123,8 +122,7 @@ class uiaction_MouseTests(wtc.WidgetTestCase): self.assertTrue(self.cmp(p.events[2], (wx.wxEVT_LEFT_DOWN, wx.wxEVT_LEFT_DCLICK), (10,10))) self.assertTrue(self.cmp(p.events[3], wx.wxEVT_LEFT_UP, (10,10))) - - + def test_uiactionMouseDD(self): p = MouseEventsPanel(self.frame, [wx.EVT_MOTION, wx.EVT_LEFT_DOWN, wx.EVT_LEFT_UP]) @@ -150,10 +148,12 @@ class uiaction_KeyboardTests(wtc.WidgetTestCase): def setUp(self): super(uiaction_KeyboardTests, self).setUp() - self.tc = wx.TextCtrl(self.frame) + pnl = wx.Panel(self.frame) + pnl.SetBackgroundColour('pink') + self.tc = wx.TextCtrl(pnl) self.tc.SetFocus() self.waitFor(WAIT) - + def test_uiactionKeyboardKeyDownUp(self): uia = wx.UIActionSimulator() @@ -169,7 +169,7 @@ class uiaction_KeyboardTests(wtc.WidgetTestCase): self.assertEqual(self.tc.GetValue(), "This is a test") - @unittest.skipIf(sys.platform == 'darwin', 'wx.UIActionSimulator.Char needs work...') + @unittest.skipIf(sys.platform == 'darwin', 'wx.UIActionSimulator.Char needs work...') def test_uiactionKeyboardChar(self): uia = wx.UIActionSimulator() for c in "This is a test": diff --git a/unittests/test_xrc.py b/unittests/test_xrc.py index 012592cc..c1065a1c 100644 --- a/unittests/test_xrc.py +++ b/unittests/test_xrc.py @@ -27,8 +27,6 @@ class xrc_Tests(wtc.WidgetTestCase): self.assertTrue(isinstance(ctrl, wx.StaticText)) - - def test_xrc1(self): xmlres = xrc.XmlResource(xrcFile) self.checkXmlRes(xmlres) @@ -236,7 +234,7 @@ class xrc_Tests(wtc.WidgetTestCase): resource = b''' - + 200,100 @@ -255,7 +253,7 @@ class xrc_Tests(wtc.WidgetTestCase): self.myYield() self.assertNotEqual(panel, None) - import xrcfactorytest + from unittests import xrcfactorytest self.assertTrue(isinstance(panel, xrcfactorytest.MyCustomPanel)) diff --git a/unittests/wtc.py b/unittests/wtc.py index d6873af3..17ffb1f4 100644 --- a/unittests/wtc.py +++ b/unittests/wtc.py @@ -17,15 +17,21 @@ class WidgetTestCase(unittest.TestCase): wx.Log.SetActiveTarget(wx.LogStderr()) self.frame = wx.Frame(None, title='WTC: '+self.__class__.__name__) self.frame.Show() + self.frame.PostSizeEvent() def tearDown(self): def _cleanup(): for tlw in wx.GetTopLevelWindows(): if tlw: - tlw.Destroy() + if isinstance(tlw, wx.Dialog) and tlw.IsModal(): + tlw.EndModal(0) + wx.CallAfter(tlw.Destroy) + else: + tlw.Close(force=True) wx.WakeUpIdle() - #self.app.ExitMainLoop() - wx.CallLater(50, _cleanup) + + timer = wx.PyTimer(_cleanup) + timer.Start(100) self.app.MainLoop() del self.app diff --git a/wx/lib/floatcanvas/FCObjects.py b/wx/lib/floatcanvas/FCObjects.py index 30808aa9..1e051f95 100644 --- a/wx/lib/floatcanvas/FCObjects.py +++ b/wx/lib/floatcanvas/FCObjects.py @@ -17,7 +17,7 @@ This is where FloatCanvas defines its drawings objects. import sys import wx -from wx.lib import six +import six import numpy as N diff --git a/wx/lib/floatcanvas/FloatCanvas.py b/wx/lib/floatcanvas/FloatCanvas.py index 850feb06..c627d690 100644 --- a/wx/lib/floatcanvas/FloatCanvas.py +++ b/wx/lib/floatcanvas/FloatCanvas.py @@ -50,7 +50,7 @@ mac = sys.platform.startswith("darwin") import numpy as N from time import clock import wx -from wx.lib import six +import six from .FCObjects import * diff --git a/wx/lib/floatcanvas/ScreenShot.py b/wx/lib/floatcanvas/ScreenShot.py index 52e9a699..e26d856a 100644 --- a/wx/lib/floatcanvas/ScreenShot.py +++ b/wx/lib/floatcanvas/ScreenShot.py @@ -10,7 +10,7 @@ import zlib def getScreenShotData(): return zlib.decompress( -'x\xdatzeP\\M\xd0.N\xf0\xe0\x16\xdc\xdd\x12\xdc\xdd\t/\xee\xee\xee\x0e!\x10\ +b'x\xdatzeP\\M\xd0.N\xf0\xe0\x16\xdc\xdd\x12\xdc\xdd\t/\xee\xee\xee\x0e!\x10\ \xdc\xdd\t\xee\xee\x8b\xbbC`\x91`\x8b;\xcb\xe2.\x97|_\xdd\x7f\xf7v\xd5\xd4\ \xa9\x9a\xd3\xa7\xa7g\xba{\xe6y\xa6N\xe4we\x194d"d(((49Y\xc9\xff\xa0\xa0\xa0\ />\x9a\xe8\'\x84\x8f\x1e\tK\xd6\xe4\x8f\x07\x9c\x9b\xb8\x9c\xfa\xa7\x0f\xf1\