From c1fcf9c4d8710d7f204058f1f99677675f838099 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Tue, 1 Sep 2009 16:10:21 +0200 Subject: [PATCH] * use py.builtin._getimself instead of getattr(..., '*self*') everywhere * fix logging to work with 3k, implement buffering manually * fix unicode capturing issue - re-introduce EncodedFile for <3K file writes --HG-- branch : trunk --- py/__init__.py | 1 + py/_com.py | 5 ++-- py/builtin/builtin31.py | 6 +++++ py/execnet/gateway_base.py | 10 ++++---- py/execnet/rsync.py | 5 +++- py/io/capture.py | 32 +++++++++++++++++++++--- py/log/log.py | 35 ++++++++++++++------------- py/log/testing/test_log.py | 11 +++++---- py/log/testing/test_warning.py | 10 ++++---- py/log/warning.py | 2 +- py/test/collect.py | 2 +- py/test/compat.py | 7 +----- py/test/dist/dsession.py | 10 +++++--- py/test/dist/testing/test_mypickle.py | 27 ++++++++++----------- py/test/funcargs.py | 8 +++--- py/test/plugin/pytest_pytester.py | 2 +- py/test/plugin/pytest_resultlog.py | 7 +++--- py/test/plugin/pytest_unittest.py | 6 ++--- py/test/plugin/test_pytest_capture.py | 8 +++--- py/test/pycollect.py | 21 ++++++---------- py/test/testing/test_funcargs.py | 7 +++--- py/test/testing/test_genitems.py | 2 +- py/test/testing/test_pickling.py | 2 +- py/thread/io.py | 12 +++++---- py/thread/pool.py | 15 +++++++----- py/thread/testing/test_pool.py | 5 ++-- 26 files changed, 149 insertions(+), 109 deletions(-) diff --git a/py/__init__.py b/py/__init__.py index 5f951ac43..ccf03373c 100644 --- a/py/__init__.py +++ b/py/__init__.py @@ -151,6 +151,7 @@ initpkg(__name__, 'builtin._totext' : ('./builtin/builtin31.py', '_totext'), 'builtin._isbytes' : ('./builtin/builtin31.py', '_isbytes'), 'builtin._istext' : ('./builtin/builtin31.py', '_istext'), + 'builtin._getimself' : ('./builtin/builtin31.py', '_getimself'), 'builtin.builtins' : ('./builtin/builtin31.py', 'builtins'), 'builtin.execfile' : ('./builtin/builtin31.py', 'execfile'), 'builtin.callable' : ('./builtin/builtin31.py', 'callable'), diff --git a/py/_com.py b/py/_com.py index 98104043e..d157e2168 100644 --- a/py/_com.py +++ b/py/_com.py @@ -75,7 +75,8 @@ class Registry: l = [] if plugins is None: plugins = self._plugins - for plugin in list(plugins) + list(extra): + candidates = list(plugins) + list(extra) + for plugin in candidates: try: l.append(getattr(plugin, attrname)) except AttributeError: @@ -105,7 +106,7 @@ class HookRelay: return multicall.execute() class HookCaller: - def __init__(self, hookrelay, name, firstresult, extralookup=()): + def __init__(self, hookrelay, name, firstresult, extralookup=None): self.hookrelay = hookrelay self.name = name self.firstresult = firstresult diff --git a/py/builtin/builtin31.py b/py/builtin/builtin31.py index 5849ce062..29821e4e1 100644 --- a/py/builtin/builtin31.py +++ b/py/builtin/builtin31.py @@ -19,6 +19,9 @@ if sys.version_info >= (3, 0): def _istext(x): return isinstance(x, str) + def _getimself(function): + return getattr(function, '__self__', None) + def execfile(fn, globs=None, locs=None): if globs is None: back = sys._getframe(1) @@ -51,6 +54,9 @@ else: def _istext(x): return isinstance(x, unicode) + def _getimself(function): + return getattr(function, 'im_self', None) + import __builtin__ as builtins def print_(*args, **kwargs): """ minimal backport of py3k print statement. """ diff --git a/py/execnet/gateway_base.py b/py/execnet/gateway_base.py index 4933cff9d..c31ff2812 100644 --- a/py/execnet/gateway_base.py +++ b/py/execnet/gateway_base.py @@ -181,6 +181,7 @@ class Message: def _setupmessages(): + # XXX use metaclass for registering class CHANNEL_OPEN(Message): def received(self, gateway): @@ -211,14 +212,13 @@ def _setupmessages(): def received(self, gateway): gateway._channelfactory._local_last_message(self.channelid) - classes = [x for x in locals().values() if hasattr(x, '__bases__')] - classes.sort(lambda x,y : cmp(x.__name__, y.__name__)) - i = 0 - for cls in classes: + classes = [CHANNEL_OPEN, CHANNEL_NEW, CHANNEL_DATA, + CHANNEL_CLOSE, CHANNEL_CLOSE_ERROR, CHANNEL_LAST_MESSAGE] + + for i, cls in enumerate(classes): Message._types[i] = cls cls.msgtype = i setattr(Message, cls.__name__, cls) - i+=1 _setupmessages() diff --git a/py/execnet/rsync.py b/py/execnet/rsync.py index 6e34363c4..07b58df36 100644 --- a/py/execnet/rsync.py +++ b/py/execnet/rsync.py @@ -1,9 +1,12 @@ import py, os, stat -from Queue import Queue try: from hashlib import md5 except ImportError: from md5 import md5 +try: + from queue import Queue +except ImportError: + from Queue import Queue class RSync(object): """ This class allows to send a directory structure (recursively) diff --git a/py/io/capture.py b/py/io/capture.py index 6e3745b30..5daf43c6d 100644 --- a/py/io/capture.py +++ b/py/io/capture.py @@ -96,13 +96,37 @@ def dupfile(f, mode=None, buffering=0, raising=False, encoding=None): return f newfd = os.dup(fd) mode = mode and mode or f.mode - if encoding is not None and sys.version_info >= (3,0): - mode = mode.replace("b", "") - buffering = True + if sys.version_info >= (3,0): + if encoding is not None: + mode = mode.replace("b", "") + buffering = True return os.fdopen(newfd, mode, buffering, encoding, closefd=False) else: - return os.fdopen(newfd, mode, buffering) + f = os.fdopen(newfd, mode, buffering) + if encoding is not None: + return EncodedFile(f, encoding) + return f +class EncodedFile(object): + def __init__(self, _stream, encoding): + self._stream = _stream + self.encoding = encoding + + def write(self, obj): + if isinstance(obj, unicode): + obj = obj.encode(self.encoding) + elif isinstance(obj, str): + pass + else: + obj = str(obj) + self._stream.write(obj) + + def writelines(self, linelist): + data = ''.join(linelist) + self.write(data) + + def __getattr__(self, name): + return getattr(self._stream, name) class Capture(object): def call(cls, func, *args, **kwargs): diff --git a/py/log/log.py b/py/log/log.py index 57103c8f2..4b55c20f4 100644 --- a/py/log/log.py +++ b/py/log/log.py @@ -92,12 +92,12 @@ class KeywordMapper: """ set a consumer for a set of keywords. """ # normalize to tuples if isinstance(keywords, str): - keywords = tuple(map(None, keywords.split())) + keywords = tuple(filter(None, keywords.split())) elif hasattr(keywords, '_keywords'): keywords = keywords._keywords elif not isinstance(keywords, tuple): raise TypeError("key %r is not a string or tuple" % (keywords,)) - if consumer is not None and not callable(consumer): + if consumer is not None and not py.builtin.callable(consumer): if not hasattr(consumer, 'write'): raise TypeError( "%r should be None, callable or file-like" % (consumer,)) @@ -123,11 +123,10 @@ def getstate(): # class File(object): - """ log consumer wrapping a file(-like) object - """ + """ log consumer wrapping a file(-like) object """ def __init__(self, f): assert hasattr(f, 'write') - assert isinstance(f, file) or not hasattr(f, 'open') + #assert isinstance(f, file) or not hasattr(f, 'open') self._file = f def __call__(self, msg): @@ -135,19 +134,18 @@ class File(object): self._file.write(str(msg) + "\n") class Path(object): - """ log consumer able to write log messages into - """ - def __init__(self, filename, append=False, delayed_create=False, - buffering=1): + """ log consumer that opens and writes to a Path """ + def __init__(self, filename, append=False, + delayed_create=False, buffering=False): self._append = append - self._filename = filename + self._filename = str(filename) self._buffering = buffering if not delayed_create: self._openfile() def _openfile(self): mode = self._append and 'a' or 'w' - f = open(str(self._filename), mode, buffering=self._buffering) + f = open(self._filename, mode) self._file = f def __call__(self, msg): @@ -155,6 +153,8 @@ class Path(object): if not hasattr(self, "_file"): self._openfile() self._file.write(str(msg) + "\n") + if not self._buffering: + self._file.flush() def STDOUT(msg): """ consumer that writes to sys.stdout """ @@ -167,12 +167,6 @@ def STDERR(msg): class Syslog: """ consumer that writes to the syslog daemon """ - for priority in "LOG_EMERG LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG".split(): - try: - exec("%s = py.std.syslog.%s" % (priority, priority)) - except AttributeError: - pass - def __init__(self, priority = None): if priority is None: priority = self.LOG_INFO @@ -181,3 +175,10 @@ class Syslog: def __call__(self, msg): """ write a message to the log """ py.std.syslog.syslog(self.priority, str(msg)) + +for _prio in "EMERG ALERT CRIT ERR WARNING NOTICE INFO DEBUG".split(): + _prio = "LOG_" + _prio + try: + setattr(Syslog, _prio, getattr(py.std.syslog, _prio)) + except AttributeError: + pass diff --git a/py/log/testing/test_log.py b/py/log/testing/test_log.py index 9c9964c5a..0c2346fde 100644 --- a/py/log/testing/test_log.py +++ b/py/log/testing/test_log.py @@ -117,14 +117,15 @@ class TestLogConsumer: assert out.strip() == '[xyz] hello' def test_log_file(self): - custom_log = tempdir.join('log.out') - py.log.setconsumer("default", open(str(custom_log), 'w', buffering=0)) + customlog = tempdir.join('log.out') + py.log.setconsumer("default", open(str(customlog), 'w', buffering=1)) py.log.Producer("default")("hello world #1") - assert custom_log.readlines() == ['[default] hello world #1\n'] + assert customlog.readlines() == ['[default] hello world #1\n'] - py.log.setconsumer("default", py.log.Path(custom_log, buffering=0)) + py.log.setconsumer("default", py.log.Path(customlog, buffering=False)) py.log.Producer("default")("hello world #2") - assert custom_log.readlines() == ['[default] hello world #2\n'] # no append by default! + res = customlog.readlines() + assert res == ['[default] hello world #2\n'] # no append by default! def test_log_file_append_mode(self): logfilefn = tempdir.join('log_append.out') diff --git a/py/log/testing/test_warning.py b/py/log/testing/test_warning.py index 01b197b74..672a5c980 100644 --- a/py/log/testing/test_warning.py +++ b/py/log/testing/test_warning.py @@ -11,7 +11,7 @@ def test_apiwarn_functional(): py.builtin.print_("out", out) py.builtin.print_("err", err) assert err.find("x.y.z") != -1 - lno = test_apiwarn_functional.func_code.co_firstlineno + 2 + lno = py.code.getrawcode(test_apiwarn_functional).co_firstlineno + 2 exp = "%s:%s" % (mypath, lno) assert err.find(exp) != -1 @@ -23,7 +23,7 @@ def test_stacklevel(): capture = py.io.StdCapture() f() out, err = capture.reset() - lno = test_stacklevel.func_code.co_firstlineno + 6 + lno = py.code.getrawcode(test_stacklevel).co_firstlineno + 6 warning = str(err) assert warning.find(":%s" % lno) != -1 @@ -38,7 +38,7 @@ def test_stacklevel_initpkg_with_resolve(testdir): capture = py.io.StdCapture() mod.__getattr__() out, err = capture.reset() - lno = test_stacklevel_initpkg_with_resolve.func_code.co_firstlineno + 9 + lno = py.code.getrawcode(test_stacklevel_initpkg_with_resolve).co_firstlineno + 9 warning = str(err) assert warning.find(":%s" % lno) != -1 @@ -48,7 +48,7 @@ def test_stacklevel_initpkg_no_resolve(): capture = py.io.StdCapture() f() out, err = capture.reset() - lno = test_stacklevel_initpkg_no_resolve.func_code.co_firstlineno + 2 + lno = py.code.getrawcode(test_stacklevel_initpkg_no_resolve).co_firstlineno + 2 warning = str(err) assert warning.find(":%s" % lno) != -1 @@ -60,7 +60,7 @@ def test_function(): py.builtin.print_("out", out) py.builtin.print_("err", err) assert err.find("x.y.z") != -1 - lno = test_function.func_code.co_firstlineno + lno = py.code.getrawcode(test_function).co_firstlineno exp = "%s:%s" % (mypath, lno) assert err.find(exp) != -1 diff --git a/py/log/warning.py b/py/log/warning.py index dc6911cfd..d9557d1c7 100644 --- a/py/log/warning.py +++ b/py/log/warning.py @@ -31,7 +31,7 @@ def _apiwarn(startversion, msg, stacklevel=1, function=None): def warn(msg, stacklevel=1, function=None): if function is not None: filename = py.std.inspect.getfile(function) - lineno = function.func_code.co_firstlineno + lineno = py.code.getrawcode(function).co_firstlineno else: try: caller = sys._getframe(stacklevel) diff --git a/py/test/collect.py b/py/test/collect.py index 894af904c..a3d6ec9e9 100644 --- a/py/test/collect.py +++ b/py/test/collect.py @@ -316,7 +316,7 @@ class Collector(Node): if method is not None and method != Collector.run: warnoldcollect(function=method) names = self.run() - return filter(None, [self.join(name) for name in names]) + return [x for x in [self.join(name) for name in names] if x] def run(self): """ DEPRECATED: returns a list of names available from this collector. diff --git a/py/test/compat.py b/py/test/compat.py index 9a08cd070..86d1d20b4 100644 --- a/py/test/compat.py +++ b/py/test/compat.py @@ -2,18 +2,13 @@ import py from py.test.collect import Function -if py.std.sys.version_info > (3, 0): - _self = "__self__" -else: - _self = "im_self" - class TestCaseUnit(Function): """ compatibility Unit executor for TestCase methods honouring setUp and tearDown semantics. """ def runtest(self, _deprecated=None): boundmethod = self.obj - instance = getattr(boundmethod, _self) + instance = py.builtin._getimself(boundmethod) instance.setUp() try: boundmethod() diff --git a/py/test/dist/dsession.py b/py/test/dist/dsession.py index f68ccd4b2..db4b8f969 100644 --- a/py/test/dist/dsession.py +++ b/py/test/dist/dsession.py @@ -8,8 +8,10 @@ import py from py.__.test.session import Session from py.__.test import outcome from py.__.test.dist.nodemanage import NodeManager - -import Queue +try: + import queue +except ImportError: + import Queue as queue debug_file = None # open('/tmp/loop.log', 'w') def debug(*args): @@ -72,7 +74,7 @@ class DSession(Session): MAXITEMSPERHOST = 15 def __init__(self, config): - self.queue = Queue.Queue() + self.queue = queue.Queue() self.node2pending = {} self.item2nodes = {} super(DSession, self).__init__(config=config) @@ -107,7 +109,7 @@ class DSession(Session): try: eventcall = self.queue.get(timeout=2.0) break - except Queue.Empty: + except queue.Empty: continue loopstate.dowork = True diff --git a/py/test/dist/testing/test_mypickle.py b/py/test/dist/testing/test_mypickle.py index c10fba76d..6b11ca84d 100644 --- a/py/test/dist/testing/test_mypickle.py +++ b/py/test/dist/testing/test_mypickle.py @@ -14,17 +14,24 @@ def pytest_generate_tests(metafunc): except ImportError: pass else: - metafunc.addcall(funcargs={'picklemod': cPpickle}) + metafunc.addcall(funcargs={'picklemod': cPickle}) + elif "obj" in metafunc.funcargnames and "proto" in metafunc.funcargnames: + a1 = A() + a2 = A() + a2.a1 = a1 + for proto in (0,1,2, -1): + for obj in {1:2}, [1,2,3], a1, a2: + metafunc.addcall(funcargs=dict(obj=obj, proto=proto)) -def xxx_test_underlying_basic_pickling_mechanisms(picklemod): +def test_underlying_basic_pickling_mechanisms(picklemod): f1 = py.io.TextIO() f2 = py.io.TextIO() - pickler1 = picklingmod.Pickler(f1) - unpickler1 = picklingmod.Unpickler(f2) + pickler1 = picklemod.Pickler(f1) + unpickler1 = picklemod.Unpickler(f2) - pickler2 = picklingmod.Pickler(f2) - unpickler2 = picklingmod.Unpickler(f1) + pickler2 = picklemod.Pickler(f2) + unpickler2 = picklemod.Unpickler(f1) #pickler1.memo = unpickler1.memo = {} #pickler2.memo = unpickler2.memo = {} @@ -50,14 +57,6 @@ def xxx_test_underlying_basic_pickling_mechanisms(picklemod): class A: pass -def pytest_generate_tests(metafunc): - if "obj" in metafunc.funcargnames and "proto" in metafunc.funcargnames: - a1 = A() - a2 = A() - a2.a1 = a1 - for proto in (0,1,2, -1): - for obj in {1:2}, [1,2,3], a1, a2: - metafunc.addcall(funcargs=dict(obj=obj, proto=proto)) def test_pickle_and_back_IS_same(obj, proto): p1 = ImmutablePickler(uneven=False, protocol=proto) diff --git a/py/test/funcargs.py b/py/test/funcargs.py index 0e21bdcc1..e9b7dc0f6 100644 --- a/py/test/funcargs.py +++ b/py/test/funcargs.py @@ -83,8 +83,9 @@ class FuncargRequest: self._pyfuncitem = pyfuncitem self.function = pyfuncitem.obj self.module = pyfuncitem.getparent(py.test.collect.Module).obj - self.cls = getattr(self.function, 'im_class', None) - self.instance = getattr(self.function, 'im_self', None) + clscol = pyfuncitem.getparent(py.test.collect.Class) + self.cls = clscol and clscol.obj or None + self.instance = py.builtin._getimself(self.function) self.config = pyfuncitem.config self.fspath = pyfuncitem.fspath if hasattr(pyfuncitem, '_requestparam'): @@ -99,7 +100,8 @@ class FuncargRequest: def _fillfuncargs(self): argnames = getfuncargnames(self.function) if argnames: - assert not getattr(self._pyfuncitem, '_args', None), "yielded functions cannot have funcargs" + assert not getattr(self._pyfuncitem, '_args', None), ( + "yielded functions cannot have funcargs") for argname in argnames: if argname not in self._pyfuncitem.funcargs: self._pyfuncitem.funcargs[argname] = self.getfuncargvalue(argname) diff --git a/py/test/plugin/pytest_pytester.py b/py/test/plugin/pytest_pytester.py index 4ebe7165c..76090035f 100644 --- a/py/test/plugin/pytest_pytester.py +++ b/py/test/plugin/pytest_pytester.py @@ -151,7 +151,7 @@ class TmpTestdir: # used from runner functional tests item = self.getitem(source) # the test class where we are called from wants to provide the runner - testclassinstance = self.request.function.im_self + testclassinstance = py.builtin._getimself(self.request.function) runner = testclassinstance.getrunner() return runner(item) diff --git a/py/test/plugin/pytest_resultlog.py b/py/test/plugin/pytest_resultlog.py index 28274e44c..382c8780b 100644 --- a/py/test/plugin/pytest_resultlog.py +++ b/py/test/plugin/pytest_resultlog.py @@ -3,6 +3,7 @@ """ import py +from py.builtin import print_ def pytest_addoption(parser): group = parser.addgroup("resultlog", "resultlog plugin options") @@ -51,9 +52,9 @@ class ResultLog(object): self.logfile = logfile # preferably line buffered def write_log_entry(self, testpath, shortrepr, longrepr): - print >>self.logfile, "%s %s" % (shortrepr, testpath) + print_("%s %s" % (shortrepr, testpath), file=self.logfile) for line in longrepr.splitlines(): - print >>self.logfile, " %s" % line + print_(" %s" % line, file=self.logfile) def log_outcome(self, node, shortrepr, longrepr): testpath = generic_path(node) @@ -161,7 +162,7 @@ class TestWithFunctionIntegration: testdir.plugins.append("resultlog") args = ["--resultlog=%s" % resultlog] + [arg] testdir.runpytest(*args) - return filter(None, resultlog.readlines(cr=0)) + return [x for x in resultlog.readlines(cr=0) if x] def test_collection_report(self, testdir): ok = testdir.makepyfile(test_collection_ok="") diff --git a/py/test/plugin/pytest_unittest.py b/py/test/plugin/pytest_unittest.py index 28f32ccff..00b873e62 100644 --- a/py/test/plugin/pytest_unittest.py +++ b/py/test/plugin/pytest_unittest.py @@ -40,7 +40,7 @@ class UnitTestCaseInstance(py.test.collect.Instance): l = [] for name in names: callobj = getattr(self.obj, name) - if callable(callobj): + if py.builtin.callable(callobj): l.append(UnitTestFunction(name, parent=self)) return l @@ -65,11 +65,11 @@ class UnitTestFunction(py.test.collect.Function): target(*args) def setup(self): - instance = self.obj.im_self + instance = py.builtin._getimself(self.obj) instance.setUp() def teardown(self): - instance = self.obj.im_self + instance = py.builtin._getimself(self.obj) instance.tearDown() diff --git a/py/test/plugin/test_pytest_capture.py b/py/test/plugin/test_pytest_capture.py index 37850da58..d3e05dc6e 100644 --- a/py/test/plugin/test_pytest_capture.py +++ b/py/test/plugin/test_pytest_capture.py @@ -56,14 +56,16 @@ class TestCaptureManager: @py.test.mark.multi(method=['fd', 'sys']) def test_capturing_unicode(testdir, method): if sys.version_info >= (3,0): - py.test.skip("test not applicable on 3k") + obj = "'b\u00f6y'" + else: + obj = "u'\u00f6y'" testdir.makepyfile(""" # taken from issue 227 from nosetests def test_unicode(): import sys print (sys.stdout) - print u'b\\u00f6y' - """) + print (%s) + """ % obj) result = testdir.runpytest("--capture=%s" % method) result.stdout.fnmatch_lines([ "*1 passed*" diff --git a/py/test/pycollect.py b/py/test/pycollect.py index 801635e25..a5f8d6498 100644 --- a/py/test/pycollect.py +++ b/py/test/pycollect.py @@ -17,6 +17,7 @@ a tree of collectors and test items that this modules provides:: """ import py +import inspect from py.__.test.collect import configproperty, warnoldcollect pydir = py.path.local(py.__file__).dirpath() from py.__.test import funcargs @@ -100,7 +101,7 @@ class PyCollectorMixin(PyobjMixin, py.test.collect.Collector): # NB. we avoid random getattrs and peek in the __dict__ instead d = {} dicts = [getattr(self.obj, '__dict__', {})] - for basecls in py.std.inspect.getmro(self.obj.__class__): + for basecls in inspect.getmro(self.obj.__class__): dicts.append(basecls.__dict__) seen = {} for dic in dicts: @@ -140,7 +141,7 @@ class PyCollectorMixin(PyobjMixin, py.test.collect.Collector): def _istestclasscandidate(self, name, obj): if self.classnamefilter(name) and \ - py.std.inspect.isclass(obj): + inspect.isclass(obj): if hasinit(obj): # XXX WARN return False @@ -149,8 +150,6 @@ class PyCollectorMixin(PyobjMixin, py.test.collect.Collector): def _genfunctions(self, name, funcobj): module = self.getparent(Module).obj - # due to _buildname2items funcobj is the raw function, we need - # to work to get at the class clscol = self.getparent(Class) cls = clscol and clscol.obj or None metafunc = funcargs.Metafunc(funcobj, config=self.config, @@ -163,15 +162,11 @@ class PyCollectorMixin(PyobjMixin, py.test.collect.Collector): return funcargs.FunctionCollector(name=name, parent=self, calls=metafunc._calls) -if py.std.sys.version_info > (3, 0): - _code_attr = "__code__" -else: - _code_attr = "func_code" - def is_generator(func): try: - return (getattr(func, _code_attr).co_flags & 32) # generator function - except AttributeError: # c / builtin functions have no func_code + return py.code.getrawcode(func).co_flags & 32 # generator function + except AttributeError: # builtin functions have no bytecode + # assume them to not be generators return False class Module(py.test.collect.File, PyCollectorMixin): @@ -242,7 +237,7 @@ class FunctionMixin(PyobjMixin): def setup(self): """ perform setup for this test function. """ - if py.std.inspect.ismethod(self.obj): + if inspect.ismethod(self.obj): name = 'setup_method' else: name = 'setup_function' @@ -257,7 +252,7 @@ class FunctionMixin(PyobjMixin): def teardown(self): """ perform teardown for this test function. """ - if hasattr(self.obj, 'im_self'): + if inspect.ismethod(self.obj): name = 'teardown_method' else: name = 'teardown_function' diff --git a/py/test/testing/test_funcargs.py b/py/test/testing/test_funcargs.py index efc6bf489..ca5ba29a6 100644 --- a/py/test/testing/test_funcargs.py +++ b/py/test/testing/test_funcargs.py @@ -1,4 +1,4 @@ -import py +import py, sys from py.__.test import funcargs def test_getfuncargnames(): @@ -14,7 +14,8 @@ def test_getfuncargnames(): def f(self, arg1, arg2="hello"): pass assert funcargs.getfuncargnames(A().f) == ['arg1'] - assert funcargs.getfuncargnames(A.f) == ['arg1'] + if sys.version_info < (3,0): + assert funcargs.getfuncargnames(A.f) == ['arg1'] class TestFillFuncArgs: def test_funcarg_lookupfails(self, testdir): @@ -361,7 +362,7 @@ class TestGenfuncFunctional: "*2 passed in*", ]) - def test_addcall_with_funcargs_two(self, testdir): + def test_addcall_with_two_funcargs_generators(self, testdir): testdir.makeconftest(""" def pytest_generate_tests(metafunc): assert "arg1" in metafunc.funcargnames diff --git a/py/test/testing/test_genitems.py b/py/test/testing/test_genitems.py index 4ceea649f..387709701 100644 --- a/py/test/testing/test_genitems.py +++ b/py/test/testing/test_genitems.py @@ -26,7 +26,7 @@ class Test_genitems: def test_subdir_conftest_error(self, testdir): tmp = testdir.tmpdir - tmp.ensure("sub", "conftest.py").write("raise SyntaxError\n") + tmp.ensure("sub", "conftest.py").write("raise SyntaxError()\n") items, reprec = testdir.inline_genitems(tmp) collectionfailures = reprec.getfailedcollections() assert len(collectionfailures) == 1 diff --git a/py/test/testing/test_pickling.py b/py/test/testing/test_pickling.py index addff0bbc..8d8093898 100644 --- a/py/test/testing/test_pickling.py +++ b/py/test/testing/test_pickling.py @@ -153,7 +153,7 @@ class TestConfigPickling: assert col2.listnames() == col.listnames() def test_config_and_collector_pickling(self, testdir): - from cPickle import Pickler, Unpickler + from pickle import Pickler, Unpickler tmpdir = testdir.tmpdir dir1 = tmpdir.ensure("somedir", dir=1) config = testdir.parseconfig() diff --git a/py/thread/io.py b/py/thread/io.py index 6e88f241e..a31addb56 100644 --- a/py/thread/io.py +++ b/py/thread/io.py @@ -1,5 +1,8 @@ -import thread +try: + from _thread import get_ident +except ImportError: + from thread import get_ident class ThreadOut(object): """ A file like object that diverts writing operations @@ -51,14 +54,13 @@ class ThreadOut(object): setattr(obj, attrname, self._oldout) def setwritefunc(self, writefunc, tid=None): - assert callable(writefunc) if tid is None: - tid = thread.get_ident() + tid = get_ident() self._tid2out[tid] = [0, writefunc] def delwritefunc(self, tid=None, ignoremissing=True): if tid is None: - tid = thread.get_ident() + tid = get_ident() try: del self._tid2out[tid] except KeyError: @@ -66,7 +68,7 @@ class ThreadOut(object): raise def _get(self): - tid = thread.get_ident() + tid = get_ident() try: return self._tid2out[tid] except KeyError: diff --git a/py/thread/pool.py b/py/thread/pool.py index a84579891..553ba6036 100644 --- a/py/thread/pool.py +++ b/py/thread/pool.py @@ -1,8 +1,11 @@ -import Queue import threading import time import sys import py +try: + import queue +except ImportError: + import Queue as queue ERRORMARKER = object() @@ -14,7 +17,7 @@ class Reply(object): _excinfo = None def __init__(self, task): self.task = task - self._queue = Queue.Queue() + self._queue = queue.Queue() def _set(self, result): self._queue.put(result) @@ -31,7 +34,7 @@ class Reply(object): while 1: try: return self._queue.get_nowait() - except Queue.Empty: + except queue.Empty: remaining = endtime - time.time() if remaining <= 0: #time is over and no element arrived raise IOError("timeout waiting for task %r" %(self.task,)) @@ -59,7 +62,7 @@ class Reply(object): class WorkerThread(threading.Thread): def __init__(self, pool): threading.Thread.__init__(self) - self._queue = Queue.Queue() + self._queue = queue.Queue() self._pool = pool self.setDaemon(1) @@ -149,7 +152,7 @@ class WorkerPool(object): """ if not self._shuttingdown: self._shuttingdown = True - for t in self._alive.keys(): + for t in list(self._alive): t.stop() def join(self, timeout=None): @@ -158,7 +161,7 @@ class WorkerPool(object): deadline = delta = None if timeout is not None: deadline = time.time() + timeout - for thread in self._alive.keys(): + for thread in list(self._alive): if deadline: delta = deadline - time.time() if delta <= 0: diff --git a/py/thread/testing/test_pool.py b/py/thread/testing/test_pool.py index 101a7e59b..20a2b1c32 100644 --- a/py/thread/testing/test_pool.py +++ b/py/thread/testing/test_pool.py @@ -1,13 +1,14 @@ import py import sys +from py.__.thread.pool import queue WorkerPool = py._thread.WorkerPool ThreadOut = py._thread.ThreadOut def test_some(): pool = WorkerPool() - q = py.std.Queue.Queue() + q = queue.Queue() num = 4 def f(i): @@ -66,7 +67,7 @@ def test_maxthreads(): def test_join_timeout(): pool = WorkerPool() - q = py.std.Queue.Queue() + q = queue.Queue() def f(): q.get() reply = pool.dispatch(f)