diff --git a/_py/test/web/__init__.py b/_py/test/web/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/_py/test/web/exception.py b/_py/test/web/exception.py deleted file mode 100644 index 1987647f7..000000000 --- a/_py/test/web/exception.py +++ /dev/null @@ -1,6 +0,0 @@ -class CSSError(Exception): - """raised when there's a problem with the CSS""" - -class HTMLError(Exception): - """raised when there's a problem with the HTML""" - diff --git a/_py/test/web/post_multipart.py b/_py/test/web/post_multipart.py deleted file mode 100644 index 669e42e8d..000000000 --- a/_py/test/web/post_multipart.py +++ /dev/null @@ -1,58 +0,0 @@ -import httplib, mimetypes - -"""Copied from the cookbook - - see ActiveState's ASPN - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 -""" - -def post_multipart(host, selector, fields, files): - """ - Post fields and files to an http host as multipart/form-data. - fields is a sequence of (name, value) elements for regular form fields. - files is a sequence of (name, filename, value) elements for data to be - uploaded as files - - Return the server's response page. - """ - content_type, body = encode_multipart_formdata(fields, files) - h = httplib.HTTP(host) - h.putrequest('POST', selector) - h.putheader('content-type', content_type) - h.putheader('content-length', str(len(body))) - h.endheaders() - h.send(body) - errcode, errmsg, headers = h.getreply() - return h.file.read() - -def encode_multipart_formdata(fields, files): - """ - fields is a sequence of (name, value) elements for regular form fields. - files is a sequence of (name, filename, value) elements for data to be - uploaded as files - - Return (content_type, body) ready for httplib.HTTP instance - """ - BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$' - CRLF = '\r\n' - L = [] - for (key, value) in fields: - L.append('--' + BOUNDARY) - L.append('Content-Disposition: form-data; name="%s"' % key) - L.append('') - L.append(value) - for (key, filename, value) in files: - L.append('--' + BOUNDARY) - L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % - (key, filename)) - L.append('Content-Type: %s' % get_content_type(filename)) - L.append('') - L.append(value) - L.append('--' + BOUNDARY + '--') - L.append('') - body = CRLF.join(L) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY - return content_type, body - -def get_content_type(filename): - return mimetypes.guess_type(filename)[0] or 'application/octet-stream' diff --git a/_py/test/web/webcheck.py b/_py/test/web/webcheck.py deleted file mode 100644 index e70ce4f11..000000000 --- a/_py/test/web/webcheck.py +++ /dev/null @@ -1,41 +0,0 @@ -import py -import re -from exception import * -from post_multipart import post_multipart -#import css_checker - -def check_html(string): - """check an HTML string for wellformedness and validity""" - tempdir = py.test.ensuretemp('check_html') - filename = 'temp%s.html' % (hash(string), ) - tempfile = tempdir.join(filename) - tempfile.write(string) - ret = post_multipart('validator.w3.org', '/check', [], - [('uploaded_file', 'somehtml.html', string)]) - is_valid = get_validation_result_from_w3_html(ret) - return is_valid - -reg_validation_result = re.compile( - '<(h2|td)[^>]*class="(in)?valid"[^>]*>([^<]*)<', re.M | re.S) -def get_validation_result_from_w3_html(html): - match = reg_validation_result.search(html) - valid = match.group(1) is None - text = match.group(2).strip() - if not valid: - temp = py.test.ensuretemp('/w3_results_%s.html' % hash(html), dir=0) - temp.write(html) - raise HTMLError( - "The html is not valid. See the report file at '%s'" % temp) - return valid - -#def check_css(string, basepath, htmlpath='/'): -# """check the CSS of an HTML string -# -# check whether an HTML string contains CSS rels, and if so check whether -# any classes defined in the HTML actually have a matching CSS selector -# """ -# c = css_checker.css_checker(string, basepath, htmlpath) -# # raises a CSSError when failing, this is done from the tester class to -# # allow being more verbose than just 'something went wrong' -# return c.check() - diff --git a/_py/thread/__init__.py b/_py/thread/__init__.py deleted file mode 100644 index 792d60054..000000000 --- a/_py/thread/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/_py/thread/io.py b/_py/thread/io.py deleted file mode 100644 index a31addb56..000000000 --- a/_py/thread/io.py +++ /dev/null @@ -1,83 +0,0 @@ - -try: - from _thread import get_ident -except ImportError: - from thread import get_ident - -class ThreadOut(object): - """ A file like object that diverts writing operations - to per-thread writefuncs. - This is a py lib internal class and not meant for outer use - or modification. - """ - def __new__(cls, obj, attrname): - """ Divert file output to per-thread writefuncs. - the given obj and attrname describe the destination - of the file. - """ - current = getattr(obj, attrname) - if isinstance(current, cls): - current._used += 1 - return current - self = object.__new__(cls) - self._tid2out = {} - self._used = 1 - self._oldout = getattr(obj, attrname) - self._defaultwriter = self._oldout.write - self._address = (obj, attrname) - setattr(obj, attrname, self) - return self - - def isatty(self): - # XXX - return False - - def setdefaultwriter(self, writefunc): - self._defaultwriter = writefunc - - def resetdefault(self): - self._defaultwriter = self._oldout.write - - def softspace(): - def fget(self): - return self._get()[0] - def fset(self, value): - self._get()[0] = value - return property(fget, fset, None, "software attribute") - softspace = softspace() - - def deinstall(self): - self._used -= 1 - x = self._used - if x <= 0: - obj, attrname = self._address - setattr(obj, attrname, self._oldout) - - def setwritefunc(self, writefunc, tid=None): - if tid is None: - tid = get_ident() - self._tid2out[tid] = [0, writefunc] - - def delwritefunc(self, tid=None, ignoremissing=True): - if tid is None: - tid = get_ident() - try: - del self._tid2out[tid] - except KeyError: - if not ignoremissing: - raise - - def _get(self): - tid = get_ident() - try: - return self._tid2out[tid] - except KeyError: - return getattr(self._defaultwriter, 'softspace', 0), self._defaultwriter - - def write(self, data): - softspace, out = self._get() - out(data) - - def flush(self): - pass - diff --git a/_py/thread/pool.py b/_py/thread/pool.py deleted file mode 100644 index 90f52ae81..000000000 --- a/_py/thread/pool.py +++ /dev/null @@ -1,208 +0,0 @@ -import threading -import time -import sys -import py - -queue = py.builtin._tryimport('queue', 'Queue') - -ERRORMARKER = object() - -class Reply(object): - """ reply instances provide access to the result - of a function execution that got dispatched - through WorkerPool.dispatch() - """ - _excinfo = None - def __init__(self, task): - self.task = task - self._queue = queue.Queue() - - def _set(self, result): - self._queue.put(result) - - def _setexcinfo(self, excinfo): - self._excinfo = excinfo - self._queue.put(ERRORMARKER) - - def _get_with_timeout(self, timeout): - # taken from python2.3's Queue.get() - # we want to run on python2.2 here - delay = 0.0005 # 500 us -> initial delay of 1 ms - endtime = time.time() + timeout - while 1: - try: - return self._queue.get_nowait() - 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,)) - delay = min(delay * 2, remaining, .05) - time.sleep(delay) #reduce CPU usage by using a sleep - - def get(self, timeout=None): - """ get the result object from an asynchronous function execution. - if the function execution raised an exception, - then calling get() will reraise that exception - including its traceback. - """ - if self._queue is None: - raise EOFError("reply has already been delivered") - if timeout is not None: - result = self._get_with_timeout(timeout) - else: - result = self._queue.get() - if result is ERRORMARKER: - self._queue = None - excinfo = self._excinfo - py.builtin._reraise(excinfo[0], excinfo[1], excinfo[2]) - return result - -class WorkerThread(threading.Thread): - def __init__(self, pool): - threading.Thread.__init__(self) - self._queue = queue.Queue() - self._pool = pool - self.setDaemon(1) - - def _run_once(self): - reply = self._queue.get() - if reply is SystemExit: - return False - assert self not in self._pool._ready - task = reply.task - try: - func, args, kwargs = task - result = func(*args, **kwargs) - except (SystemExit, KeyboardInterrupt): - return False - except: - reply._setexcinfo(sys.exc_info()) - else: - reply._set(result) - # at this point, reply, task and all other local variables go away - return True - - def run(self): - try: - while self._run_once(): - self._pool._ready[self] = True - finally: - del self._pool._alive[self] - try: - del self._pool._ready[self] - except KeyError: - pass - - def send(self, task): - reply = Reply(task) - self._queue.put(reply) - return reply - - def stop(self): - self._queue.put(SystemExit) - -class WorkerPool(object): - """ A WorkerPool allows to dispatch function executions - to threads. Each Worker Thread is reused for multiple - function executions. The dispatching operation - takes care to create and dispatch to existing - threads. - - You need to call shutdown() to signal - the WorkerThreads to terminate and join() - in order to wait until all worker threads - have terminated. - """ - _shuttingdown = False - def __init__(self, maxthreads=None): - """ init WorkerPool instance which may - create up to `maxthreads` worker threads. - """ - self.maxthreads = maxthreads - self._ready = {} - self._alive = {} - - def dispatch(self, func, *args, **kwargs): - """ return Reply object for the asynchronous dispatch - of the given func(*args, **kwargs) in a - separate worker thread. - """ - if self._shuttingdown: - raise IOError("WorkerPool is already shutting down") - try: - thread, _ = self._ready.popitem() - except KeyError: # pop from empty list - if self.maxthreads and len(self._alive) >= self.maxthreads: - raise IOError("can't create more than %d threads." % - (self.maxthreads,)) - thread = self._newthread() - return thread.send((func, args, kwargs)) - - def _newthread(self): - thread = WorkerThread(self) - self._alive[thread] = True - thread.start() - return thread - - def shutdown(self): - """ signal all worker threads to terminate. - call join() to wait until all threads termination. - """ - if not self._shuttingdown: - self._shuttingdown = True - for t in list(self._alive): - t.stop() - - def join(self, timeout=None): - """ wait until all worker threads have terminated. """ - current = threading.currentThread() - deadline = delta = None - if timeout is not None: - deadline = time.time() + timeout - for thread in list(self._alive): - if deadline: - delta = deadline - time.time() - if delta <= 0: - raise IOError("timeout while joining threads") - thread.join(timeout=delta) - if thread.isAlive(): - raise IOError("timeout while joining threads") - -class NamedThreadPool: - def __init__(self, **kw): - self._namedthreads = {} - for name, value in kw.items(): - self.start(name, value) - - def __repr__(self): - return "" %(self._namedthreads) - - def get(self, name=None): - if name is None: - l = [] - for x in self._namedthreads.values(): - l.extend(x) - return l - else: - return self._namedthreads.get(name, []) - - def getstarted(self, name=None): - return [t for t in self.get(name) if t.isAlive()] - - def prunestopped(self, name=None): - if name is None: - for name in self.names(): - self.prunestopped(name) - else: - self._namedthreads[name] = self.getstarted(name) - - def names(self): - return self._namedthreads.keys() - - def start(self, name, func): - l = self._namedthreads.setdefault(name, []) - thread = threading.Thread(name="%s%d" % (name, len(l)), - target=func) - thread.start() - l.append(thread) - diff --git a/setup.py b/setup.py index d82a3654f..c5a3e45e7 100644 --- a/setup.py +++ b/setup.py @@ -65,9 +65,7 @@ def main(): '_py.test', '_py.test.dist', '_py.test.looponfail', - '_py.test.plugin', - '_py.test.web', - '_py.thread'], + '_py.test.plugin',], package_data={'py': ['bin/_findpy.py', 'bin/env.cmd', 'bin/env.py', @@ -86,8 +84,8 @@ def main(): 'bin/win32/py.rest.cmd', 'bin/win32/py.svnwcrevert.cmd', 'bin/win32/py.test.cmd', - 'bin/win32/py.which.cmd', - 'rest/rest.sty.template']}, + 'bin/win32/py.which.cmd',], + '_py': ['rest/rest.sty.template']}, zip_safe=True, ) diff --git a/testing/pytest/looponfail/test_util.py b/testing/pytest/looponfail/test_util.py index 70bc33600..b57fc4845 100644 --- a/testing/pytest/looponfail/test_util.py +++ b/testing/pytest/looponfail/test_util.py @@ -51,14 +51,11 @@ def test_pycremoval(tmpdir): assert not pycfile.check() -def test_waitonchange(tmpdir): +def test_waitonchange(tmpdir, monkeypatch): tmp = tmpdir sd = StatRecorder([tmp]) - wp = py._thread.WorkerPool(1) - reply = wp.dispatch(sd.waitonchange, checkinterval=0.2) - py.std.time.sleep(0.05) - tmp.ensure("newfile.py") - reply.get(timeout=0.5) - wp.shutdown() - + l = [True, False] + monkeypatch.setattr(StatRecorder, 'check', lambda self: l.pop()) + sd.waitonchange(checkinterval=0.2) + assert not l diff --git a/testing/thread/__init__.py b/testing/thread/__init__.py deleted file mode 100644 index 792d60054..000000000 --- a/testing/thread/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/testing/thread/test_io.py b/testing/thread/test_io.py deleted file mode 100644 index 52d6c3d59..000000000 --- a/testing/thread/test_io.py +++ /dev/null @@ -1,72 +0,0 @@ - -import py -import sys - -WorkerPool = py._thread.WorkerPool -ThreadOut = py._thread.ThreadOut - -def test_threadout_install_deinstall(): - old = sys.stdout - out = ThreadOut(sys, 'stdout') - out.deinstall() - assert old == sys.stdout - -class TestThreadOut: - def test_threadout_one(self): - out = ThreadOut(sys, 'stdout') - try: - l = [] - out.setwritefunc(l.append) - py.builtin.print_(42,13) - x = l.pop(0) - assert x == '42' - x = l.pop(0) - assert x == ' ' - x = l.pop(0) - assert x == '13' - finally: - out.deinstall() - - def test_threadout_multi_and_default(self): - out = ThreadOut(sys, 'stdout') - try: - num = 3 - defaults = [] - def f(l): - out.setwritefunc(l.append) - sys.stdout.write(str(id(l))) - out.delwritefunc() - print(1) - out.setdefaultwriter(defaults.append) - pool = WorkerPool() - listlist = [] - for x in range(num): - l = [] - listlist.append(l) - pool.dispatch(f, l) - pool.shutdown() - for name, value in out.__dict__.items(): - sys.stderr.write("%s: %s" %(name, value)) - pool.join(2.0) - for i in range(num): - item = listlist[i] - assert item ==[str(id(item))] - assert not out._tid2out - assert defaults - expect = ['1' for x in range(num)] - defaults = [x for x in defaults if x.strip()] - assert defaults == expect - finally: - out.deinstall() - - def test_threadout_nested(self): - out1 = ThreadOut(sys, 'stdout') - try: - # we want ThreadOuts to coexist - last = sys.stdout - out = ThreadOut(sys, 'stdout') - assert last == sys.stdout - out.deinstall() - assert last == sys.stdout - finally: - out1.deinstall() diff --git a/testing/thread/test_pool.py b/testing/thread/test_pool.py deleted file mode 100644 index ab20c3e8c..000000000 --- a/testing/thread/test_pool.py +++ /dev/null @@ -1,94 +0,0 @@ - -import py -import sys -from _py.thread.pool import queue - -WorkerPool = py._thread.WorkerPool -ThreadOut = py._thread.ThreadOut - -def test_some(): - pool = WorkerPool() - q = queue.Queue() - num = 4 - - def f(i): - q.put(i) - while q.qsize(): - py.std.time.sleep(0.01) - for i in range(num): - pool.dispatch(f, i) - for i in range(num): - q.get() - assert len(pool._alive) == 4 - pool.shutdown() - # XXX I replaced the following join() with a time.sleep(1), which seems - # to fix the test on Windows, and doesn't break it on Linux... Completely - # unsure what the idea is, though, so it would be nice if someone with some - # more understanding of what happens here would either fix this better, or - # remove this comment... - # pool.join(timeout=1.0) - py.std.time.sleep(1) - assert len(pool._alive) == 0 - assert len(pool._ready) == 0 - -def test_get(): - pool = WorkerPool() - def f(): - return 42 - reply = pool.dispatch(f) - result = reply.get() - assert result == 42 - -def test_get_timeout(): - pool = WorkerPool() - def f(): - py.std.time.sleep(0.2) - return 42 - reply = pool.dispatch(f) - py.test.raises(IOError, "reply.get(timeout=0.01)") - -def test_get_excinfo(): - pool = WorkerPool() - def f(): - raise ValueError("42") - reply = pool.dispatch(f) - excinfo = py.test.raises(ValueError, "reply.get(1.0)") - py.test.raises(EOFError, "reply.get(1.0)") - -def test_maxthreads(): - pool = WorkerPool(maxthreads=1) - def f(): - py.std.time.sleep(0.5) - try: - pool.dispatch(f) - py.test.raises(IOError, pool.dispatch, f) - finally: - pool.shutdown() - -def test_join_timeout(): - pool = WorkerPool() - q = queue.Queue() - def f(): - q.get() - reply = pool.dispatch(f) - pool.shutdown() - py.test.raises(IOError, pool.join, 0.01) - q.put(None) - reply.get(timeout=1.0) - pool.join(timeout=0.1) - -def test_pool_clean_shutdown(): - capture = py.io.StdCaptureFD() - pool = WorkerPool() - def f(): - pass - pool.dispatch(f) - pool.dispatch(f) - pool.shutdown() - pool.join(timeout=1.0) - assert not pool._alive - assert not pool._ready - out, err = capture.reset() - print(out) - sys.stderr.write(err + "\n") - assert err == ''