From tismer at codespeak.net Tue Mar 1 19:33:33 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 1 Mar 2005 19:33:33 +0100 (MET) Subject: [py-svn] r9558 - py/dist/py/misc Message-ID: <20050301183333.5F6B627B3B@code1.codespeak.net> Author: tismer Date: Tue Mar 1 19:33:32 2005 New Revision: 9558 Modified: py/dist/py/misc/error.py Log: added a new windows error (5) not sure whether we should provide a default mechanism. If we do, we will probably never completely fill the windows dict... Modified: py/dist/py/misc/error.py ============================================================================== --- py/dist/py/misc/error.py (original) +++ py/dist/py/misc/error.py Tue Mar 1 19:33:32 2005 @@ -19,7 +19,8 @@ _winerrnomap = { 3: py.std.errno.ENOENT, - 267: py.std.errno.ENOTDIR, + 267: py.std.errno.ENOTDIR, + 5: py.std.errno.EACCES, # anything better? } ModuleType = type(py) From hpk at codespeak.net Thu Mar 3 18:01:16 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 3 Mar 2005 18:01:16 +0100 (MET) Subject: [py-svn] r9609 - in py/branch/py-collect/test2: . testing Message-ID: <20050303170116.7F2C727B4C@code1.codespeak.net> Author: hpk Date: Thu Mar 3 18:01:16 2005 New Revision: 9609 Modified: py/branch/py-collect/test2/collect.py py/branch/py-collect/test2/drive.py py/branch/py-collect/test2/item.py py/branch/py-collect/test2/testing/test_collect.py py/branch/py-collect/test2/testing/test_drive.py Log: shifted and added tests, improved docstrings Modified: py/branch/py-collect/test2/collect.py ============================================================================== --- py/branch/py-collect/test2/collect.py (original) +++ py/branch/py-collect/test2/collect.py Thu Mar 3 18:01:16 2005 @@ -1,9 +1,19 @@ -import py -isclass = py.std.inspect.isclass """ -The is the tree of collectors. Items are the leaves -that really get executed as tests. +Collect test items at filesystem and python module levels. + +Collectors and test items form a tree. The difference +between a collector and a test item as seen from the driver +is conceptually non existent. However, Collectors usually +return a list of child collectors/items whereas items usually +return None indicating a successful test run. +All collectors and items have a "name" and + + names = [x.name for x in colitem. + +so that driving reporting can uniformly represent item + +The is a schematic example of the tree of collectors and test items:: Directory Module @@ -17,7 +27,10 @@ Function Directory ... + """ +import py +isclass = py.std.inspect.isclass def configproperty(name): def fget(self): @@ -28,7 +41,9 @@ def getfscollector(fspath): if isinstance(fspath, str): fspath = py.path.local(fspath) - return Directory(fspath.dirpath()).join(fspath.basename) + col = Directory(fspath.dirpath()).join(fspath.basename) + col.parent = None + return col class Collector(object): def __init__(self, name, parent=None): @@ -107,8 +122,11 @@ l.reverse() return l + def listnames(self): + return [x.name for x in self.listchain()] + def getmodpath(self): - """ return path from the last module.""" + """ return dotted module path (relative to the containing). """ inmodule = False newl = [] for x in self.listchain(): @@ -124,7 +142,7 @@ return ".".join(newl) def iteritems(self): - """ yield all Items from a flattened Collector instance.""" + """ yield all Items from flattended collector instance. """ if isinstance(self, py.test2.Item): yield self else: @@ -245,7 +263,7 @@ class Instance(PyCollectorMixin, Collector): def _getobj(self): - return self.parent.obj() + return self.parent.obj() def Function(self): return getattr(self.obj, 'Function', super(Instance, self).Function) Function = property(Function) Modified: py/branch/py-collect/test2/drive.py ============================================================================== --- py/branch/py-collect/test2/drive.py (original) +++ py/branch/py-collect/test2/drive.py Thu Mar 3 18:01:16 2005 @@ -83,6 +83,8 @@ except: excinfo = py.code.ExceptionInfo() res = colitem.Failed(excinfo=excinfo) + else: + assert res is None or isinstance(res, (list, colitem.Outcome)) finally: self.finish(colitem, res) Modified: py/branch/py-collect/test2/item.py ============================================================================== --- py/branch/py-collect/test2/item.py (original) +++ py/branch/py-collect/test2/item.py Thu Mar 3 18:01:16 2005 @@ -33,8 +33,8 @@ state = SetupState() class Function(Item): - """ an Item is responsible for locating and executing - a Python callable test object. + """ a Function Item is responsible for setting up + and executing a Python callable test object. """ def __init__(self, name, parent, args=(), obj=None): self.name = name Modified: py/branch/py-collect/test2/testing/test_collect.py ============================================================================== --- py/branch/py-collect/test2/testing/test_collect.py (original) +++ py/branch/py-collect/test2/testing/test_collect.py Thu Mar 3 18:01:16 2005 @@ -116,25 +116,7 @@ assert isinstance(l2[1], py.test2.Function) assert l2[0].name == '[0]' assert l2[1].name == '[1]' - -l = [] -def test_1(): - l.append(1) -def test_2(): - l.append(2) -def test_3(): - assert l == [1,2] -class Testmygroup: - reslist = [] - def test_1(self): - self.reslist.append(1) - def test_2(self): - self.reslist.append(2) - def test_3(self): - self.reslist.append(3) - def test_4(self): - assert self.reslist == [1,2,3] - + def test_custom_collection_from_conftest(): o = py.test2.config.tmpdir.ensure('customconfigtest', dir=1) o.ensure('conftest.py').write("""if 1: Modified: py/branch/py-collect/test2/testing/test_drive.py ============================================================================== --- py/branch/py-collect/test2/testing/test_drive.py (original) +++ py/branch/py-collect/test2/testing/test_drive.py Thu Mar 3 18:01:16 2005 @@ -51,3 +51,38 @@ for line in ('filetest.py', 'test_one', 'TestClass', 'test_method_one'): assert out.find(line) + +def test_order_of_execution(): + o = py.test2.config.tmpdir.ensure('ordertest', dir=1) + tfile = o.join('test_orderofexecution.py') + tfile.write(py.code.Source(""" + l = [] + def test_1(): + l.append(1) + def test_2(): + l.append(2) + def test_3(): + assert l == [1,2] + class Testmygroup: + reslist = l + def test_1(self): + self.reslist.append(1) + def test_2(self): + self.reslist.append(2) + def test_3(self): + self.reslist.append(3) + def test_4(self): + assert self.reslist == [1,2,1,2,3] + """)) + + drive = py.test2.Driver() + drive.runpath(o) + l = drive.getresults(py.test2.Item.Failed) + assert len(l) == 0 + l = drive.getresults(py.test2.Item.Passed) + assert len(l) == 7 + # also test listnames() here ... + item, result = l[-1] + assert item.name == 'test_4' + names = item.listnames() + assert names == ['ordertest', 'test_orderofexecution.py', 'Testmygroup', '()', 'test_4'] From hpk at codespeak.net Fri Mar 4 08:07:28 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 08:07:28 +0100 (MET) Subject: [py-svn] r9616 - in py/dist/py/c-extension: . greenlet Message-ID: <20050304070728.84D2C27B45@code1.codespeak.net> Author: hpk Date: Fri Mar 4 08:07:28 2005 New Revision: 9616 Modified: py/dist/py/c-extension/ (props changed) py/dist/py/c-extension/greenlet/test_remote.py (props changed) Log: fixeol From hpk at codespeak.net Fri Mar 4 08:20:21 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 08:20:21 +0100 (MET) Subject: [py-svn] r9617 - in py/branch/py-collect/test2: . testing Message-ID: <20050304072021.EA93A27B45@code1.codespeak.net> Author: hpk Date: Fri Mar 4 08:20:21 2005 New Revision: 9617 Modified: py/branch/py-collect/test2/collect.py py/branch/py-collect/test2/item.py py/branch/py-collect/test2/raises.py py/branch/py-collect/test2/testing/test_api.py Log: test more of test2 (the ongoing code branch for collect-refactoring) Modified: py/branch/py-collect/test2/collect.py ============================================================================== --- py/branch/py-collect/test2/collect.py (original) +++ py/branch/py-collect/test2/collect.py Fri Mar 4 08:20:21 2005 @@ -57,7 +57,7 @@ Function = configproperty('Function') Generator = configproperty('Generator') - class Outcome(object): + class Outcome: def __init__(self, **kwargs): assert 'msg' not in kwargs or isinstance(kwargs['msg'], str), ( "given 'msg' argument is not a string" ) Modified: py/branch/py-collect/test2/item.py ============================================================================== --- py/branch/py-collect/test2/item.py (original) +++ py/branch/py-collect/test2/item.py Fri Mar 4 08:20:21 2005 @@ -82,7 +82,7 @@ # def skip(msg="unknown reason", tbindex=-2): """ skip with the given Message. """ - raise py.test.Item.Skipped(msg=msg, tbindex=tbindex) + raise py.test2.Item.Skipped(msg=msg, tbindex=tbindex) def skip_on_error(func, *args, **kwargs): """ skip test if the given call fails. """ @@ -91,9 +91,9 @@ except Exception, e: s = py.code.ExceptionInfo().exconly() name = getattr(func, '__name__', func) - py.test.skip("%s(...) -> %s" %(name, s.rstrip(), ), tbindex=-3) + py.test2.skip("%s(...) -> %s" %(name, s.rstrip(), ), tbindex=-3) def fail(msg="unknown failure"): """ fail with the given Message. """ - raise py.test.Item.Failed(msg=msg, tbindex=-2) + raise py.test2.Item.Failed(msg=msg, tbindex=-2) Modified: py/branch/py-collect/test2/raises.py ============================================================================== --- py/branch/py-collect/test2/raises.py (original) +++ py/branch/py-collect/test2/raises.py Fri Mar 4 08:20:21 2005 @@ -1,6 +1,6 @@ import sys import py -ExceptionFailure = py.test.Item.ExceptionFailure +ExceptionFailure = py.test2.Item.ExceptionFailure def raises(ExpectedException, *args, **kwargs): """ raise AssertionError, if target code does not raise the expected Modified: py/branch/py-collect/test2/testing/test_api.py ============================================================================== --- py/branch/py-collect/test2/testing/test_api.py (original) +++ py/branch/py-collect/test2/testing/test_api.py Fri Mar 4 08:20:21 2005 @@ -4,9 +4,9 @@ def test_skipfailure(): def f(): raise ValueError() - excinfo = py.test.raises( - py.test.Item.Skipped, - "py.test.skip_on_error(f)") + excinfo = py.test2.raises( + py.test2.Item.Skipped, + "py.test2.skip_on_error(f)") print excinfo assert str(excinfo).find("ValueError") != -1 From hpk at codespeak.net Fri Mar 4 08:37:25 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 08:37:25 +0100 (MET) Subject: [py-svn] r9618 - py/branch/py-collect/test2 Message-ID: <20050304073725.148ED27B45@code1.codespeak.net> Author: hpk Date: Fri Mar 4 08:37:24 2005 New Revision: 9618 Modified: py/branch/py-collect/test2/terminal.py Log: don't use reporter/summary object anymore Modified: py/branch/py-collect/test2/terminal.py ============================================================================== --- py/branch/py-collect/test2/terminal.py (original) +++ py/branch/py-collect/test2/terminal.py Fri Mar 4 08:37:24 2005 @@ -1,7 +1,6 @@ import py from py.__impl__.test2.report.text.out import getout -from py.__impl__.test2.report.text.summary import Summary from time import time as now Item = py.test2.Item @@ -12,8 +11,6 @@ file = py.std.sys.stdout self.out = getout(file) self._started = {} - self.summary = Summary(self.out) - self.summary.option = self.option self._opencollectors = [] # --------------------- From hpk at codespeak.net Fri Mar 4 13:27:08 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 13:27:08 +0100 (MET) Subject: [py-svn] r9623 - in py/branch/py-collect/test2: . report/testing report/text testing testing/data tool tool/testing Message-ID: <20050304122708.54B0627B53@code1.codespeak.net> Author: hpk Date: Fri Mar 4 13:27:07 2005 New Revision: 9623 Modified: py/branch/py-collect/test2/cmdline.py py/branch/py-collect/test2/collect.py py/branch/py-collect/test2/config.py py/branch/py-collect/test2/defaultconfig.py py/branch/py-collect/test2/drive.py py/branch/py-collect/test2/item.py py/branch/py-collect/test2/report/testing/test_memo.py py/branch/py-collect/test2/report/text/reporter.py py/branch/py-collect/test2/report/text/summary.py py/branch/py-collect/test2/run.py py/branch/py-collect/test2/terminal.py py/branch/py-collect/test2/testing/data/filetest.py py/branch/py-collect/test2/testing/test_api.py py/branch/py-collect/test2/testing/test_collect.py py/branch/py-collect/test2/testing/test_config.py py/branch/py-collect/test2/testing/test_drive.py py/branch/py-collect/test2/testing/test_setup_nested.py py/branch/py-collect/test2/tool/optparse.py py/branch/py-collect/test2/tool/outerrcapture.py py/branch/py-collect/test2/tool/testing/test_outerrcapture.py Log: intermediate checkin (test2 begins to do its work ...) Modified: py/branch/py-collect/test2/cmdline.py ============================================================================== --- py/branch/py-collect/test2/cmdline.py (original) +++ py/branch/py-collect/test2/cmdline.py Fri Mar 4 13:27:07 2005 @@ -1,30 +1,20 @@ from __future__ import generators import py import sys -from py.__impl__.test import run +from py.__impl__.test2 import run # # main entry point # -def _old(argv): - if argv is None: - argv = py.std.sys.argv - frame = py.std.sys._getframe(1) - name = frame.f_locals.get('__name__') - if name != '__main__': - return # called from an imported test file - import __main__ - return [py.test.collect.Module(py.std.sys.argv[0])] - def main(): args = py.std.sys.argv[1:] - py.test.config.readconfiguration(*run.getanchors(args)) + py.test2.config.readconfiguration(*run.getanchors(args)) - filenames = py.test.config.parseargs(args) + filenames = py.test2.config.parseargs(args) if not filenames: filenames.append(str(py.path.local())) - option = py.test.config.option + option = py.test2.config.option try: if option.session or option.executable: run.session(args, filenames) Modified: py/branch/py-collect/test2/collect.py ============================================================================== --- py/branch/py-collect/test2/collect.py (original) +++ py/branch/py-collect/test2/collect.py Fri Mar 4 13:27:07 2005 @@ -234,12 +234,12 @@ obj = property(obj, None, None, "module object") def setup(self): - if hasattr(self, 'setup_module'): - self.setup_module(self.obj) + if hasattr(self.obj, 'setup_module'): + self.obj.setup_module(self.obj) def teardown(self): - if hasattr(self, 'teardown_module'): - self.teardown_module(self.obj) + if hasattr(self.obj, 'teardown_module'): + self.obj.teardown_module(self.obj) class Class(PyCollectorMixin, Collector): def run(self): @@ -252,13 +252,15 @@ return self.Instance(name, self) def setup(self): - setup_class = self.obj.__dict__.get('setup_class', None) + setup_class = getattr(self.obj, 'setup_class', None) if setup_class is not None: + setup_class = getattr(setup_class, 'im_func', setup_class) setup_class(self.obj) def teardown(self): - teardown_class = self.obj.__dict__.get('teardown_class', None) + teardown_class = getattr(self.obj, 'teardown_class', None) if teardown_class is not None: + teardown_class = getattr(teardown_class, 'im_func', teardown_class) teardown_class(self.obj) class Instance(PyCollectorMixin, Collector): Modified: py/branch/py-collect/test2/config.py ============================================================================== --- py/branch/py-collect/test2/config.py (original) +++ py/branch/py-collect/test2/config.py Fri Mar 4 13:27:07 2005 @@ -1,7 +1,7 @@ from __future__ import generators import py -from py.__impl__.test.tool import optparse +from py.__impl__.test2.tool import optparse defaultconfig = py.magic.autopath().dirpath('defaultconfig.py') defaultconfig = py.path.extpy(defaultconfig) @@ -71,7 +71,7 @@ def parseargs(self, args): # first a small fight with optparse to merge the - # pytest.py file options correctly + # conftest.py file options correctly parser = optparse.OptionParser() for config in self.configpaths: meth = config.join('options') @@ -87,11 +87,10 @@ value = self.getfirst(option.dest, option.default) #print "setting %r to %r" %(option.dest, value) setattr(self.option, option.dest, value) - option.default = 'NODEFAULT' + #option.default = 'NODEFAULT' # parse cmdline args cmdlineoption, remaining = parser.parse_args(args, self.option) - self.fixoptions() # override previously computed defaults #for name in cmdlineoption.__dict__: Modified: py/branch/py-collect/test2/defaultconfig.py ============================================================================== --- py/branch/py-collect/test2/defaultconfig.py (original) +++ py/branch/py-collect/test2/defaultconfig.py Fri Mar 4 13:27:07 2005 @@ -1,5 +1,5 @@ import py -Option = py.test.Option +Option = py.test2.Option Module = py.test2.Module Directory = py.test2.Directory @@ -9,7 +9,7 @@ Instance = py.test2.Instance def getreporter(): - return py.test.TextReporter() + return py.test2.TextReporter() additionalinfo = None Modified: py/branch/py-collect/test2/drive.py ============================================================================== --- py/branch/py-collect/test2/drive.py (original) +++ py/branch/py-collect/test2/drive.py Fri Mar 4 13:27:07 2005 @@ -1,5 +1,5 @@ import py -from py.__impl__.test.tool.outerrcapture import SimpleOutErrCapture +from py.__impl__.test2.tool.outerrcapture import SimpleOutErrCapture class ShadowOptions(object): def __init__(self, obj): @@ -41,9 +41,6 @@ except AttributeError: pass self._memo.append((colitem, res)) - if isinstance(res, (colitem.Failed,)): - if self.option.exitfirstproblem: - exit("exit on first problem configured.", item=colitem) def getresults(self, cls): return [x for x in self._memo if isinstance(x[1], cls)] Modified: py/branch/py-collect/test2/item.py ============================================================================== --- py/branch/py-collect/test2/item.py (original) +++ py/branch/py-collect/test2/item.py Fri Mar 4 13:27:07 2005 @@ -9,7 +9,7 @@ def teardown_all(self): while self.stack: - col, item = self.stack.pop() + col = self.stack.pop() col.teardown() def prepare(self, colitem): @@ -18,16 +18,14 @@ """ needed_collectors = colitem.listchain() while self.stack: + if self.stack == needed_collectors[:len(self.stack)]: + break col = self.stack.pop() - try: - i = needed_collectors.index(col) - except ValueError: - col.teardown() - continue - else: - for col in needed_collectors[i+1:]: - col.setup() - self.stack.append(col) + col.teardown() + for col in needed_collectors[len(self.stack):]: + print "setting up", col + col.setup() + self.stack.append(col) class Item(py.test2.Collector): state = SetupState() @@ -70,12 +68,15 @@ return "%s%r" % (self.extpy.modpath, self.args) def setup(self): - if hasattr(self.obj, 'setup_function'): - return self.parent.setup_function(self.obj) + #print "checking setup_function", self, "parent=", self.parent + obj = self.parent.obj + if hasattr(obj, 'setup_function'): + return obj.setup_function(self.obj) def teardown(self): - if hasattr(self.obj, 'teardown_function'): - return self.parent.teardown_function(self.obj) + obj = self.parent.obj + if hasattr(obj, 'teardown_function'): + return obj.teardown_function(self.obj) # # triggering specific outcomes while executing Items Modified: py/branch/py-collect/test2/report/testing/test_memo.py ============================================================================== --- py/branch/py-collect/test2/report/testing/test_memo.py (original) +++ py/branch/py-collect/test2/report/testing/test_memo.py Fri Mar 4 13:27:07 2005 @@ -13,11 +13,11 @@ # def execute(self, runner): # try: # -def test_memoreporter(): - reporter = py.test.MemoReporter() +def XXtest_memoreporter(): + reporter = py.test2.MemoReporter() p = tmpdir.join('memoimport.py') p.write('raise IOError') - collector = py.test.collect.Module(p) + collector = py.test2.collect.Module(p) #main(collector=collector, reporter=reporter) #collect_errors = reporter.getlist(collect.Error) #assert len(collect_errors) == 1 Modified: py/branch/py-collect/test2/report/text/reporter.py ============================================================================== --- py/branch/py-collect/test2/report/text/reporter.py (original) +++ py/branch/py-collect/test2/report/text/reporter.py Fri Mar 4 13:27:07 2005 @@ -1,7 +1,7 @@ from __future__ import generators import py -Item = py.test.Item -Collector = py.test.collect.Collector +Item = py.test2.Item +Collector = py.test2.collect.Collector from time import time as now # lazy relative Implementation imports @@ -29,11 +29,11 @@ self.out = getout(f) self._started = {} self.summary = self.Summary(self.out) - self.summary.option = self.option = py.test.config.option + self.summary.option = self.option = py.test2.config.option def start(self): self.out.sep("=", "test process starts") - option = py.test.config.option + option = py.test2.config.option if option.session: mode = 'session/child process' elif option.executable: @@ -48,9 +48,9 @@ self.out.line("using py lib: %s " % ( py.path.local(py.__file__).dirpath(), rev)) - for i, x in py.builtin.enumerate(py.test.config.configpaths): + for i, x in py.builtin.enumerate(py.test2.config.configpaths): self.out.line("initial testconfig %d: %s" %(i, x)) - additional = py.test.config.getfirst('additionalinfo') + additional = py.test2.config.getfirst('additionalinfo') if additional: for key, descr in additional(): self.out.line("%s: %s" %(key, descr)) @@ -114,7 +114,7 @@ print "Item", item.extpy.modpath return if not self.option.nocapture: - from py.__impl__.test.tool.outerrcapture import SimpleOutErrCapture + from py.__impl__.test2.tool.outerrcapture import SimpleOutErrCapture item.iocapture = SimpleOutErrCapture() if self.out.tty: realpath, lineno = item.extpy.getfilelineno() @@ -138,9 +138,9 @@ restype, c = self.processresult(result) writeinfo = None if self.out.tty: - if not isinstance(result, py.test.Item.Passed) or self.option.verbose >=1: + if not isinstance(result, py.test2.Item.Passed) or self.option.verbose >=1: writeinfo = '\n' - elif isinstance(result, py.test.Item.Passed): + elif isinstance(result, py.test2.Item.Passed): writeinfo = '' elif self.option.verbose >= 1: writeinfo = '\n' Modified: py/branch/py-collect/test2/report/text/summary.py ============================================================================== --- py/branch/py-collect/test2/report/text/summary.py (original) +++ py/branch/py-collect/test2/report/text/summary.py Fri Mar 4 13:27:07 2005 @@ -1,6 +1,6 @@ from __future__ import generators import py -Item = py.test.Item +Item = py.test2.Item from py.__impl__.magic import exprinfo, assertion class Summary(object): @@ -31,7 +31,7 @@ self.out.line("[%s:%d]" % (err.filename, err.lineno)) def summary_collect_errors(self): - for error in self.getlist(py.test.collect.Error): + for error in self.getlist(py.test2.collect.Error): self.repr_collect_error(error) def render(self): Modified: py/branch/py-collect/test2/run.py ============================================================================== --- py/branch/py-collect/test2/run.py (original) +++ py/branch/py-collect/test2/run.py Fri Mar 4 13:27:07 2005 @@ -1,8 +1,8 @@ from __future__ import generators import py from py.__impl__.execnet.channel import ChannelFile, receive2file -from py.__impl__.test.config import configbasename -from py.__impl__.test.collect import getfscollector +from py.__impl__.test2.config import configbasename +from py.__impl__.test2.collect import getfscollector import sys def checkpyfilechange(rootdir, statcache): @@ -28,7 +28,7 @@ changed = True return changed -class FailingCollector(py.test.collect.Collector): +class FailingCollector(py.test2.Collector): def __init__(self, faileditems): self._faileditems = faileditems @@ -76,13 +76,13 @@ channel.gateway.exit() def failure_master(args, filenames, failures): - exe = py.test.config.option.executable + exe = py.test2.config.option.executable gw = py.execnet.PopenGateway(python=exe or sys.executable) outproxy = StdouterrProxy(gw) outproxy.setup() try: channel = gw.remote_exec(""" - from py.__impl__.test.run import failure_slave + from py.__impl__.test2.run import failure_slave failure_slave(channel) """) channel.send((args, filenames, failures)) @@ -94,18 +94,18 @@ """ we run this on the other side. """ args, filenames, failures = channel.receive() filenames = map(py.path.local, filenames) - py.test.config.readconfiguration(*filenames) - py.test.config.parseargs(args) + py.test2.config.readconfiguration(*filenames) + py.test2.config.parseargs(args) if failures: col = FailureCollector(failures) else: col = list(getcollectors(filenames)) - driver = py.test.Driver(channel) + driver = py.test2.Driver(channel) failures = driver.run(col) channel.send(failures) -class FailureCollector(py.test.collect.Collector): +class FailureCollector(py.test2.Collector): def __init__(self, failures): self.failures = failures def __iter__(self): @@ -136,23 +136,24 @@ # def inprocess(args, filenames): """ we run this on the other side. """ + print "inprocess" fncollectors = list(getcollectors(filenames)) - driver = py.test.Driver(None) - driver.run(fncollectors) + driver = py.test2.TerminalDriver() + driver.run(*fncollectors) def session(args, filenames): statcache = {} # XXX find out rootdir automatically with # something like py.magic.autopath() ? - rootdir = py.path.local(py.test.config.getfirst('rootdir', py.path.local())) + rootdir = py.path.local(py.test2.config.getfirst('rootdir', py.path.local())) l = len(str(rootdir)) failures = [] while 1: - if py.test.config.option.session: + if py.test2.config.option.session: while not checkpyfilechange(rootdir, statcache): py.std.time.sleep(0.4) failures = failure_master(args, filenames, failures) - if not py.test.config.option.session: + if not py.test2.config.option.session: break print "#" * 60 print "# session mode: %d failures remaining" % len(failures) Modified: py/branch/py-collect/test2/terminal.py ============================================================================== --- py/branch/py-collect/test2/terminal.py (original) +++ py/branch/py-collect/test2/terminal.py Fri Mar 4 13:27:07 2005 @@ -32,7 +32,23 @@ cols = self._opencollectors last = cols.pop() #assert last == colitem, "expected %r, got %r" %(last, colitem) - + return + if isinstance(res, (colitem.Failed,)): + print "checking", res + if self.option.exitfirstproblem: + py.test2.exit("exit on first problem configured.", item=colitem) + if self.option.usepdb: + if isinstance(res, Item.Failed): + print "dispatching to ppdb", colitem + self.repr_failure(colitem, res) + import pdb + self.out.rewrite( + '\n%s: %s\n' + % (res.excinfo.type.__name__, + res.excinfo.value)) + pdb.post_mortem(res.excinfo._excinfo[2]) + else: + self.repr_result(colitem, res) # ------------------- # HEADER information @@ -40,7 +56,7 @@ def header(self): super(TerminalDriver, self).header() self.out.sep("=", "test process starts") - option = py.test.config.option + option = py.test2.config.option if option.session: mode = 'session/child process' elif option.executable: @@ -55,9 +71,9 @@ self.out.line("using py lib: %s " % ( py.path.local(py.__file__).dirpath(), rev)) - for i, x in py.builtin.enumerate(py.test.config.configpaths): + for i, x in py.builtin.enumerate(py.test2.config.configpaths): self.out.line("initial testconfig %d: %s" %(i, x)) - additional = py.test.config.getfirst('additionalinfo') + additional = py.test2.config.getfirst('additionalinfo') if additional: for key, descr in additional(): self.out.line("%s: %s" %(key, descr)) @@ -76,6 +92,37 @@ self.failures() self.summaryline() + # -------------------- + # progress information + # -------------------- + typemap = { + Item.Passed: '.', + Item.Skipped: 's', + Item.Failed: 'F', + } + def _processresult(self, testresult): + for restype, char in self.typemap.items(): + if isinstance(testresult, restype): + return restype, char + else: + raise TypeError, "not a result instance: %r" % testresult + + def repr_result(self, colitem, result): + if result is None or not isinstance(colitem, py.test2.Item): + #print "colitem not represented", colitem + return + restype, c = self._processresult(result) + writeinfo = None + if self.out.tty: + if not isinstance(result, py.test2.Item.Passed) or self.option.verbose >=1: + writeinfo = '\n' + elif isinstance(result, py.test2.Item.Passed): + writeinfo = '' + elif self.option.verbose >= 1: + writeinfo = '\n' + else: + self.out.write(c) + def summaryline(self): outlist = [] sum = 0 Modified: py/branch/py-collect/test2/testing/data/filetest.py ============================================================================== --- py/branch/py-collect/test2/testing/data/filetest.py (original) +++ py/branch/py-collect/test2/testing/data/filetest.py Fri Mar 4 13:27:07 2005 @@ -2,6 +2,6 @@ def test_one(): assert 42 == 43 -class TestClass: +class TestClass(object): def test_method_one(self): assert 42 == 43 Modified: py/branch/py-collect/test2/testing/test_api.py ============================================================================== --- py/branch/py-collect/test2/testing/test_api.py (original) +++ py/branch/py-collect/test2/testing/test_api.py Fri Mar 4 13:27:07 2005 @@ -13,4 +13,4 @@ def test_skip_on_error_with_no_failure(): def f(): return 42 - assert py.test.skip_on_error(f) == 42 + assert py.test2.skip_on_error(f) == 42 Modified: py/branch/py-collect/test2/testing/test_collect.py ============================================================================== --- py/branch/py-collect/test2/testing/test_collect.py (original) +++ py/branch/py-collect/test2/testing/test_collect.py Fri Mar 4 13:27:07 2005 @@ -40,7 +40,7 @@ l = MyDirectory(datadir).run() assert len(l) == 1 assert isinstance(l[0], py.test2.Module) - py.test.raises(ImportError, l[0].run) + py.test2.raises(ImportError, l[0].run) def test_module_file_not_found(): fn = datadir.join('nada','no') @@ -50,7 +50,7 @@ def test_syntax_error_in_module(): modpath = py.path.extpy(datadir.join('syntax_error.py')) col = py.test2.Module(modpath) - py.test.raises(SyntaxError, col.run) + py.test2.raises(SyntaxError, col.run) def test_disabled_class(): col = py.test2.Module(datadir.join('disabled.py')) Modified: py/branch/py-collect/test2/testing/test_config.py ============================================================================== --- py/branch/py-collect/test2/testing/test_config.py (original) +++ py/branch/py-collect/test2/testing/test_config.py Fri Mar 4 13:27:07 2005 @@ -1,6 +1,6 @@ from __future__ import generators import py -config = py.test.config +config = py.test2.config class MyClass: def getoptions(self): @@ -28,8 +28,8 @@ assert d1 == d2 def test_config_order(): - from py.__impl__.test import config - o = py.test.config.tmpdir.ensure('configorder', dir=1) + from py.__impl__.test2 import config + o = py.test2.config.tmpdir.ensure('configorder', dir=1) o.ensure('conftest.py').write('x=1 ; import py ; py._x = [x]') o.ensure('a/conftest.py').write('x=2 ; import py ; py._x.append(x)') o.ensure('a/b/c/conftest.py').write('x=3 ; import py ; py._x.append(x)') @@ -44,9 +44,9 @@ assert py._x == [1,2,3] def test_getconfigvalue(): - from py.__impl__.test import config + from py.__impl__.test2 import config cfg = config.Config() - o = py.test.config.tmpdir.ensure('configtest', dir=1) + o = py.test2.config.tmpdir.ensure('configtest', dir=1) o.ensure('conftest.py').write('x=1') assert cfg.getconfigvalue(o, 'x') == 1 - py.test.raises(ValueError, "cfg.getconfigvalue(o, 'y')") + py.test2.raises(ValueError, "cfg.getconfigvalue(o, 'y')") Modified: py/branch/py-collect/test2/testing/test_drive.py ============================================================================== --- py/branch/py-collect/test2/testing/test_drive.py (original) +++ py/branch/py-collect/test2/testing/test_drive.py Fri Mar 4 13:27:07 2005 @@ -12,15 +12,6 @@ l = drive.getresults(py.test2.Item.Passed) assert not l - def test_exit_first_problem(self): - drive = py.test2.Driver() - drive.option.exitfirstproblem = True - drive.runpath(str(datadir / 'filetest.py')) - l = drive.getresults(py.test2.Item.Failed) - assert len(l) == 1 - l = drive.getresults(py.test2.Item.Passed) - assert not l - class TestTerminalDriver: def test_terminal(self): c = StringIO() @@ -35,6 +26,16 @@ assert len(l) == 2 assert out.find('2 failed') != -1 + def test_exit_first_problem(self): + drive = py.test2.TerminalDriver() + drive.option.exitfirstproblem = True + drive.runpath(str(datadir / 'filetest.py')) + l = drive.getresults(py.test2.Item.Failed) + assert len(l) == 1 + l = drive.getresults(py.test2.Item.Passed) + assert not l + + def test_collectonly(self): c = StringIO() drive = py.test2.TerminalDriver(file=c) Modified: py/branch/py-collect/test2/testing/test_setup_nested.py ============================================================================== --- py/branch/py-collect/test2/testing/test_setup_nested.py (original) +++ py/branch/py-collect/test2/testing/test_setup_nested.py Fri Mar 4 13:27:07 2005 @@ -5,6 +5,7 @@ modlevel = [] def setup_module(module): + assert not modlevel module.modlevel.append(42) def teardown_module(module): @@ -32,6 +33,7 @@ assert self.clslevel[0] == 23 def test_modulelevel(self): + print modlevel assert modlevel == [42] class TestInheritedClassSetupStillWorks(TestSimpleClassSetup): Modified: py/branch/py-collect/test2/tool/optparse.py ============================================================================== --- py/branch/py-collect/test2/tool/optparse.py (original) +++ py/branch/py-collect/test2/tool/optparse.py Fri Mar 4 13:27:07 2005 @@ -69,7 +69,7 @@ import sys, os import types -from py.__impl__.test.tool import textwrap +from py.__impl__.test2.tool import textwrap class OptParseError (Exception): def __init__ (self, msg): Modified: py/branch/py-collect/test2/tool/outerrcapture.py ============================================================================== --- py/branch/py-collect/test2/tool/outerrcapture.py (original) +++ py/branch/py-collect/test2/tool/outerrcapture.py Fri Mar 4 13:27:07 2005 @@ -28,6 +28,7 @@ o,e = sys.stdout, sys.stderr sys.stdout, sys.stderr = self.oldout, self.olderr del self.oldout, self.olderr + o, e = self.newout, self.newerr o.seek(0) e.seek(0) return o,e Modified: py/branch/py-collect/test2/tool/testing/test_outerrcapture.py ============================================================================== --- py/branch/py-collect/test2/tool/testing/test_outerrcapture.py (original) +++ py/branch/py-collect/test2/tool/testing/test_outerrcapture.py Fri Mar 4 13:27:07 2005 @@ -1,6 +1,6 @@ import sys import py -from py.__impl__.test.tool.outerrcapture import SimpleOutErrCapture +from py.__impl__.test2.tool.outerrcapture import SimpleOutErrCapture def test_capturing_simple(): cap = SimpleOutErrCapture() @@ -14,7 +14,7 @@ cap = SimpleOutErrCapture() print "hello" cap.reset() - py.test.raises(AttributeError, "cap.reset()") + py.test2.raises(AttributeError, "cap.reset()") def test_capturing_modify_sysouterr_in_between(): oldout = sys.stdout @@ -37,4 +37,4 @@ cap2 = SimpleOutErrCapture() print "hello" cap2.reset() - py.test.raises(AttributeError, "cap2.reset()") + py.test2.raises(AttributeError, "cap2.reset()") From hpk at codespeak.net Fri Mar 4 16:36:45 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 16:36:45 +0100 (MET) Subject: [py-svn] r9637 - in py/branch/py-collect/test2: . testing Message-ID: <20050304153645.B294B27B8E@code1.codespeak.net> Author: hpk Date: Fri Mar 4 16:36:45 2005 New Revision: 9637 Modified: py/branch/py-collect/test2/cmdline.py py/branch/py-collect/test2/config.py py/branch/py-collect/test2/drive.py py/branch/py-collect/test2/item.py py/branch/py-collect/test2/terminal.py py/branch/py-collect/test2/testing/test_drive.py Log: reintegrating reporting functionality into the TerminalDriver Modified: py/branch/py-collect/test2/cmdline.py ============================================================================== --- py/branch/py-collect/test2/cmdline.py (original) +++ py/branch/py-collect/test2/cmdline.py Fri Mar 4 16:36:45 2005 @@ -10,7 +10,6 @@ def main(): args = py.std.sys.argv[1:] py.test2.config.readconfiguration(*run.getanchors(args)) - filenames = py.test2.config.parseargs(args) if not filenames: filenames.append(str(py.path.local())) Modified: py/branch/py-collect/test2/config.py ============================================================================== --- py/branch/py-collect/test2/config.py (original) +++ py/branch/py-collect/test2/config.py Fri Mar 4 16:36:45 2005 @@ -8,7 +8,7 @@ dummy = object() # -# config file handling (utest.conf) +# configuration file handling # configbasename = 'conftest.py' Modified: py/branch/py-collect/test2/drive.py ============================================================================== --- py/branch/py-collect/test2/drive.py (original) +++ py/branch/py-collect/test2/drive.py Fri Mar 4 16:36:45 2005 @@ -76,6 +76,7 @@ res = None raise except colitem.Outcome, res: + res.excinfo = py.code.ExceptionInfo() pass except: excinfo = py.code.ExceptionInfo() Modified: py/branch/py-collect/test2/item.py ============================================================================== --- py/branch/py-collect/test2/item.py (original) +++ py/branch/py-collect/test2/item.py Fri Mar 4 16:36:45 2005 @@ -23,7 +23,7 @@ col = self.stack.pop() col.teardown() for col in needed_collectors[len(self.stack):]: - print "setting up", col + #print "setting up", col col.setup() self.stack.append(col) @@ -65,7 +65,7 @@ """ return a string representing a call to the underlying test function. """ - return "%s%r" % (self.extpy.modpath, self.args) + return "%s%r" % (self.getmodpath(), self.args) def setup(self): #print "checking setup_function", self, "parent=", self.parent Modified: py/branch/py-collect/test2/terminal.py ============================================================================== --- py/branch/py-collect/test2/terminal.py (original) +++ py/branch/py-collect/test2/terminal.py Fri Mar 4 16:36:45 2005 @@ -27,16 +27,13 @@ def finish(self, colitem, res): end = now() - super(TerminalDriver, self).finish(colitem, res) + colitem.elapsedtime = end - self._started[colitem] if self.option.collectonly: cols = self._opencollectors last = cols.pop() #assert last == colitem, "expected %r, got %r" %(last, colitem) return - if isinstance(res, (colitem.Failed,)): - print "checking", res - if self.option.exitfirstproblem: - py.test2.exit("exit on first problem configured.", item=colitem) + super(TerminalDriver, self).finish(colitem, res) if self.option.usepdb: if isinstance(res, Item.Failed): print "dispatching to ppdb", colitem @@ -47,8 +44,10 @@ % (res.excinfo.type.__name__, res.excinfo.value)) pdb.post_mortem(res.excinfo._excinfo[2]) - else: - self.repr_result(colitem, res) + if isinstance(res, (colitem.Failed,)): + if self.option.exitfirstproblem: + py.test2.exit("exit on first problem configured.", item=colitem) + self.repr_result(colitem, res) # ------------------- # HEADER information @@ -56,7 +55,7 @@ def header(self): super(TerminalDriver, self).header() self.out.sep("=", "test process starts") - option = py.test2.config.option + option = self.option if option.session: mode = 'session/child process' elif option.executable: @@ -100,6 +99,12 @@ Item.Skipped: 's', Item.Failed: 'F', } + namemap = { + Item.Passed: 'ok', + Item.Skipped: 'SKIP', + Item.Failed: 'FAIL', + } + def _processresult(self, testresult): for restype, char in self.typemap.items(): if isinstance(testresult, restype): @@ -122,7 +127,18 @@ writeinfo = '\n' else: self.out.write(c) + if writeinfo is not None: + realpath, lineno = colitem.getpathlineno() + location = "%s:%d" % (realpath.basename, lineno+1) + resultstring = self.namemap.get(restype, result.__class__.__name__) + self.out.rewrite("%.3f %-2s %-20s %s%s" % ( + colitem.elapsedtime, resultstring, location, + colitem.reprcall(), writeinfo + )) + # -------------------- + # summary information + # -------------------- def summaryline(self): outlist = [] sum = 0 Modified: py/branch/py-collect/test2/testing/test_drive.py ============================================================================== --- py/branch/py-collect/test2/testing/test_drive.py (original) +++ py/branch/py-collect/test2/testing/test_drive.py Fri Mar 4 16:36:45 2005 @@ -28,6 +28,8 @@ def test_exit_first_problem(self): drive = py.test2.TerminalDriver() + if drive.option.usepdb: + py.test2.skip("options of sub-runs are not isolated") drive.option.exitfirstproblem = True drive.runpath(str(datadir / 'filetest.py')) l = drive.getresults(py.test2.Item.Failed) From hpk at codespeak.net Fri Mar 4 16:54:34 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 16:54:34 +0100 (MET) Subject: [py-svn] r9638 - in py/branch/py-collect/test2: . testing Message-ID: <20050304155434.850D927B97@code1.codespeak.net> Author: hpk Date: Fri Mar 4 16:54:34 2005 New Revision: 9638 Modified: py/branch/py-collect/test2/item.py py/branch/py-collect/test2/testing/test_setup_nested.py Log: fix setup/teardown for methods Modified: py/branch/py-collect/test2/item.py ============================================================================== --- py/branch/py-collect/test2/item.py (original) +++ py/branch/py-collect/test2/item.py Fri Mar 4 16:54:34 2005 @@ -68,15 +68,24 @@ return "%s%r" % (self.getmodpath(), self.args) def setup(self): - #print "checking setup_function", self, "parent=", self.parent + if getattr(self.obj, 'im_self', None): + name = 'setup_method' + else: + name = 'setup_function' obj = self.parent.obj - if hasattr(obj, 'setup_function'): - return obj.setup_function(self.obj) + meth = getattr(obj, name, None) + if meth is not None: + return meth(self.obj) def teardown(self): + if getattr(self.obj, 'im_self', None): + name = 'teardown_method' + else: + name = 'teardown_function' obj = self.parent.obj - if hasattr(obj, 'teardown_function'): - return obj.teardown_function(self.obj) + meth = getattr(obj, name, None) + if meth is not None: + return meth(self.obj) # # triggering specific outcomes while executing Items Modified: py/branch/py-collect/test2/testing/test_setup_nested.py ============================================================================== --- py/branch/py-collect/test2/testing/test_setup_nested.py (original) +++ py/branch/py-collect/test2/testing/test_setup_nested.py Fri Mar 4 16:54:34 2005 @@ -40,7 +40,7 @@ def test_classlevel_anothertime(self): assert self.clslevel == [23] -class SetupTeardownOnInstance(TestSimpleClassSetup): +class TestSetupTeardownOnInstance(TestSimpleClassSetup): def setup_method(self, method): self.clslevel.append(17) @@ -51,3 +51,5 @@ def test_setup(self): assert self.clslevel[-1] == 17 +def test_teardown_method_worked(): + assert not TestSetupTeardownOnInstance.clslevel From hpk at codespeak.net Fri Mar 4 18:21:51 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 18:21:51 +0100 (MET) Subject: [py-svn] r9642 - in py/dist/py: . code code/testing Message-ID: <20050304172151.3427827B88@code1.codespeak.net> Author: hpk Date: Fri Mar 4 18:21:50 2005 New Revision: 9642 Added: py/dist/py/code/code.py - copied, changed from r9470, py/dist/py/code/frame.py py/dist/py/code/testing/test_code.py (contents, props changed) Modified: py/dist/py/__init__.py py/dist/py/code/frame.py py/dist/py/code/source.py py/dist/py/code/testing/test_source.py py/dist/py/code/traceback.py (props changed) Log: refactored py.code.Code() to directly offer a convienent new() method that returns a raw code object with modified attributes. Now you can say: py.code.Code(rawpycode).new(co_filename="newfilename") and this returns a cpython code object with a modified co_filename. if you specify rec=True like so: py.code.Code(rawpycode).new(rec=True, co_filename="newfilename") then you will get a raw python code object where all the inner code object have their co_filename changed as well. We might later want to allow passing a function instead of just true as a value for "rec" to change code objects more dynamically ... added a couple of tests. Modified: py/dist/py/__init__.py ============================================================================== --- py/dist/py/__init__.py (original) +++ py/dist/py/__init__.py Fri Mar 4 18:21:50 2005 @@ -42,7 +42,7 @@ 'code.compile' : ('./code/source.py', 'compile_'), 'code.Source' : ('./code/source.py', 'Source'), - 'code.Code' : ('./code/frame.py', 'Code'), + 'code.Code' : ('./code/code.py', 'Code'), 'code.Frame' : ('./code/frame.py', 'Frame'), 'code.ExceptionInfo' : ('./code/excinfo.py', 'ExceptionInfo'), 'code.Traceback' : ('./code/traceback.py', 'Traceback'), Copied: py/dist/py/code/code.py (from r9470, py/dist/py/code/frame.py) ============================================================================== --- py/dist/py/code/frame.py (original) +++ py/dist/py/code/code.py Fri Mar 4 18:21:50 2005 @@ -1,10 +1,51 @@ import py class Code(object): - def __init__(self, f_code): - self.raw = f_code - self.firstlineno = f_code.co_firstlineno - 1 - self.name = f_code.co_name + def __init__(self, rawcode): + self.raw = rawcode + self.firstlineno = rawcode.co_firstlineno - 1 + self.name = rawcode.co_name + + def __eq__(self, other): + return self.raw == other.raw + + def new(self, rec=False, **kwargs): + """ return new code object with modified attributes. + if rec-cursive is true then dive into code + objects contained in co_consts. + """ + names = [x for x in dir(self.raw) if x[:3] == 'co_'] + for name in kwargs: + if name not in names: + raise TypeError("unknown code attribute: %r" %(name, )) + if rec: + newconstlist = [] + co = self.raw + cotype = type(co) + for c in co.co_consts: + if isinstance(c, cotype): + c = self.__class__(c).new(rec=True, **kwargs) + newconstlist.append(c) + return self.new(rec=False, co_consts=tuple(newconstlist), **kwargs) + for name in names: + if name not in kwargs: + kwargs[name] = getattr(self.raw, name) + return py.std.new.code( + kwargs['co_argcount'], + kwargs['co_nlocals'], + kwargs['co_stacksize'], + kwargs['co_flags'], + kwargs['co_code'], + kwargs['co_consts'], + kwargs['co_names'], + kwargs['co_varnames'], + kwargs['co_filename'], + kwargs['co_name'], + kwargs['co_firstlineno'], + kwargs['co_lnotab'], + kwargs['co_freevars'], + kwargs['co_cellvars'], + ) def path(self): try: @@ -22,34 +63,3 @@ fullsource = property(fullsource, None, None, "full source containing this code object") - -class Frame(object): - """Wrapper around a Python frame holding f_locals and f_globals - in which expressions can be evaluated.""" - - def __init__(self, frame): - self.code = Code(frame.f_code) - self.lineno = frame.f_lineno - 1 - self.f_globals = frame.f_globals - self.f_locals = frame.f_locals - - def statement(self): - return self.code.fullsource.getstatement(self.lineno) - statement = property(statement, None, None, - "statement this frame is at") - - def eval(self, code, **vars): - self.f_locals.update(vars) - return eval(code, self.f_globals, self.f_locals) - - def exec_(self, code, **vars): - self.f_locals.update(vars) - exec code in self.f_globals, self.f_locals - - def repr(self, object): - return repr(object) - - def is_true(self, object): - return object - - Modified: py/dist/py/code/frame.py ============================================================================== --- py/dist/py/code/frame.py (original) +++ py/dist/py/code/frame.py Fri Mar 4 18:21:50 2005 @@ -1,34 +1,11 @@ import py -class Code(object): - def __init__(self, f_code): - self.raw = f_code - self.firstlineno = f_code.co_firstlineno - 1 - self.name = f_code.co_name - - def path(self): - try: - return self.raw.co_filename.__path__ - except AttributeError: - return py.path.local(self.raw.co_filename) - path = property(path, None, None, "path of this code object") - - def fullsource(self): - fn = self.raw.co_filename - try: - return fn.__source__ - except AttributeError: - return py.code.Source(self.path.read(mode="rU")) - fullsource = property(fullsource, None, None, - "full source containing this code object") - - class Frame(object): """Wrapper around a Python frame holding f_locals and f_globals in which expressions can be evaluated.""" def __init__(self, frame): - self.code = Code(frame.f_code) + self.code = py.code.Code(frame.f_code) self.lineno = frame.f_lineno - 1 self.f_globals = frame.f_globals self.f_locals = frame.f_locals Modified: py/dist/py/code/source.py ============================================================================== --- py/dist/py/code/source.py (original) +++ py/dist/py/code/source.py Fri Mar 4 18:21:50 2005 @@ -193,7 +193,8 @@ else: co_filename = MyStr(filename) co_filename.__source__ = self - return newcode_withfilename(co, co_filename) + return py.code.Code(co).new(rec=1, co_filename=co_filename) + #return newcode_withfilename(co, co_filename) # # public API shortcut functions @@ -255,36 +256,3 @@ newlines.append(line) return newlines -def newcode(fromcode, **kwargs): - names = [x for x in dir(fromcode) if x[:3] == 'co_'] - for name in names: - if name not in kwargs: - kwargs[name] = getattr(fromcode, name) - import new - return new.code( - kwargs['co_argcount'], - kwargs['co_nlocals'], - kwargs['co_stacksize'], - kwargs['co_flags'], - kwargs['co_code'], - kwargs['co_consts'], - kwargs['co_names'], - kwargs['co_varnames'], - kwargs['co_filename'], - kwargs['co_name'], - kwargs['co_firstlineno'], - kwargs['co_lnotab'], - kwargs['co_freevars'], - kwargs['co_cellvars'], - ) - -def newcode_withfilename(co, co_filename): - newconstlist = [] - cotype = type(co) - for c in co.co_consts: - if isinstance(c, cotype): - c = newcode_withfilename(c, co_filename) - newconstlist.append(c) - return newcode(co, co_consts = tuple(newconstlist), - co_filename = co_filename) - Added: py/dist/py/code/testing/test_code.py ============================================================================== --- (empty file) +++ py/dist/py/code/testing/test_code.py Fri Mar 4 18:21:50 2005 @@ -0,0 +1,50 @@ +import py + +def test_newcode(): + source = "i = 3" + co = compile(source, '', 'exec') + code = py.code.Code(co) + newco = code.new() + assert co == newco + +def test_newcode_unknown_args(): + code = py.code.Code(compile("", '', 'exec')) + py.test.raises(TypeError, 'code.new(filename="hello")') + +def test_newcode_withfilename(): + source = py.code.Source(""" + def f(): + def g(): + pass + """) + co = compile(str(source)+'\n', 'nada', 'exec') + obj = 'hello' + newco = py.code.Code(co).new(rec=True, co_filename=obj) + def walkcode(co): + for x in co.co_consts: + if isinstance(x, type(co)): + for y in walkcode(x): + yield y + yield co + + names = [] + for code in walkcode(newco): + assert newco.co_filename == obj + assert newco.co_filename is obj + names.append(code.co_name) + assert 'f' in names + assert 'g' in names + +def test_newcode_with_filename(): + source = "i = 3" + co = compile(source, '', 'exec') + code = py.code.Code(co) + class MyStr(str): + pass + filename = MyStr("hello") + filename.__source__ = py.code.Source(source) + newco = code.new(rec=True, co_filename=filename) + assert newco.co_filename is filename + s = py.code.Source(newco) + assert str(s) == source + Modified: py/dist/py/code/testing/test_source.py ============================================================================== --- py/dist/py/code/testing/test_source.py (original) +++ py/dist/py/code/testing/test_source.py Fri Mar 4 18:21:50 2005 @@ -109,41 +109,6 @@ l = [x for x in self.source] assert len(l) == 4 - -class TestCodeHacks: - def test_newcode(self): - from py.__impl__.code.source import newcode - def f(): - pass - co_filename = 'hello' - c = newcode(f.func_code, co_filename=co_filename) - assert c.co_filename is co_filename - - def test_newcode_withfilename(self): - from py.__impl__.code.source import newcode_withfilename - source = py.code.Source(""" - def f(): - def g(): - pass - """) - co = compile(str(source)+'\n', 'nada', 'exec') - obj = 'hello' - newco = newcode_withfilename(co, obj) - def walkcode(co): - for x in co.co_consts: - if isinstance(x, type(co)): - for y in walkcode(x): - yield y - yield co - - names = [] - for code in walkcode(newco): - assert newco.co_filename == obj - assert newco.co_filename is obj - names.append(code.co_name) - assert 'f' in names - assert 'g' in names - class TestSourceParsingAndCompiling: source = Source("""\ def f(x): From hpk at codespeak.net Fri Mar 4 18:35:31 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 18:35:31 +0100 (MET) Subject: [py-svn] r9643 - py/branch/py-collect/test2 Message-ID: <20050304173531.05D5627B8D@code1.codespeak.net> Author: hpk Date: Fri Mar 4 18:35:31 2005 New Revision: 9643 Modified: py/branch/py-collect/test2/terminal.py Log: fixes to output Modified: py/branch/py-collect/test2/terminal.py ============================================================================== --- py/branch/py-collect/test2/terminal.py (original) +++ py/branch/py-collect/test2/terminal.py Fri Mar 4 18:35:31 2005 @@ -24,6 +24,12 @@ self.out.line(' ' * len(cols) + repr(colitem)) cols.append(colitem) self._started[colitem] = now() + if self.option.verbose >= 1: + if isinstance(colitem, py.test2.Item): + realpath, lineno = colitem.getpathlineno() + location = "%s:%d" % (realpath.basename, lineno+1) + self.out.rewrite("%-20s %s " % ( + location, colitem.reprcall())) def finish(self, colitem, res): end = now() @@ -117,24 +123,11 @@ #print "colitem not represented", colitem return restype, c = self._processresult(result) - writeinfo = None - if self.out.tty: - if not isinstance(result, py.test2.Item.Passed) or self.option.verbose >=1: - writeinfo = '\n' - elif isinstance(result, py.test2.Item.Passed): - writeinfo = '' - elif self.option.verbose >= 1: - writeinfo = '\n' - else: - self.out.write(c) - if writeinfo is not None: - realpath, lineno = colitem.getpathlineno() - location = "%s:%d" % (realpath.basename, lineno+1) + if self.option.verbose >= 1: resultstring = self.namemap.get(restype, result.__class__.__name__) - self.out.rewrite("%.3f %-2s %-20s %s%s" % ( - colitem.elapsedtime, resultstring, location, - colitem.reprcall(), writeinfo - )) + self.out.line(resultstring) + else: + self.out.write(c) # -------------------- # summary information From hpk at codespeak.net Fri Mar 4 19:47:56 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 19:47:56 +0100 (MET) Subject: [py-svn] r9645 - in py/branch/py-collect: c-extension misc/testing test2 Message-ID: <20050304184756.A877B27B96@code1.codespeak.net> Author: hpk Date: Fri Mar 4 19:47:56 2005 New Revision: 9645 Modified: py/branch/py-collect/c-extension/ (props changed) py/branch/py-collect/misc/testing/test_initpkg.py py/branch/py-collect/test2/collect.py py/branch/py-collect/test2/drive.py py/branch/py-collect/test2/terminal.py Log: port some more reporting functionality to the driver Modified: py/branch/py-collect/misc/testing/test_initpkg.py ============================================================================== --- py/branch/py-collect/misc/testing/test_initpkg.py (original) +++ py/branch/py-collect/misc/testing/test_initpkg.py Fri Mar 4 19:47:56 2005 @@ -50,6 +50,7 @@ yield check_import, modpath def check_import(modpath): + #print "checking import", modpath assert __import__(modpath) def test_shahexdigest(): Modified: py/branch/py-collect/test2/collect.py ============================================================================== --- py/branch/py-collect/test2/collect.py (original) +++ py/branch/py-collect/test2/collect.py Fri Mar 4 19:47:56 2005 @@ -272,14 +272,23 @@ class Generator(Collector): def run(self): + #def iterator(): + # for i,x in py.builtin.enumerate(self.obj()): + # yield self.join("[%d]" % i) + #return py.builtin.collect(iterator()) + self._objlist = list(self.obj()) return [self.join("[%d]" % i) - for i in range(len(list(self.obj())))] + for i in range(len(self._objlist))] def join(self, name): if name[:1] != '[' or name[-1:] != ']': raise NameError("%r is not an index" %(name,)) num = int(name[1:-1]) - for i, x in py.builtin.enumerate(self.obj()): + try: + objlist = self._objlist + except AttributeError: + self._objlist = objlist = list(self.obj()) + for i, x in py.builtin.enumerate(objlist): if i == num: if isinstance(x, (Collector, )): return x Modified: py/branch/py-collect/test2/drive.py ============================================================================== --- py/branch/py-collect/test2/drive.py (original) +++ py/branch/py-collect/test2/drive.py Fri Mar 4 19:47:56 2005 @@ -82,7 +82,8 @@ excinfo = py.code.ExceptionInfo() res = colitem.Failed(excinfo=excinfo) else: - assert res is None or isinstance(res, (list, colitem.Outcome)) + assert (res is None or isinstance(res, (list, colitem.Outcome)) or + isinstance(res, py.builtin.collect)) finally: self.finish(colitem, res) Modified: py/branch/py-collect/test2/terminal.py ============================================================================== --- py/branch/py-collect/test2/terminal.py (original) +++ py/branch/py-collect/test2/terminal.py Fri Mar 4 19:47:56 2005 @@ -23,15 +23,36 @@ cols = self._opencollectors self.out.line(' ' * len(cols) + repr(colitem)) cols.append(colitem) - self._started[colitem] = now() + else: + if isinstance(colitem, py.test2.Module): + numunits = len(list(colitem.iteritems())) + if numunits > 0: + fspath = colitem.fspath + if self.option.verbose == 0: + parts = fspath.parts() + basename = parts.pop().basename + while parts and parts[-1].basename in ('testing', 'test'): + parts.pop() + base = parts[-1].basename + if len(base) < 13: + base = base + "_" * (13-len(base)) + abbrev_fn = base + "_" + basename + self.out.write('%s[%d] ' % (abbrev_fn, numunits)) + elif self.option.verbose > 0: + #curdir = py.path.local() + #if fspath.check(local=True, relto=curdir): + # fspath = fspath.relto(curdir) + self.out.line() + self.out.line("+ testmodule: %s" % fspath) if self.option.verbose >= 1: if isinstance(colitem, py.test2.Item): realpath, lineno = colitem.getpathlineno() location = "%s:%d" % (realpath.basename, lineno+1) self.out.rewrite("%-20s %s " % ( location, colitem.reprcall())) + self._started[colitem] = now() - def finish(self, colitem, res): + def finish(self, colitem, result): end = now() colitem.elapsedtime = end - self._started[colitem] if self.option.collectonly: @@ -39,21 +60,26 @@ last = cols.pop() #assert last == colitem, "expected %r, got %r" %(last, colitem) return - super(TerminalDriver, self).finish(colitem, res) + super(TerminalDriver, self).finish(colitem, result) if self.option.usepdb: - if isinstance(res, Item.Failed): + if isinstance(result, Item.Failed): print "dispatching to ppdb", colitem - self.repr_failure(colitem, res) + self.repr_failure(colitem, result) import pdb self.out.rewrite( '\n%s: %s\n' - % (res.excinfo.type.__name__, - res.excinfo.value)) - pdb.post_mortem(res.excinfo._excinfo[2]) - if isinstance(res, (colitem.Failed,)): + % (result.excinfo.type.__name__, + result.excinfo.value)) + pdb.post_mortem(result.excinfo._excinfo[2]) + if isinstance(result, (colitem.Failed,)): if self.option.exitfirstproblem: py.test2.exit("exit on first problem configured.", item=colitem) - self.repr_result(colitem, res) + if result is None or not isinstance(colitem, py.test2.Item): + if isinstance(colitem, py.test2.Module) and self.option.verbose == 0: + self.out.line() + return + else: + self.repr_progress(colitem, result) # ------------------- # HEADER information @@ -118,10 +144,7 @@ else: raise TypeError, "not a result instance: %r" % testresult - def repr_result(self, colitem, result): - if result is None or not isinstance(colitem, py.test2.Item): - #print "colitem not represented", colitem - return + def repr_progress(self, colitem, result): restype, c = self._processresult(result) if self.option.verbose >= 1: resultstring = self.namemap.get(restype, result.__class__.__name__) From hpk at codespeak.net Fri Mar 4 20:06:31 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 20:06:31 +0100 (MET) Subject: [py-svn] r9646 - py/branch/py-collect/test2 Message-ID: <20050304190631.CE96127B9A@code1.codespeak.net> Author: hpk Date: Fri Mar 4 20:06:31 2005 New Revision: 9646 Modified: py/branch/py-collect/test2/terminal.py Log: more refactored reporting Modified: py/branch/py-collect/test2/terminal.py ============================================================================== --- py/branch/py-collect/test2/terminal.py (original) +++ py/branch/py-collect/test2/terminal.py Fri Mar 4 20:06:31 2005 @@ -24,42 +24,53 @@ self.out.line(' ' * len(cols) + repr(colitem)) cols.append(colitem) else: - if isinstance(colitem, py.test2.Module): - numunits = len(list(colitem.iteritems())) - if numunits > 0: - fspath = colitem.fspath - if self.option.verbose == 0: - parts = fspath.parts() - basename = parts.pop().basename - while parts and parts[-1].basename in ('testing', 'test'): - parts.pop() - base = parts[-1].basename - if len(base) < 13: - base = base + "_" * (13-len(base)) - abbrev_fn = base + "_" + basename - self.out.write('%s[%d] ' % (abbrev_fn, numunits)) - elif self.option.verbose > 0: - #curdir = py.path.local() - #if fspath.check(local=True, relto=curdir): - # fspath = fspath.relto(curdir) - self.out.line() - self.out.line("+ testmodule: %s" % fspath) + cls = getattr(colitem, '__class__', None) + if cls is None: + return + for typ in py.std.inspect.getmro(cls): + meth = getattr(self, 'start_%s' % typ.__name__, None) + if meth: + meth(colitem) + break + colitem.start = py.std.time.time() + + def start_Module(self, colitem): + numunits = len(list(colitem.iteritems())) + if numunits > 0: + fspath = colitem.fspath + if self.option.verbose == 0: + parts = fspath.parts() + basename = parts.pop().basename + while parts and parts[-1].basename in ('testing', 'test'): + parts.pop() + base = parts[-1].basename + if len(base) < 13: + base = base + "_" * (13-len(base)) + abbrev_fn = base + "_" + basename + self.out.write('%s[%d] ' % (abbrev_fn, numunits)) + elif self.option.verbose > 0: + #curdir = py.path.local() + #if fspath.check(local=True, relto=curdir): + # fspath = fspath.relto(curdir) + self.out.line() + self.out.line("+ testmodule: %s" % fspath) + + def start_Item(self, colitem): if self.option.verbose >= 1: if isinstance(colitem, py.test2.Item): realpath, lineno = colitem.getpathlineno() location = "%s:%d" % (realpath.basename, lineno+1) self.out.rewrite("%-20s %s " % ( location, colitem.reprcall())) - self._started[colitem] = now() def finish(self, colitem, result): end = now() - colitem.elapsedtime = end - self._started[colitem] if self.option.collectonly: cols = self._opencollectors last = cols.pop() #assert last == colitem, "expected %r, got %r" %(last, colitem) return + colitem.elapsedtime = end - colitem.start super(TerminalDriver, self).finish(colitem, result) if self.option.usepdb: if isinstance(result, Item.Failed): @@ -79,7 +90,13 @@ self.out.line() return else: - self.repr_progress(colitem, result) + restype, c = self._processresult(result) + if self.option.verbose >= 1: + resultstring = self.namemap.get(restype, result.__class__.__name__) + resultstring += " (%.2f)" % (colitem.elapsedtime,) + self.out.line(resultstring) + else: + self.out.write(c) # ------------------- # HEADER information @@ -144,14 +161,6 @@ else: raise TypeError, "not a result instance: %r" % testresult - def repr_progress(self, colitem, result): - restype, c = self._processresult(result) - if self.option.verbose >= 1: - resultstring = self.namemap.get(restype, result.__class__.__name__) - self.out.line(resultstring) - else: - self.out.write(c) - # -------------------- # summary information # -------------------- From hpk at codespeak.net Fri Mar 4 20:13:31 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 20:13:31 +0100 (MET) Subject: [py-svn] r9647 - in py/branch/py-collect: . path/local/testing path/testing test test2 test2/report/testing test2/report/text test2/testing test2/tool test2/tool/testing Message-ID: <20050304191331.1701F27B96@code1.codespeak.net> Author: hpk Date: Fri Mar 4 20:13:30 2005 New Revision: 9647 Removed: py/branch/py-collect/test/ Modified: py/branch/py-collect/__init__.py py/branch/py-collect/path/local/testing/test_local.py py/branch/py-collect/path/testing/fscommon.py py/branch/py-collect/test2/cmdline.py py/branch/py-collect/test2/collect.py py/branch/py-collect/test2/config.py py/branch/py-collect/test2/defaultconfig.py py/branch/py-collect/test2/drive.py py/branch/py-collect/test2/item.py py/branch/py-collect/test2/raises.py py/branch/py-collect/test2/report/testing/test_memo.py py/branch/py-collect/test2/report/text/reporter.py py/branch/py-collect/test2/report/text/summary.py py/branch/py-collect/test2/run.py py/branch/py-collect/test2/terminal.py py/branch/py-collect/test2/testing/test_api.py py/branch/py-collect/test2/testing/test_collect.py py/branch/py-collect/test2/testing/test_config.py py/branch/py-collect/test2/testing/test_drive.py py/branch/py-collect/test2/tool/optparse.py py/branch/py-collect/test2/tool/testing/test_outerrcapture.py Log: intermediate checking, heading towards merging the branch now Modified: py/branch/py-collect/__init__.py ============================================================================== --- py/branch/py-collect/__init__.py (original) +++ py/branch/py-collect/__init__.py Fri Mar 4 20:13:30 2005 @@ -6,41 +6,18 @@ 'test.fail' : ('./test/item.py', 'fail'), 'test.exit' : ('./test/drive.py', 'exit'), 'test.config' : ('./test/config.py', 'config'), - 'test.compat.TestCase' : ('./test/compat.py', 'TestCase'), - 'test.collect.Directory' : ('./test/collect.py', 'Directory'), - 'test.collect.PyCollector': ('./test/collect.py', 'PyCollector'), - 'test.collect.Module' : ('./test/collect.py', 'Module'), - 'test.collect.Class' : ('./test/collect.py', 'Class'), - 'test.collect.Error' : ('./test/collect.py', 'Error'), - 'test.collect.Collector' : ('./test/collect.py', 'Collector'), - 'test.TextReporter' : ('./test/report/text/reporter.py', - 'TextReporter'), 'test.Option' : ('./test/tool/optparse.py', 'Option'), - 'test.MemoReporter' : ('./test/report/memo.py', 'MemoReporter'), - 'test.Item' : ('./test/item.py', 'Item'), - 'test.GenItem' : ('./test/item.py', 'GenItem'), 'test.Driver' : ('./test/drive.py', 'Driver'), + 'test.TerminalDriver' : ('./test/terminal.py', 'TerminalDriver'), - 'test2.skip' : ('./test2/item.py', 'skip'), - 'test2.skip_on_error' : ('./test2/item.py', 'skip_on_error'), - 'test2.raises' : ('./test2/raises.py', 'raises'), - 'test2.fail' : ('./test2/item.py', 'fail'), - 'test2.exit' : ('./test2/drive.py', 'exit'), - 'test2.config' : ('./test2/config.py', 'config'), - 'test2.Option' : ('./test2/tool/optparse.py', 'Option'), - 'test2.Driver' : ('./test2/drive.py', 'Driver'), - 'test2.TerminalDriver' : ('./test2/terminal.py', 'TerminalDriver'), - #'test2.TextReporter' : ('./test2/report/text/reporter.py', - # 'TextReporter'), - - 'test2.Collector' : ('./test2/collect.py', 'Collector'), - 'test2.Directory' : ('./test2/collect.py', 'Directory'), - 'test2.Module' : ('./test2/collect.py', 'Module'), - 'test2.Class' : ('./test2/collect.py', 'Class'), - 'test2.Instance' : ('./test2/collect.py', 'Instance'), - 'test2.Generator' : ('./test2/collect.py', 'Generator'), - 'test2.Item' : ('./test2/item.py', 'Item'), - 'test2.Function' : ('./test2/item.py', 'Function'), + 'test.Collector' : ('./test/collect.py', 'Collector'), + 'test.Directory' : ('./test/collect.py', 'Directory'), + 'test.Module' : ('./test/collect.py', 'Module'), + 'test.Class' : ('./test/collect.py', 'Class'), + 'test.Instance' : ('./test/collect.py', 'Instance'), + 'test.Generator' : ('./test/collect.py', 'Generator'), + 'test.Item' : ('./test/item.py', 'Item'), + 'test.Function' : ('./test/item.py', 'Function'), 'std' : ('./misc/std.py', 'std'), Modified: py/branch/py-collect/path/local/testing/test_local.py ============================================================================== --- py/branch/py-collect/path/local/testing/test_local.py (original) +++ py/branch/py-collect/path/local/testing/test_local.py Fri Mar 4 20:13:30 2005 @@ -108,7 +108,7 @@ def test_ensure_filepath_withdir(self): tmpdir = self.tmpdir - newfile = tmpdir.join('test1','test2') + newfile = tmpdir.join('test1','test') newfile.ensure() assert newfile.check(file=1) newfile.write("42") @@ -124,7 +124,7 @@ def test_ensure_dirpath(self): tmpdir = self.tmpdir - newfile = tmpdir.join('test1','test2file') + newfile = tmpdir.join('test1','testfile') t = newfile.ensure(dir=1) assert t == newfile assert newfile.check(dir=1) Modified: py/branch/py-collect/path/testing/fscommon.py ============================================================================== --- py/branch/py-collect/path/testing/fscommon.py (original) +++ py/branch/py-collect/path/testing/fscommon.py Fri Mar 4 20:13:30 2005 @@ -191,10 +191,10 @@ assert new.check(dir=1) new.remove() - new = tmpdir.mkdir('mktest2') + new = tmpdir.mkdir('mktest') assert new.check(dir=1) new.remove() - assert tmpdir.join('mktest2') == new + assert tmpdir.join('mktest') == new def test_move_file(self): p = self.root.join('samplefile') Modified: py/branch/py-collect/test2/cmdline.py ============================================================================== --- py/branch/py-collect/test2/cmdline.py (original) +++ py/branch/py-collect/test2/cmdline.py Fri Mar 4 20:13:30 2005 @@ -1,7 +1,7 @@ from __future__ import generators import py import sys -from py.__impl__.test2 import run +from py.__impl__.test import run # # main entry point @@ -9,11 +9,11 @@ def main(): args = py.std.sys.argv[1:] - py.test2.config.readconfiguration(*run.getanchors(args)) - filenames = py.test2.config.parseargs(args) + py.test.config.readconfiguration(*run.getanchors(args)) + filenames = py.test.config.parseargs(args) if not filenames: filenames.append(str(py.path.local())) - option = py.test2.config.option + option = py.test.config.option try: if option.session or option.executable: run.session(args, filenames) Modified: py/branch/py-collect/test2/collect.py ============================================================================== --- py/branch/py-collect/test2/collect.py (original) +++ py/branch/py-collect/test2/collect.py Fri Mar 4 20:13:30 2005 @@ -35,7 +35,7 @@ def configproperty(name): def fget(self): #print "retrieving %r property from %s" %(name, self.fspath) - return py.test2.config.getconfigvalue(self.fspath, name) + return py.test.config.getconfigvalue(self.fspath, name) return property(fget) def getfscollector(fspath): @@ -143,7 +143,7 @@ def iteritems(self): """ yield all Items from flattended collector instance. """ - if isinstance(self, py.test2.Item): + if isinstance(self, py.test.Item): yield self else: for x in self.run(): Modified: py/branch/py-collect/test2/config.py ============================================================================== --- py/branch/py-collect/test2/config.py (original) +++ py/branch/py-collect/test2/config.py Fri Mar 4 20:13:30 2005 @@ -1,7 +1,7 @@ from __future__ import generators import py -from py.__impl__.test2.tool import optparse +from py.__impl__.test.tool import optparse defaultconfig = py.magic.autopath().dirpath('defaultconfig.py') defaultconfig = py.path.extpy(defaultconfig) Modified: py/branch/py-collect/test2/defaultconfig.py ============================================================================== --- py/branch/py-collect/test2/defaultconfig.py (original) +++ py/branch/py-collect/test2/defaultconfig.py Fri Mar 4 20:13:30 2005 @@ -1,15 +1,15 @@ import py -Option = py.test2.Option +Option = py.test.Option -Module = py.test2.Module -Directory = py.test2.Directory -Class = py.test2.Class -Generator = py.test2.Generator -Function = py.test2.Function -Instance = py.test2.Instance +Module = py.test.Module +Directory = py.test.Directory +Class = py.test.Class +Generator = py.test.Generator +Function = py.test.Function +Instance = py.test.Instance def getreporter(): - return py.test2.TextReporter() + return py.test.TextReporter() additionalinfo = None Modified: py/branch/py-collect/test2/drive.py ============================================================================== --- py/branch/py-collect/test2/drive.py (original) +++ py/branch/py-collect/test2/drive.py Fri Mar 4 20:13:30 2005 @@ -1,5 +1,5 @@ import py -from py.__impl__.test2.tool.outerrcapture import SimpleOutErrCapture +from py.__impl__.test.tool.outerrcapture import SimpleOutErrCapture class ShadowOptions(object): def __init__(self, obj): @@ -14,7 +14,7 @@ """ def __init__(self): self._memo = [] - self.option = ShadowOptions(py.test2.config.option) + self.option = ShadowOptions(py.test.config.option) def shouldclose(self): return False @@ -26,12 +26,12 @@ def footer(self): """ teardown any resources we know about. """ - py.test2.Item.state.teardown_all() + py.test.Item.state.teardown_all() if not self.option.nomagic: py.magic.revoke(assertion=1) def start(self, colitem): - if not self.option.nocapture and isinstance(colitem, py.test2.Item): + if not self.option.nocapture and isinstance(colitem, py.test.Item): assert not hasattr(colitem, 'iocapture') colitem.iocapture = SimpleOutErrCapture() @@ -49,7 +49,7 @@ raise Warning(msg) def runpath(self, path): - from py.__impl__.test2.collect import getfscollector + from py.__impl__.test.collect import getfscollector col = getfscollector(path) return self.run(col) @@ -88,7 +88,7 @@ self.finish(colitem, res) def runinner(self, colitem): - if self.option.collectonly and isinstance(colitem, py.test2.Item): + if self.option.collectonly and isinstance(colitem, py.test.Item): return res = colitem.run() try: Modified: py/branch/py-collect/test2/item.py ============================================================================== --- py/branch/py-collect/test2/item.py (original) +++ py/branch/py-collect/test2/item.py Fri Mar 4 20:13:30 2005 @@ -27,7 +27,7 @@ col.setup() self.stack.append(col) -class Item(py.test2.Collector): +class Item(py.test.Collector): state = SetupState() class Function(Item): @@ -92,7 +92,7 @@ # def skip(msg="unknown reason", tbindex=-2): """ skip with the given Message. """ - raise py.test2.Item.Skipped(msg=msg, tbindex=tbindex) + raise py.test.Item.Skipped(msg=msg, tbindex=tbindex) def skip_on_error(func, *args, **kwargs): """ skip test if the given call fails. """ @@ -101,9 +101,9 @@ except Exception, e: s = py.code.ExceptionInfo().exconly() name = getattr(func, '__name__', func) - py.test2.skip("%s(...) -> %s" %(name, s.rstrip(), ), tbindex=-3) + py.test.skip("%s(...) -> %s" %(name, s.rstrip(), ), tbindex=-3) def fail(msg="unknown failure"): """ fail with the given Message. """ - raise py.test2.Item.Failed(msg=msg, tbindex=-2) + raise py.test.Item.Failed(msg=msg, tbindex=-2) Modified: py/branch/py-collect/test2/raises.py ============================================================================== --- py/branch/py-collect/test2/raises.py (original) +++ py/branch/py-collect/test2/raises.py Fri Mar 4 20:13:30 2005 @@ -1,6 +1,6 @@ import sys import py -ExceptionFailure = py.test2.Item.ExceptionFailure +ExceptionFailure = py.test.Item.ExceptionFailure def raises(ExpectedException, *args, **kwargs): """ raise AssertionError, if target code does not raise the expected Modified: py/branch/py-collect/test2/report/testing/test_memo.py ============================================================================== --- py/branch/py-collect/test2/report/testing/test_memo.py (original) +++ py/branch/py-collect/test2/report/testing/test_memo.py Fri Mar 4 20:13:30 2005 @@ -14,10 +14,10 @@ # try: # def XXtest_memoreporter(): - reporter = py.test2.MemoReporter() + reporter = py.test.MemoReporter() p = tmpdir.join('memoimport.py') p.write('raise IOError') - collector = py.test2.collect.Module(p) + collector = py.test.collect.Module(p) #main(collector=collector, reporter=reporter) #collect_errors = reporter.getlist(collect.Error) #assert len(collect_errors) == 1 Modified: py/branch/py-collect/test2/report/text/reporter.py ============================================================================== --- py/branch/py-collect/test2/report/text/reporter.py (original) +++ py/branch/py-collect/test2/report/text/reporter.py Fri Mar 4 20:13:30 2005 @@ -1,7 +1,7 @@ from __future__ import generators import py -Item = py.test2.Item -Collector = py.test2.collect.Collector +Item = py.test.Item +Collector = py.test.collect.Collector from time import time as now # lazy relative Implementation imports @@ -29,11 +29,11 @@ self.out = getout(f) self._started = {} self.summary = self.Summary(self.out) - self.summary.option = self.option = py.test2.config.option + self.summary.option = self.option = py.test.config.option def start(self): self.out.sep("=", "test process starts") - option = py.test2.config.option + option = py.test.config.option if option.session: mode = 'session/child process' elif option.executable: @@ -48,9 +48,9 @@ self.out.line("using py lib: %s " % ( py.path.local(py.__file__).dirpath(), rev)) - for i, x in py.builtin.enumerate(py.test2.config.configpaths): + for i, x in py.builtin.enumerate(py.test.config.configpaths): self.out.line("initial testconfig %d: %s" %(i, x)) - additional = py.test2.config.getfirst('additionalinfo') + additional = py.test.config.getfirst('additionalinfo') if additional: for key, descr in additional(): self.out.line("%s: %s" %(key, descr)) @@ -114,7 +114,7 @@ print "Item", item.extpy.modpath return if not self.option.nocapture: - from py.__impl__.test2.tool.outerrcapture import SimpleOutErrCapture + from py.__impl__.test.tool.outerrcapture import SimpleOutErrCapture item.iocapture = SimpleOutErrCapture() if self.out.tty: realpath, lineno = item.extpy.getfilelineno() @@ -138,9 +138,9 @@ restype, c = self.processresult(result) writeinfo = None if self.out.tty: - if not isinstance(result, py.test2.Item.Passed) or self.option.verbose >=1: + if not isinstance(result, py.test.Item.Passed) or self.option.verbose >=1: writeinfo = '\n' - elif isinstance(result, py.test2.Item.Passed): + elif isinstance(result, py.test.Item.Passed): writeinfo = '' elif self.option.verbose >= 1: writeinfo = '\n' Modified: py/branch/py-collect/test2/report/text/summary.py ============================================================================== --- py/branch/py-collect/test2/report/text/summary.py (original) +++ py/branch/py-collect/test2/report/text/summary.py Fri Mar 4 20:13:30 2005 @@ -1,6 +1,6 @@ from __future__ import generators import py -Item = py.test2.Item +Item = py.test.Item from py.__impl__.magic import exprinfo, assertion class Summary(object): @@ -31,7 +31,7 @@ self.out.line("[%s:%d]" % (err.filename, err.lineno)) def summary_collect_errors(self): - for error in self.getlist(py.test2.collect.Error): + for error in self.getlist(py.test.collect.Error): self.repr_collect_error(error) def render(self): Modified: py/branch/py-collect/test2/run.py ============================================================================== --- py/branch/py-collect/test2/run.py (original) +++ py/branch/py-collect/test2/run.py Fri Mar 4 20:13:30 2005 @@ -1,8 +1,8 @@ from __future__ import generators import py from py.__impl__.execnet.channel import ChannelFile, receive2file -from py.__impl__.test2.config import configbasename -from py.__impl__.test2.collect import getfscollector +from py.__impl__.test.config import configbasename +from py.__impl__.test.collect import getfscollector import sys def checkpyfilechange(rootdir, statcache): @@ -28,7 +28,7 @@ changed = True return changed -class FailingCollector(py.test2.Collector): +class FailingCollector(py.test.Collector): def __init__(self, faileditems): self._faileditems = faileditems @@ -76,13 +76,13 @@ channel.gateway.exit() def failure_master(args, filenames, failures): - exe = py.test2.config.option.executable + exe = py.test.config.option.executable gw = py.execnet.PopenGateway(python=exe or sys.executable) outproxy = StdouterrProxy(gw) outproxy.setup() try: channel = gw.remote_exec(""" - from py.__impl__.test2.run import failure_slave + from py.__impl__.test.run import failure_slave failure_slave(channel) """) channel.send((args, filenames, failures)) @@ -94,18 +94,18 @@ """ we run this on the other side. """ args, filenames, failures = channel.receive() filenames = map(py.path.local, filenames) - py.test2.config.readconfiguration(*filenames) - py.test2.config.parseargs(args) + py.test.config.readconfiguration(*filenames) + py.test.config.parseargs(args) if failures: col = FailureCollector(failures) else: col = list(getcollectors(filenames)) - driver = py.test2.Driver(channel) + driver = py.test.Driver(channel) failures = driver.run(col) channel.send(failures) -class FailureCollector(py.test2.Collector): +class FailureCollector(py.test.Collector): def __init__(self, failures): self.failures = failures def __iter__(self): @@ -138,22 +138,22 @@ """ we run this on the other side. """ print "inprocess" fncollectors = list(getcollectors(filenames)) - driver = py.test2.TerminalDriver() + driver = py.test.TerminalDriver() driver.run(*fncollectors) def session(args, filenames): statcache = {} # XXX find out rootdir automatically with # something like py.magic.autopath() ? - rootdir = py.path.local(py.test2.config.getfirst('rootdir', py.path.local())) + rootdir = py.path.local(py.test.config.getfirst('rootdir', py.path.local())) l = len(str(rootdir)) failures = [] while 1: - if py.test2.config.option.session: + if py.test.config.option.session: while not checkpyfilechange(rootdir, statcache): py.std.time.sleep(0.4) failures = failure_master(args, filenames, failures) - if not py.test2.config.option.session: + if not py.test.config.option.session: break print "#" * 60 print "# session mode: %d failures remaining" % len(failures) Modified: py/branch/py-collect/test2/terminal.py ============================================================================== --- py/branch/py-collect/test2/terminal.py (original) +++ py/branch/py-collect/test2/terminal.py Fri Mar 4 20:13:30 2005 @@ -1,10 +1,10 @@ import py -from py.__impl__.test2.report.text.out import getout +from py.__impl__.test.report.text.out import getout from time import time as now -Item = py.test2.Item +Item = py.test.Item -class TerminalDriver(py.test2.Driver): +class TerminalDriver(py.test.Driver): def __init__(self, file=None): super(TerminalDriver, self).__init__() if file is None: @@ -57,7 +57,7 @@ def start_Item(self, colitem): if self.option.verbose >= 1: - if isinstance(colitem, py.test2.Item): + if isinstance(colitem, py.test.Item): realpath, lineno = colitem.getpathlineno() location = "%s:%d" % (realpath.basename, lineno+1) self.out.rewrite("%-20s %s " % ( @@ -84,9 +84,9 @@ pdb.post_mortem(result.excinfo._excinfo[2]) if isinstance(result, (colitem.Failed,)): if self.option.exitfirstproblem: - py.test2.exit("exit on first problem configured.", item=colitem) - if result is None or not isinstance(colitem, py.test2.Item): - if isinstance(colitem, py.test2.Module) and self.option.verbose == 0: + py.test.exit("exit on first problem configured.", item=colitem) + if result is None or not isinstance(colitem, py.test.Item): + if isinstance(colitem, py.test.Module) and self.option.verbose == 0: self.out.line() return else: @@ -119,9 +119,9 @@ self.out.line("using py lib: %s " % ( py.path.local(py.__file__).dirpath(), rev)) - for i, x in py.builtin.enumerate(py.test2.config.configpaths): + for i, x in py.builtin.enumerate(py.test.config.configpaths): self.out.line("initial testconfig %d: %s" %(i, x)) - additional = py.test2.config.getfirst('additionalinfo') + additional = py.test.config.getfirst('additionalinfo') if additional: for key, descr in additional(): self.out.line("%s: %s" %(key, descr)) Modified: py/branch/py-collect/test2/testing/test_api.py ============================================================================== --- py/branch/py-collect/test2/testing/test_api.py (original) +++ py/branch/py-collect/test2/testing/test_api.py Fri Mar 4 20:13:30 2005 @@ -4,13 +4,13 @@ def test_skipfailure(): def f(): raise ValueError() - excinfo = py.test2.raises( - py.test2.Item.Skipped, - "py.test2.skip_on_error(f)") + excinfo = py.test.raises( + py.test.Item.Skipped, + "py.test.skip_on_error(f)") print excinfo assert str(excinfo).find("ValueError") != -1 def test_skip_on_error_with_no_failure(): def f(): return 42 - assert py.test2.skip_on_error(f) == 42 + assert py.test.skip_on_error(f) == 42 Modified: py/branch/py-collect/test2/testing/test_collect.py ============================================================================== --- py/branch/py-collect/test2/testing/test_collect.py (original) +++ py/branch/py-collect/test2/testing/test_collect.py Fri Mar 4 20:13:30 2005 @@ -4,17 +4,17 @@ def test_failing_import_execfile(): fn = datadir / 'failingimport.py' - col = py.test2.Module(fn) + col = py.test.Module(fn) def _import(): - py.test2.raises(ImportError, col.run) + py.test.raises(ImportError, col.run) _import() _import() def XXXtest_finds_root(): fn = datadir / 'filetest.py' - col = py.test2.Module(fn) + col = py.test.Module(fn) root, namelist = col.fromroot() - assert isinstance(root, py.test2.Directory) + assert isinstance(root, py.test.Directory) cur = root for x in namelist: cur = cur.join(x) @@ -24,7 +24,7 @@ def test_finds_tests(): fn = datadir / 'filetest.py' - col = py.test2.Module(fn) + col = py.test.Module(fn) l = col.run() assert len(l) == 2 items = list(col.iteritems()) @@ -35,28 +35,28 @@ assert l[1].fspath == fn def test_failing_import_directory(): - class MyDirectory(py.test2.Directory): + class MyDirectory(py.test.Directory): filefilter = py.path.checker(fnmatch='testspecial*.py') l = MyDirectory(datadir).run() assert len(l) == 1 - assert isinstance(l[0], py.test2.Module) - py.test2.raises(ImportError, l[0].run) + assert isinstance(l[0], py.test.Module) + py.test.raises(ImportError, l[0].run) def test_module_file_not_found(): fn = datadir.join('nada','no') - col = py.test2.Module(fn) - py.test2.raises(py.error.ENOENT, col.run) + col = py.test.Module(fn) + py.test.raises(py.error.ENOENT, col.run) def test_syntax_error_in_module(): modpath = py.path.extpy(datadir.join('syntax_error.py')) - col = py.test2.Module(modpath) - py.test2.raises(SyntaxError, col.run) + col = py.test.Module(modpath) + py.test.raises(SyntaxError, col.run) def test_disabled_class(): - col = py.test2.Module(datadir.join('disabled.py')) + col = py.test.Module(datadir.join('disabled.py')) l = col.run() assert len(l) == 1 - assert isinstance(l[0], py.test2.Class) + assert isinstance(l[0], py.test.Class) assert not l[0].run() class Testsomeclass: @@ -66,7 +66,7 @@ #class TestWithCustomItem: -# class Item(py.test2.Item): +# class Item(py.test.Item): # flag = [] # def execute(self, target, *args): # self.flag.append(42) @@ -77,7 +77,7 @@ # def test_generative_simple(): - o = py.test2.config.tmpdir.ensure('generativetest', dir=1) + o = py.test.config.tmpdir.ensure('generativetest', dir=1) tfile = o.join('test_generative.py') tfile.write(py.code.Source(""" def func1(arg, arg2): @@ -92,38 +92,38 @@ yield func1, 17, 3*5 yield func1, 42, 6*7 """)) - col = py.test2.Module(tfile) + col = py.test.Module(tfile) l = col.run() assert len(l) == 2 generator = l[0] print l - assert isinstance(generator, py.test2.Generator) + assert isinstance(generator, py.test.Generator) l2 = generator.run() assert len(l2) == 2 - assert isinstance(l2[0], py.test2.Function) - assert isinstance(l2[1], py.test2.Function) + assert isinstance(l2[0], py.test.Function) + assert isinstance(l2[1], py.test.Function) assert l2[0].name == '[0]' assert l2[1].name == '[1]' classlist = l[1].run() assert len(classlist) == 1 generator = classlist[0].run()[0] - assert isinstance(generator, py.test2.Generator) + assert isinstance(generator, py.test.Generator) l2 = generator.run() assert len(l2) == 2 - assert isinstance(l2[0], py.test2.Function) - assert isinstance(l2[1], py.test2.Function) + assert isinstance(l2[0], py.test.Function) + assert isinstance(l2[1], py.test.Function) assert l2[0].name == '[0]' assert l2[1].name == '[1]' def test_custom_collection_from_conftest(): - o = py.test2.config.tmpdir.ensure('customconfigtest', dir=1) + o = py.test.config.tmpdir.ensure('customconfigtest', dir=1) o.ensure('conftest.py').write("""if 1: import py - class MyFunction(py.test2.Function): + class MyFunction(py.test.Function): pass - class Directory(py.test2.Directory): + class Directory(py.test.Directory): def filefilter(self, fspath): return fspath.check(basestarts='check_') class myfuncmixin: @@ -131,10 +131,10 @@ def funcnamefilter(self, name): return name.startswith('check_') - class Module(myfuncmixin, py.test2.Module): + class Module(myfuncmixin, py.test.Module): def classnamefilter(self, name): return name.startswith('CustomTestClass') - class Instance(myfuncmixin, py.test2.Instance): + class Instance(myfuncmixin, py.test.Instance): pass """) o.ensure('somedir', 'check_something').write("""if 1: @@ -144,7 +144,7 @@ def check_method(self): assert 23 == 23 """) - from py.__impl__.test2.collect import getfscollector + from py.__impl__.test.collect import getfscollector items = list(getfscollector(o).iteritems()) assert len(items) == 2 assert items[1].__class__.__name__ == 'MyFunction' Modified: py/branch/py-collect/test2/testing/test_config.py ============================================================================== --- py/branch/py-collect/test2/testing/test_config.py (original) +++ py/branch/py-collect/test2/testing/test_config.py Fri Mar 4 20:13:30 2005 @@ -1,6 +1,6 @@ from __future__ import generators import py -config = py.test2.config +config = py.test.config class MyClass: def getoptions(self): @@ -28,8 +28,8 @@ assert d1 == d2 def test_config_order(): - from py.__impl__.test2 import config - o = py.test2.config.tmpdir.ensure('configorder', dir=1) + from py.__impl__.test import config + o = py.test.config.tmpdir.ensure('configorder', dir=1) o.ensure('conftest.py').write('x=1 ; import py ; py._x = [x]') o.ensure('a/conftest.py').write('x=2 ; import py ; py._x.append(x)') o.ensure('a/b/c/conftest.py').write('x=3 ; import py ; py._x.append(x)') @@ -44,9 +44,9 @@ assert py._x == [1,2,3] def test_getconfigvalue(): - from py.__impl__.test2 import config + from py.__impl__.test import config cfg = config.Config() - o = py.test2.config.tmpdir.ensure('configtest', dir=1) + o = py.test.config.tmpdir.ensure('configtest', dir=1) o.ensure('conftest.py').write('x=1') assert cfg.getconfigvalue(o, 'x') == 1 - py.test2.raises(ValueError, "cfg.getconfigvalue(o, 'y')") + py.test.raises(ValueError, "cfg.getconfigvalue(o, 'y')") Modified: py/branch/py-collect/test2/testing/test_drive.py ============================================================================== --- py/branch/py-collect/test2/testing/test_drive.py (original) +++ py/branch/py-collect/test2/testing/test_drive.py Fri Mar 4 20:13:30 2005 @@ -4,48 +4,48 @@ class TestDefaultDriver: def test_simple(self): - drive = py.test2.Driver() + drive = py.test.Driver() drive.option.nocapture = True drive.runpath(datadir / 'filetest.py') - l = drive.getresults(py.test2.Item.Failed) + l = drive.getresults(py.test.Item.Failed) assert len(l) == 2 - l = drive.getresults(py.test2.Item.Passed) + l = drive.getresults(py.test.Item.Passed) assert not l class TestTerminalDriver: def test_terminal(self): c = StringIO() - drive = py.test2.TerminalDriver(file=c) + drive = py.test.TerminalDriver(file=c) drive.runpath(datadir / 'filetest.py') out = c.getvalue() print "memo" print drive._memo print "out" print out - l = drive.getresults(py.test2.Item.Failed) + l = drive.getresults(py.test.Item.Failed) assert len(l) == 2 assert out.find('2 failed') != -1 def test_exit_first_problem(self): - drive = py.test2.TerminalDriver() + drive = py.test.TerminalDriver() if drive.option.usepdb: - py.test2.skip("options of sub-runs are not isolated") + py.test.skip("options of sub-runs are not isolated") drive.option.exitfirstproblem = True drive.runpath(str(datadir / 'filetest.py')) - l = drive.getresults(py.test2.Item.Failed) + l = drive.getresults(py.test.Item.Failed) assert len(l) == 1 - l = drive.getresults(py.test2.Item.Passed) + l = drive.getresults(py.test.Item.Passed) assert not l def test_collectonly(self): c = StringIO() - drive = py.test2.TerminalDriver(file=c) + drive = py.test.TerminalDriver(file=c) drive.option.collectonly = True drive.runpath(str(datadir / 'filetest.py')) out = c.getvalue() print out - l = drive.getresults(py.test2.Item.Failed) + l = drive.getresults(py.test.Item.Failed) #if l: # x = l[0][1].excinfo # print x.exconly() @@ -56,7 +56,7 @@ assert out.find(line) def test_order_of_execution(): - o = py.test2.config.tmpdir.ensure('ordertest', dir=1) + o = py.test.config.tmpdir.ensure('ordertest', dir=1) tfile = o.join('test_orderofexecution.py') tfile.write(py.code.Source(""" l = [] @@ -78,11 +78,11 @@ assert self.reslist == [1,2,1,2,3] """)) - drive = py.test2.Driver() + drive = py.test.Driver() drive.runpath(o) - l = drive.getresults(py.test2.Item.Failed) + l = drive.getresults(py.test.Item.Failed) assert len(l) == 0 - l = drive.getresults(py.test2.Item.Passed) + l = drive.getresults(py.test.Item.Passed) assert len(l) == 7 # also test listnames() here ... item, result = l[-1] Modified: py/branch/py-collect/test2/tool/optparse.py ============================================================================== --- py/branch/py-collect/test2/tool/optparse.py (original) +++ py/branch/py-collect/test2/tool/optparse.py Fri Mar 4 20:13:30 2005 @@ -69,7 +69,7 @@ import sys, os import types -from py.__impl__.test2.tool import textwrap +from py.__impl__.test.tool import textwrap class OptParseError (Exception): def __init__ (self, msg): Modified: py/branch/py-collect/test2/tool/testing/test_outerrcapture.py ============================================================================== --- py/branch/py-collect/test2/tool/testing/test_outerrcapture.py (original) +++ py/branch/py-collect/test2/tool/testing/test_outerrcapture.py Fri Mar 4 20:13:30 2005 @@ -1,6 +1,6 @@ import sys import py -from py.__impl__.test2.tool.outerrcapture import SimpleOutErrCapture +from py.__impl__.test.tool.outerrcapture import SimpleOutErrCapture def test_capturing_simple(): cap = SimpleOutErrCapture() @@ -14,7 +14,7 @@ cap = SimpleOutErrCapture() print "hello" cap.reset() - py.test2.raises(AttributeError, "cap.reset()") + py.test.raises(AttributeError, "cap.reset()") def test_capturing_modify_sysouterr_in_between(): oldout = sys.stdout @@ -37,4 +37,4 @@ cap2 = SimpleOutErrCapture() print "hello" cap2.reset() - py.test2.raises(AttributeError, "cap2.reset()") + py.test.raises(AttributeError, "cap2.reset()") From hpk at codespeak.net Fri Mar 4 20:28:06 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 20:28:06 +0100 (MET) Subject: [py-svn] r9649 - in py/branch/py-collect: c-extension misc/testing test test/report test/report/text test/testing test/tool test2 Message-ID: <20050304192806.5462027B4C@code1.codespeak.net> Author: hpk Date: Fri Mar 4 20:28:06 2005 New Revision: 9649 Added: py/branch/py-collect/test/ - copied from r9616, py/branch/py-collect/test2/ py/branch/py-collect/test/__init__.py - copied unchanged from r9648, py/branch/py-collect/test2/__init__.py py/branch/py-collect/test/cmdline.py - copied unchanged from r9648, py/branch/py-collect/test2/cmdline.py py/branch/py-collect/test/collect.py - copied unchanged from r9648, py/branch/py-collect/test2/collect.py py/branch/py-collect/test/config.py - copied unchanged from r9648, py/branch/py-collect/test2/config.py py/branch/py-collect/test/defaultconfig.py - copied, changed from r9648, py/branch/py-collect/test2/defaultconfig.py py/branch/py-collect/test/drive.py - copied unchanged from r9648, py/branch/py-collect/test2/drive.py py/branch/py-collect/test/item.py - copied unchanged from r9648, py/branch/py-collect/test2/item.py py/branch/py-collect/test/raises.py - copied unchanged from r9648, py/branch/py-collect/test2/raises.py py/branch/py-collect/test/report/ - copied from r9648, py/branch/py-collect/test2/report/ py/branch/py-collect/test/run.py - copied unchanged from r9648, py/branch/py-collect/test2/run.py py/branch/py-collect/test/terminal.py - copied, changed from r9648, py/branch/py-collect/test2/terminal.py py/branch/py-collect/test/testing/ - copied from r9648, py/branch/py-collect/test2/testing/ py/branch/py-collect/test/tool/ - copied from r9648, py/branch/py-collect/test2/tool/ Removed: py/branch/py-collect/test/report/text/reporter.py py/branch/py-collect/test/report/text/summary.py py/branch/py-collect/test2/ Modified: py/branch/py-collect/c-extension/conftest.py py/branch/py-collect/misc/testing/test_initpkg.py Log: move new stuff to py.test Modified: py/branch/py-collect/c-extension/conftest.py ============================================================================== --- py/branch/py-collect/c-extension/conftest.py (original) +++ py/branch/py-collect/c-extension/conftest.py Fri Mar 4 20:28:06 2005 @@ -1,8 +1,8 @@ import py -class Directory(py.test.collect.Directory): - def rec(self, path): +class Directory(py.test.Directory): + def recfilter(self, path): if py.std.sys.platform == 'linux2': if path.basename == 'greenlet': return False - return super(Directory, self).rec(path) + return super(Directory, self).recfilter(path) Modified: py/branch/py-collect/misc/testing/test_initpkg.py ============================================================================== --- py/branch/py-collect/misc/testing/test_initpkg.py (original) +++ py/branch/py-collect/misc/testing/test_initpkg.py Fri Mar 4 20:28:06 2005 @@ -29,7 +29,7 @@ def test_importall(): base = py.path.local(py.__file__).dirpath() nodirs = ( - base.join('test', 'testing', 'test'), + base.join('test', 'testing', 'data'), base.join('path', 'extpy', 'testing', 'test_data'), base.join('path', 'gateway',), base.join('documentation',), Copied: py/branch/py-collect/test/defaultconfig.py (from r9648, py/branch/py-collect/test2/defaultconfig.py) ============================================================================== --- py/branch/py-collect/test2/defaultconfig.py (original) +++ py/branch/py-collect/test/defaultconfig.py Fri Mar 4 20:28:06 2005 @@ -8,9 +8,6 @@ Function = py.test.Function Instance = py.test.Instance -def getreporter(): - return py.test.TextReporter() - additionalinfo = None options = ('py.test standard options', [ Deleted: /py/branch/py-collect/test2/report/text/reporter.py ============================================================================== --- /py/branch/py-collect/test2/report/text/reporter.py Fri Mar 4 20:28:06 2005 +++ (empty file) @@ -1,202 +0,0 @@ -from __future__ import generators -import py -Item = py.test.Item -Collector = py.test.collect.Collector - -from time import time as now -# lazy relative Implementation imports -from summary import Summary -from out import getout - -class TextReporter(object): - Summary = Summary - typemap = { - Item.Passed: '.', - Item.Skipped: 's', - Item.Failed: 'F', - Collector.Error: 'C', - } - namemap = { - Item.Passed: 'ok', - Item.Skipped: 'SKIP', - Item.Failed: 'FAIL', - Collector.Error: 'COLLECT ERROR', - } - - def __init__(self, f=None): - if f is None: - f = py.std.sys.stdout - self.out = getout(f) - self._started = {} - self.summary = self.Summary(self.out) - self.summary.option = self.option = py.test.config.option - - def start(self): - self.out.sep("=", "test process starts") - option = py.test.config.option - if option.session: - mode = 'session/child process' - elif option.executable: - mode = 'child process' - else: - mode = 'inprocess' - self.out.line("testing-mode: %s" % mode) - self.out.line("executable : %s (%s)" % - (py.std.sys.executable, repr_pythonversion())) - - rev = py.__package__.getrev() - self.out.line("using py lib: %s " % ( - py.path.local(py.__file__).dirpath(), rev)) - - for i, x in py.builtin.enumerate(py.test.config.configpaths): - self.out.line("initial testconfig %d: %s" %(i, x)) - additional = py.test.config.getfirst('additionalinfo') - if additional: - for key, descr in additional(): - self.out.line("%s: %s" %(key, descr)) - self.out.sep("=") - if not self.option.nomagic: - py.magic.invoke(assertion=1) - self.summary.starttime = now() - - def end(self): - if not self.option.nomagic: - py.magic.revoke(assertion=1) - self.summary.endtime = now() - self.summary.render() - - def open(self, collector): - if self.option.collectonly: - cols = self.__dict__.setdefault('_opencollectors', []) - print ' ' * len(cols), repr(collector) - cols.append(collector) - return cols.pop - - cls = getattr(collector, '__class__', None) - if cls is None: - return - for typ in py.std.inspect.getmro(cls): - meth = getattr(self, 'open_%s' % typ.__name__, None) - if meth: - return meth(collector) - - def open_Module(self, collector): - verbose = self.option.verbose - numunits = len(list(collector.iterunits())) - if numunits > 0: - fspath = collector.extpy.root - if verbose == 0: - parts = fspath.parts() - basename = parts.pop().basename - while parts and parts[-1].basename in ('testing', 'test'): - parts.pop() - base = parts[-1].basename - if len(base) < 13: - base = base + "_" * (13-len(base)) - abbrev_fn = base + "_" + basename - self.out.write('%s[%d] ' % (abbrev_fn, numunits)) - return self.out.line - elif verbose > 0: - #curdir = py.path.local() - #if fspath.check(local=True, relto=curdir): - # fspath = fspath.relto(curdir) - self.out.line() - self.out.line("+ testmodule: %s" % fspath) - - def open_Directory(self, collector): - return - - def startitem(self, item): - if self.option.collectonly: - cols = self._opencollectors - if len(cols): - print ' ' * len(cols), - print "Item", item.extpy.modpath - return - if not self.option.nocapture: - from py.__impl__.test.tool.outerrcapture import SimpleOutErrCapture - item.iocapture = SimpleOutErrCapture() - if self.out.tty: - realpath, lineno = item.extpy.getfilelineno() - location = "running %s:%d %s" % (realpath.basename, lineno, str(item.extpy.modpath)) - self.out.rewrite(location) - self._started[item] = now() - - def enditem(self, result): - if self.option.collectonly: - return - endtime = now() - item = result.item - starttime = self._started[item] - del self._started[item] - elapsed = endtime - starttime - item.elapsed = elapsed - - if not self.option.nocapture: - result.out, result.err = item.iocapture.reset() - - restype, c = self.processresult(result) - writeinfo = None - if self.out.tty: - if not isinstance(result, py.test.Item.Passed) or self.option.verbose >=1: - writeinfo = '\n' - elif isinstance(result, py.test.Item.Passed): - writeinfo = '' - elif self.option.verbose >= 1: - writeinfo = '\n' - else: - self.out.write(c) - - if writeinfo is not None: - realpath, lineno = item.extpy.getfilelineno() - location = "%s:%d" % (realpath.basename, lineno+1) - resultstring = self.namemap.get(restype, result.__class__.__name__) - self.out.rewrite("%.3f %-2s %-20s %s%s" % ( - elapsed, resultstring, location, item.reprcall(), writeinfo - )) - if self.option.usepdb: - if (issubclass(restype, Collector.Error) or - issubclass(restype, Item.Failed)): - self.summary.repr_failure(result.excinfo) - import pdb - self.out.rewrite( - '\n%s: %s\n' - % (result.excinfo.type.__name__, - result.excinfo.value)) - pdb.post_mortem(result.excinfo._excinfo[2]) - - def report_collect_error(self, error): - restype, c = self.processresult(error) - writeinfo = None - if self.out.tty: - if not isinstance(result, Item.Passed) or self.option.verbose >=1: - writeinfo = '\n' - elif isinstance(result, Item.Passed): - writeinfo = '' - elif self.option.verbose >= 1: - writeinfo = '\n' - else: - self.out.write(c) - - if writeinfo is not None: - #exc, frame, filename,lineno = self.summary.getexinfo(error) - tbentries = error.excinfo.traceback - filename = tbentries[-1].frame.code.path - lineno = tbentries[-1].lineno - self.out.line('CollectError: %s:%d' % (filename, lineno) ) - - def processresult(self, testresult): - for restype, c in self.typemap.items(): - if isinstance(testresult, restype): - self.summary.append(restype, testresult) - return restype, c - else: - raise TypeError, "not a result instance: %r" % testresult - -def repr_pythonversion(): - v = py.std.sys.version_info - try: - return "%s.%s.%s-%s-%s" % v - except ValueError: - return str(v) - Deleted: /py/branch/py-collect/test2/report/text/summary.py ============================================================================== --- /py/branch/py-collect/test2/report/text/summary.py Fri Mar 4 20:28:06 2005 +++ (empty file) @@ -1,80 +0,0 @@ -from __future__ import generators -import py -Item = py.test.Item -from py.__impl__.magic import exprinfo, assertion - -class Summary(object): - def __init__(self, out): - self.out = out - - def append(self, restype, testresult): - self.getlist(restype).append(testresult) - - def getlist(self, restype): - name = restype.__name__.lower() - return self.__dict__.setdefault(name, []) - - def repr_collect_error(self, error): - self.out.line() - self.out.sep("_") - self.out.sep("_", "Collect Error") - self.out.line() - if isinstance(error.excinfo.value, SyntaxError): - self.repr_syntaxerror(error.excinfo) - else: - self.repr_failure(error.excinfo) - - def repr_syntaxerror(self, excinfo): - err = excinfo.value - self.out.line(err.text) - self.out.line("SyntaxError: %s" %(err.msg)) - self.out.line("[%s:%d]" % (err.filename, err.lineno)) - - def summary_collect_errors(self): - for error in self.getlist(py.test.collect.Error): - self.repr_collect_error(error) - - def render(self): - self.out.write('\n') - self.skippedreasons() - self.failures() - self.summary_collect_errors() - outlist = [] - sum = 0 - for typ in Item.Passed, Item.Failed, Item.Skipped: - l = self.getlist(typ) - if l: - outlist.append('%d %s' % (len(l), typ.__name__.lower())) - sum += len(l) - elapsed = self.endtime-self.starttime - status = "%s" % ", ".join(outlist) - self.out.sep('=', 'tests finished: %s in %4.2f seconds' % - (status, elapsed)) - - - def Xrepr_traceback_raw(self, traceback): - recursioncache = {} - for tb in tbentries: - if first: - first = False - else: - self.out.sep('-') - #self.out.line("%-10s = %r" %(name, value)) - key = (path, lineno) - if key not in recursioncache: - recursioncache.setdefault(key, []).append(tb.frame.f_locals) - else: - f = tb.frame - loc = f.f_locals - for x in recursioncache[key]: - if f.is_true(f.eval(co_equal, __recursioncache_locals_1=loc, - __recursioncache_locals_2=x)): - self.out.line("Recursion detected (same locals & position)") - break - else: - #self.out.sep('-') - continue - break - -co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2', - '?', 'eval') Copied: py/branch/py-collect/test/terminal.py (from r9648, py/branch/py-collect/test2/terminal.py) ============================================================================== --- py/branch/py-collect/test2/terminal.py (original) +++ py/branch/py-collect/test/terminal.py Fri Mar 4 20:28:06 2005 @@ -315,13 +315,42 @@ if self.option.showlocals: self.out.sep('- ', 'locals') for name, value in entry.frame.f_locals.items(): - if len(repr(value)) < 70 or not isinstance(value, + if name == '__builtins__': + self.out.line("__builtins__ = ") + elif len(repr(value)) < 70 or not isinstance(value, (list, tuple, dict)): self.out.line("%-10s = %r" %(name, value)) else: self.out.line("%-10s =\\" % (name,)) py.std.pprint.pprint(value, stream=self.out) + def Xrepr_traceback_raw(self, traceback): + recursioncache = {} + for tb in tbentries: + if first: + first = False + else: + self.out.sep('-') + #self.out.line("%-10s = %r" %(name, value)) + key = (path, lineno) + if key not in recursioncache: + recursioncache.setdefault(key, []).append(tb.frame.f_locals) + else: + f = tb.frame + loc = f.f_locals + for x in recursioncache[key]: + if f.is_true(f.eval(co_equal, __recursioncache_locals_1=loc, + __recursioncache_locals_2=x)): + self.out.line("Recursion detected (same locals & position)") + break + else: + #self.out.sep('-') + continue + break + +co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2', + '?', 'eval') + def repr_pythonversion(): v = py.std.sys.version_info try: From hpk at codespeak.net Fri Mar 4 20:49:06 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 20:49:06 +0100 (MET) Subject: [py-svn] r9650 - in py/branch/py-collect: . misc/testing test test/testing Message-ID: <20050304194906.7668F27B71@code1.codespeak.net> Author: hpk Date: Fri Mar 4 20:49:06 2005 New Revision: 9650 Added: py/branch/py-collect/test/compat.py - copied, changed from r9641, py/dist/py/test/compat.py py/branch/py-collect/test/testing/test_compat.py - copied, changed from r9641, py/dist/py/test/testing/test_compat.py Modified: py/branch/py-collect/__init__.py py/branch/py-collect/misc/testing/test_initpkg.py py/branch/py-collect/test/collect.py Log: reintroduced py.test.compat.TestCase Modified: py/branch/py-collect/__init__.py ============================================================================== --- py/branch/py-collect/__init__.py (original) +++ py/branch/py-collect/__init__.py Fri Mar 4 20:49:06 2005 @@ -10,6 +10,8 @@ 'test.Driver' : ('./test/drive.py', 'Driver'), 'test.TerminalDriver' : ('./test/terminal.py', 'TerminalDriver'), + 'test.compat.TestCase' : ('./test/compat.py', 'TestCase'), + 'test.Collector' : ('./test/collect.py', 'Collector'), 'test.Directory' : ('./test/collect.py', 'Directory'), 'test.Module' : ('./test/collect.py', 'Module'), Modified: py/branch/py-collect/misc/testing/test_initpkg.py ============================================================================== --- py/branch/py-collect/misc/testing/test_initpkg.py (original) +++ py/branch/py-collect/misc/testing/test_initpkg.py Fri Mar 4 20:49:06 2005 @@ -30,6 +30,7 @@ base = py.path.local(py.__file__).dirpath() nodirs = ( base.join('test', 'testing', 'data'), + base.join('test', 'testing', 'test'), base.join('path', 'extpy', 'testing', 'test_data'), base.join('path', 'gateway',), base.join('documentation',), Modified: py/branch/py-collect/test/collect.py ============================================================================== --- py/branch/py-collect/test/collect.py (original) +++ py/branch/py-collect/test/collect.py Fri Mar 4 20:49:06 2005 @@ -102,7 +102,6 @@ return x.sortvalue() def getpathlineno(self): - print "getpathlineno", self return self.fspath, py.std.sys.maxint def setup(self): Copied: py/branch/py-collect/test/compat.py (from r9641, py/dist/py/test/compat.py) ============================================================================== --- py/dist/py/test/compat.py (original) +++ py/branch/py-collect/test/compat.py Fri Mar 4 20:49:06 2005 @@ -1,24 +1,23 @@ from __future__ import generators import py -class TestCaseUnit(py.test.Item): +class TestCaseUnit(py.test.Function): """ compatibility Unit executor for TestCase methods honouring setUp and tearDown semantics. """ def execute(self, driver): - unboundmethod = self.extpy.resolve() - cls = unboundmethod.im_class - instance = cls() + boundmethod = self.obj + instance = boundmethod.im_self instance.setUp() try: - unboundmethod(instance) + boundmethod() finally: instance.tearDown() return py.test.Item.Passed() class TestCase: """compatibility class of unittest's TestCase. """ - Item = TestCaseUnit + Function = TestCaseUnit def setUp(self): pass Copied: py/branch/py-collect/test/testing/test_compat.py (from r9641, py/dist/py/test/testing/test_compat.py) ============================================================================== --- py/dist/py/test/testing/test_compat.py (original) +++ py/branch/py-collect/test/testing/test_compat.py Fri Mar 4 20:49:06 2005 @@ -15,17 +15,17 @@ l = self.l assert len(l) == 1 assert l[-1] == 42 - self.checkmultipleinstances() + #self.checkmultipleinstances() def test_issetup2(self): l = self.l assert len(l) == 1 assert l[-1] == 42 - self.checkmultipleinstances() + #self.checkmultipleinstances() - def checkmultipleinstances(self): - for x,y in zip(self.globlist, self.globlist[1:]): - assert x is not y + #def checkmultipleinstances(self): + # for x,y in zip(self.globlist, self.globlist[1:]): + # assert x is not y class TestCompatAssertions(py.test.compat.TestCase): nameparamdef = { From hpk at codespeak.net Fri Mar 4 20:59:25 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 20:59:25 +0100 (MET) Subject: [py-svn] r9651 - py/branch/py-collect/misc/testing Message-ID: <20050304195925.755D727B71@code1.codespeak.net> Author: hpk Date: Fri Mar 4 20:59:25 2005 New Revision: 9651 Modified: py/branch/py-collect/misc/testing/test_initpkg.py Log: mask out greenlets from autoimport-tests Modified: py/branch/py-collect/misc/testing/test_initpkg.py ============================================================================== --- py/branch/py-collect/misc/testing/test_initpkg.py (original) +++ py/branch/py-collect/misc/testing/test_initpkg.py Fri Mar 4 20:59:25 2005 @@ -31,6 +31,7 @@ nodirs = ( base.join('test', 'testing', 'data'), base.join('test', 'testing', 'test'), + base.join('magic', 'greenlet.py'), base.join('path', 'extpy', 'testing', 'test_data'), base.join('path', 'gateway',), base.join('documentation',), @@ -41,9 +42,9 @@ ) for p in base.visit('*.py', py.path.checker(dotfile=0)): relpath = p.new(ext='').relto(base) - if base.sep in relpath: # not std/*.py itself + if base.sep in relpath: # not py/*.py itself for x in nodirs: - if p.relto(x): + if p == x or p.relto(x): break else: relpath = relpath.replace(base.sep, '.') From hpk at codespeak.net Fri Mar 4 21:12:16 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Mar 2005 21:12:16 +0100 (MET) Subject: [py-svn] r9652 - py/branch/py-collect/code Message-ID: <20050304201216.5639127B4C@code1.codespeak.net> Author: hpk Date: Fri Mar 4 21:12:16 2005 New Revision: 9652 Added: py/branch/py-collect/code/code.py (contents, props changed) - copied, changed from r9651, py/dist/py/code/code.py Log: allow functions to be passed to py.code.Code Copied: py/branch/py-collect/code/code.py (from r9651, py/dist/py/code/code.py) ============================================================================== --- py/dist/py/code/code.py (original) +++ py/branch/py-collect/code/code.py Fri Mar 4 21:12:16 2005 @@ -2,6 +2,8 @@ class Code(object): def __init__(self, rawcode): + rawcode = getattr(rawcode, 'im_func', rawcode) + rawcode = getattr(rawcode, 'func_code', rawcode) self.raw = rawcode self.firstlineno = rawcode.co_firstlineno - 1 self.name = rawcode.co_name From hpk at codespeak.net Sat Mar 5 12:16:29 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Mar 2005 12:16:29 +0100 (MET) Subject: [py-svn] r9654 - py/branch/py-collect/test Message-ID: <20050305111629.8FFEF27B4C@code1.codespeak.net> Author: hpk Date: Sat Mar 5 12:16:29 2005 New Revision: 9654 Modified: py/branch/py-collect/test/terminal.py Log: small refactoring Modified: py/branch/py-collect/test/terminal.py ============================================================================== --- py/branch/py-collect/test/terminal.py (original) +++ py/branch/py-collect/test/terminal.py Sat Mar 5 12:16:29 2005 @@ -221,21 +221,23 @@ self.repr_locals(entry) if entry == last: if item: - root = item.fspath - modpath = item.getmodpath() - fn, lineno = item.getpathlineno() - if fn != entry.frame.code.path or \ - entry.frame.code.firstlineno != lineno: - self.out.line("[testcode : %s:%d]" % (fn, lineno+1)) - if root == fn: - self.out.line("[modulepath: %s]" %(modpath)) - else: - self.out.line("[modulepath: %s %s]" %(root.basename, modpath)) + self.repr_failure_info(item, entry) self.repr_out_err(res) self.out.sep("_") else: self.out.sep("_ ") - + + def repr_failure_info(self, item, entry): + root = item.fspath + modpath = item.getmodpath() + fn, lineno = item.getpathlineno() + if fn != entry.frame.code.path or \ + entry.frame.code.firstlineno != lineno: + self.out.line("[testcode : %s:%d]" % (fn, lineno+1)) + if root == fn: + self.out.line("[modulepath: %s]" %(modpath)) + else: + self.out.line("[modulepath: %s %s]" %(root.basename, modpath)) def repr_source(self, entry, marker=">"): try: From hpk at codespeak.net Sat Mar 5 15:24:30 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Mar 2005 15:24:30 +0100 (MET) Subject: [py-svn] r9656 - in py/branch/py-collect: code test test/testing Message-ID: <20050305142430.ED52027B4C@code1.codespeak.net> Author: hpk Date: Sat Mar 5 15:24:30 2005 New Revision: 9656 Modified: py/branch/py-collect/code/code.py py/branch/py-collect/code/frame.py py/branch/py-collect/test/collect.py py/branch/py-collect/test/item.py py/branch/py-collect/test/terminal.py py/branch/py-collect/test/testing/test_collect.py py/branch/py-collect/test/testing/test_drive.py Log: various fixes for recursion-detection and failure_demo.py Modified: py/branch/py-collect/code/code.py ============================================================================== --- py/branch/py-collect/code/code.py (original) +++ py/branch/py-collect/code/code.py Sat Mar 5 15:24:30 2005 @@ -5,7 +5,10 @@ rawcode = getattr(rawcode, 'im_func', rawcode) rawcode = getattr(rawcode, 'func_code', rawcode) self.raw = rawcode - self.firstlineno = rawcode.co_firstlineno - 1 + try: + self.firstlineno = rawcode.co_firstlineno - 1 + except AttributeError: + raise TypeError("not a code object: %r" %(rawcode,)) self.name = rawcode.co_name def __eq__(self, other): Modified: py/branch/py-collect/code/frame.py ============================================================================== --- py/branch/py-collect/code/frame.py (original) +++ py/branch/py-collect/code/frame.py Sat Mar 5 15:24:30 2005 @@ -5,7 +5,10 @@ f_code = getattr(f_code, 'im_func', f_code) f_code = getattr(f_code, 'func_code', f_code) self.raw = f_code - self.firstlineno = f_code.co_firstlineno - 1 + try: + self.firstlineno = f_code.co_firstlineno - 1 + except AttributeError: + raise TypeError("not a code object: %r" %(f_code,)) self.name = f_code.co_name def path(self): @@ -41,12 +44,14 @@ "statement this frame is at") def eval(self, code, **vars): - self.f_locals.update(vars) - return eval(code, self.f_globals, self.f_locals) + f_locals = self.f_locals.copy() + f_locals.update(vars) + return eval(code, self.f_globals, f_locals) def exec_(self, code, **vars): - self.f_locals.update(vars) - exec code in self.f_globals, self.f_locals + f_locals = self.f_locals.copy() + f_locals.update(vars) + exec code in self.f_globals, f_locals def repr(self, object): return repr(object) Modified: py/branch/py-collect/test/collect.py ============================================================================== --- py/branch/py-collect/test/collect.py (original) +++ py/branch/py-collect/test/collect.py Sat Mar 5 15:24:30 2005 @@ -275,9 +275,15 @@ # for i,x in py.builtin.enumerate(self.obj()): # yield self.join("[%d]" % i) #return py.builtin.collect(iterator()) - self._objlist = list(self.obj()) - return [self.join("[%d]" % i) - for i in range(len(self._objlist))] + self._objlist = l = [] + namelist = [] + for i, x in py.builtin.enumerate(self.obj()): + call,args = self.getcallargs(x) + if not callable(call): + raise TypeError("yielded test %r not callable" %(call,)) + l.append(x) + namelist.append(self.join("[%d]" % i)) + return namelist def join(self, name): if name[:1] != '[' or name[-1:] != ']': @@ -292,14 +298,14 @@ if isinstance(x, (Collector, )): return x call, args = self.getcallargs(x) - return self.Function(name, self, args, call) + assert callable(call) + return self.Function(name, self, args, obj=call) def getcallargs(self, obj): if isinstance(obj, (tuple, list)): call, args = obj[0], obj[1:] else: call, args = obj, () - assert callable(call) return call, args def getpathlineno(self): Modified: py/branch/py-collect/test/item.py ============================================================================== --- py/branch/py-collect/test/item.py (original) +++ py/branch/py-collect/test/item.py Sat Mar 5 15:24:30 2005 @@ -2,6 +2,8 @@ from inspect import isclass, ismodule +_dummy = object() + class SetupState(object): """ shared state for setting up/tearing down tests. """ def __init__(self): @@ -34,11 +36,11 @@ """ a Function Item is responsible for setting up and executing a Python callable test object. """ - def __init__(self, name, parent, args=(), obj=None): + def __init__(self, name, parent, args=(), obj=_dummy): self.name = name self.parent = parent self.args = args - if obj is not None: + if obj is not _dummy: self._obj = obj def __repr__(self): Modified: py/branch/py-collect/test/terminal.py ============================================================================== --- py/branch/py-collect/test/terminal.py (original) +++ py/branch/py-collect/test/terminal.py Sat Mar 5 15:24:30 2005 @@ -35,7 +35,11 @@ colitem.start = py.std.time.time() def start_Module(self, colitem): - numunits = len(list(colitem.iteritems())) + try: + numunits = len(list(colitem.iteritems())) + except TypeError: + numunits = 99999 + if numunits > 0: fspath = colitem.fspath if self.option.verbose == 0: @@ -209,6 +213,7 @@ if item: self.cut_traceback(traceback, item) last = traceback[-1] + recursioncache = {} for entry in traceback: self.out.line("") if entry == last: @@ -219,6 +224,8 @@ self.out.line("") self.out.line("[%s:%d]" %(entry.frame.code.path, entry.lineno+1)) self.repr_locals(entry) + + # trailing info if entry == last: if item: self.repr_failure_info(item, entry) @@ -226,11 +233,38 @@ self.out.sep("_") else: self.out.sep("_ ") + if not self.option.nomagic and \ + isinstance(excinfo.value, RuntimeError) and \ + self.isrecursive(entry, recursioncache): + self.out.line("Recursion detected (same locals & position)") + self.out.sep("!") + break + + def isrecursive(self, entry, recursioncache): + # recursion detection + key = entry.frame.code.path, entry.frame.lineno + print "checking for recursion at", key + l = recursioncache.setdefault(key, []) + if l: + f = entry.frame + loc = f.f_locals + for otherloc in l: + print "comparing %r and %r" %(loc, otherloc) + if f.is_true(f.eval(co_equal, + __recursioncache_locals_1=loc, + __recursioncache_locals_2=otherloc)): + return True + l.append(entry.frame.f_locals) def repr_failure_info(self, item, entry): root = item.fspath modpath = item.getmodpath() - fn, lineno = item.getpathlineno() + try: + fn, lineno = item.getpathlineno() + except TypeError: + assert isinstance(item.parent, py.test.Generator) + # a generative test yielded a non-callable + fn, lineno = item.parent.getpathlineno() if fn != entry.frame.code.path or \ entry.frame.code.firstlineno != lineno: self.out.line("[testcode : %s:%d]" % (fn, lineno+1)) @@ -326,30 +360,6 @@ self.out.line("%-10s =\\" % (name,)) py.std.pprint.pprint(value, stream=self.out) - def Xrepr_traceback_raw(self, traceback): - recursioncache = {} - for tb in tbentries: - if first: - first = False - else: - self.out.sep('-') - #self.out.line("%-10s = %r" %(name, value)) - key = (path, lineno) - if key not in recursioncache: - recursioncache.setdefault(key, []).append(tb.frame.f_locals) - else: - f = tb.frame - loc = f.f_locals - for x in recursioncache[key]: - if f.is_true(f.eval(co_equal, __recursioncache_locals_1=loc, - __recursioncache_locals_2=x)): - self.out.line("Recursion detected (same locals & position)") - break - else: - #self.out.sep('-') - continue - break - co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2', '?', 'eval') Modified: py/branch/py-collect/test/testing/test_collect.py ============================================================================== --- py/branch/py-collect/test/testing/test_collect.py (original) +++ py/branch/py-collect/test/testing/test_collect.py Sat Mar 5 15:24:30 2005 @@ -105,6 +105,8 @@ assert isinstance(l2[1], py.test.Function) assert l2[0].name == '[0]' assert l2[1].name == '[1]' + + assert l2[0].obj.func_name == 'func1' classlist = l[1].run() assert len(classlist) == 1 Modified: py/branch/py-collect/test/testing/test_drive.py ============================================================================== --- py/branch/py-collect/test/testing/test_drive.py (original) +++ py/branch/py-collect/test/testing/test_drive.py Sat Mar 5 15:24:30 2005 @@ -55,6 +55,42 @@ 'TestClass', 'test_method_one'): assert out.find(line) + def test_recursion_detection(self): + o = py.test.config.tmpdir.ensure('recursiontest', dir=1) + tfile = o.join('test_recursion.py') + tfile.write(py.code.Source(""" + def test_1(): + def f(): + g() + def g(): + f() + f() + """)) + c = StringIO() + drive = py.test.TerminalDriver(file=c) + drive.runpath(o) + out = c.getvalue() + print out + i = out.find('Recursion detected') + assert i != -1 + + def test_generator_yields_None(self): + o = py.test.config.tmpdir.ensure('generatornonetest', dir=1) + tfile = o.join('test_generatornone.py') + tfile.write(py.code.Source(""" + def test_1(): + yield None + """)) + c = StringIO() + drive = py.test.TerminalDriver(file=c) + drive.runpath(o) + out = c.getvalue() + print out + i = out.find('TypeError') + assert i != -1 + + + def test_order_of_execution(): o = py.test.config.tmpdir.ensure('ordertest', dir=1) tfile = o.join('test_orderofexecution.py') From hpk at codespeak.net Sun Mar 6 10:12:20 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 6 Mar 2005 10:12:20 +0100 (MET) Subject: [py-svn] r9672 - py/dist/py/bin Message-ID: <20050306091220.6A02F27B47@code1.codespeak.net> Author: hpk Date: Sun Mar 6 10:12:20 2005 New Revision: 9672 Modified: py/dist/py/bin/_findpy.py Log: relax checks for finding the py library to assume that it is just on sys.path if a version cannot be found nearby ... Modified: py/dist/py/bin/_findpy.py ============================================================================== --- py/dist/py/bin/_findpy.py (original) +++ py/dist/py/bin/_findpy.py Sun Mar 6 10:12:20 2005 @@ -27,6 +27,6 @@ if not searchpy(abspath(os.curdir)): if not searchpy(opd(abspath(sys.argv[0]))): if not searchpy(opd(__file__)): - raise SystemExit, "Could not find 'py' package!" + pass # let's hope it is just on sys.path import py From hpk at codespeak.net Mon Mar 7 10:27:21 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 7 Mar 2005 10:27:21 +0100 (MET) Subject: [py-svn] r9683 - py/dist/py/path/svn/testing Message-ID: <20050307092721.4B1FC27B53@code1.codespeak.net> Author: hpk Date: Mon Mar 7 10:27:21 2005 New Revision: 9683 Modified: py/dist/py/path/svn/testing/test_urlcommand.py py/dist/py/path/svn/testing/test_wccommand.py Log: relative imports -> absolute imports Modified: py/dist/py/path/svn/testing/test_urlcommand.py ============================================================================== --- py/dist/py/path/svn/testing/test_urlcommand.py (original) +++ py/dist/py/path/svn/testing/test_urlcommand.py Mon Mar 7 10:27:21 2005 @@ -1,5 +1,5 @@ import py -from svntestbase import CommonCommandAndBindingTests, getrepowc +from py.__impl__.path.svn.testing.svntestbase import CommonCommandAndBindingTests, getrepowc class TestSvnCommandPath(CommonCommandAndBindingTests): def __init__(self): Modified: py/dist/py/path/svn/testing/test_wccommand.py ============================================================================== --- py/dist/py/path/svn/testing/test_wccommand.py (original) +++ py/dist/py/path/svn/testing/test_wccommand.py Mon Mar 7 10:27:21 2005 @@ -1,5 +1,5 @@ import py -from svntestbase import CommonSvnTests, getrepowc +from py.__impl__.path.svn.testing.svntestbase import CommonSvnTests, getrepowc class TestWCSvnCommandPath(CommonSvnTests): def __init__(self): From hpk at codespeak.net Wed Mar 9 09:19:12 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 9 Mar 2005 09:19:12 +0100 (MET) Subject: [py-svn] r9718 - in py/branch/py-collect: . magic/testing path/local/testing path/svn/testing path/testing test test/testing Message-ID: <20050309081912.DF3CB27B39@code1.codespeak.net> Author: hpk Date: Wed Mar 9 09:19:12 2005 New Revision: 9718 Modified: py/branch/py-collect/__init__.py py/branch/py-collect/initpkg.py py/branch/py-collect/magic/testing/test_autopath.py py/branch/py-collect/path/local/testing/test_local.py py/branch/py-collect/path/local/testing/test_posix.py py/branch/py-collect/path/svn/testing/svntestbase.py py/branch/py-collect/path/svn/testing/test_urlcommand.py py/branch/py-collect/path/svn/testing/test_wccommand.py py/branch/py-collect/path/testing/test_api.py py/branch/py-collect/test/cmdline.py py/branch/py-collect/test/config.py py/branch/py-collect/test/defaultconfig.py py/branch/py-collect/test/drive.py py/branch/py-collect/test/run.py py/branch/py-collect/test/terminal.py py/branch/py-collect/test/testing/test_collect.py py/branch/py-collect/test/testing/test_config.py py/branch/py-collect/test/testing/test_drive.py Log: - revised and cleaned up test initilization/setup to not carry any global options anymore. - Changed temporary directory handling. There now is py.test.ensuretemp(NAME) which basically creates (or reuses) a subdirectory below the /tmp/pytest-... ones. - Fixed a couple of tests to use TestX.setup_class instead of TestX.__init__ - "remote" testing almost works again but not fully Modified: py/branch/py-collect/__init__.py ============================================================================== --- py/branch/py-collect/__init__.py (original) +++ py/branch/py-collect/__init__.py Wed Mar 9 09:19:12 2005 @@ -5,11 +5,15 @@ 'test.raises' : ('./test/raises.py', 'raises'), 'test.fail' : ('./test/item.py', 'fail'), 'test.exit' : ('./test/drive.py', 'exit'), - 'test.config' : ('./test/config.py', 'config'), 'test.Option' : ('./test/tool/optparse.py', 'Option'), 'test.Driver' : ('./test/drive.py', 'Driver'), 'test.TerminalDriver' : ('./test/terminal.py', 'TerminalDriver'), + 'test.config.init' : ('./test/config.py', 'init'), + 'test.config.parse' : ('./test/config.py', 'parse'), + 'test.config.getconfigvalue' : ('./test/config.py', 'getconfigvalue'), + 'test.ensuretemp' : ('./test/config.py', 'ensuretemp'), + 'test.compat.TestCase' : ('./test/compat.py', 'TestCase'), 'test.Collector' : ('./test/collect.py', 'Collector'), Modified: py/branch/py-collect/initpkg.py ============================================================================== --- py/branch/py-collect/initpkg.py (original) +++ py/branch/py-collect/initpkg.py Wed Mar 9 09:19:12 2005 @@ -153,7 +153,7 @@ __tracebackhide__ = True raise AttributeError(name) #print "getattr(%r, %r)" %(self, name) - result = self.__package__._resolve(extpy) + result = self.__package__._resolve(extpy) setattr(self, name, result) del self.__map__[name] # XXX modify some attrs to make a class appear at virtual module level Modified: py/branch/py-collect/magic/testing/test_autopath.py ============================================================================== --- py/branch/py-collect/magic/testing/test_autopath.py (original) +++ py/branch/py-collect/magic/testing/test_autopath.py Wed Mar 9 09:19:12 2005 @@ -3,12 +3,12 @@ class TestAutoPath: getauto = "from py.magic import autopath ; autopath = autopath()" - def __init__(self): - self.root = py.test.config.tmpdir.ensure('autoconfigure', dir=1) - self.initdir = self.root.ensure('pkgdir', dir=1) - self.initdir.ensure('__init__.py') - self.initdir2 = self.initdir.ensure('initdir2', dir=1) - self.initdir2.ensure('__init__.py') + def setup_class(cls): + cls.root = py.test.ensuretemp(cls.__name__) + cls.initdir = cls.root.ensure('pkgdir', dir=1) + cls.initdir.ensure('__init__.py') + cls.initdir2 = cls.initdir.ensure('initdir2', dir=1) + cls.initdir2.ensure('__init__.py') def test_import_autoconfigure__file__with_init(self): testpath = self.initdir2 / 'autoconfiguretest.py' Modified: py/branch/py-collect/path/local/testing/test_local.py ============================================================================== --- py/branch/py-collect/path/local/testing/test_local.py (original) +++ py/branch/py-collect/path/local/testing/test_local.py Wed Mar 9 09:19:12 2005 @@ -4,7 +4,7 @@ class LocalSetup: def setup_class(cls): - cls.root = py.test.config.tmpdir / 'TestLocalPath' + cls.root = py.test.ensuretemp('TestLocalPath') cls.root.ensure(dir=1) setuptestfs(cls.root) @@ -150,7 +150,7 @@ """) def test_sysfind_multiple(self): - dir = py.test.config.tmpdir.ensure('sysfind', dir=1) + dir = py.test.ensuretemp('sysfind') env = py.std.os.environ oldpath = env['PATH'] try: Modified: py/branch/py-collect/path/local/testing/test_posix.py ============================================================================== --- py/branch/py-collect/path/local/testing/test_posix.py (original) +++ py/branch/py-collect/path/local/testing/test_posix.py Wed Mar 9 09:19:12 2005 @@ -5,7 +5,7 @@ disabled = py.std.sys.platform == 'win32' def setup_class(cls): - cls.root = py.test.config.tmpdir / 'TestPosixLocalPath' + cls.root = py.test.ensuretemp(cls.__name__) def setup_method(self, method): name = method.im_func.func_name Modified: py/branch/py-collect/path/svn/testing/svntestbase.py ============================================================================== --- py/branch/py-collect/path/svn/testing/svntestbase.py (original) +++ py/branch/py-collect/path/svn/testing/svntestbase.py Wed Mar 9 09:19:12 2005 @@ -10,10 +10,10 @@ # cache previously obtained wcs! # def getrepowc(): - repo = py.test.config.tmpdir / 'path' / 'repo' - wcdir = py.test.config.tmpdir / 'path' / 'wc' - if not repo.check(): - assert not wcdir.check() + repo = py.test.ensuretemp('repo') + wcdir = py.test.ensuretemp('wc') + if not repo.listdir(): + #assert not wcdir.check() repo.ensure(dir=1) try: py.process.cmdexec('svnadmin create %s' % repo) Modified: py/branch/py-collect/path/svn/testing/test_urlcommand.py ============================================================================== --- py/branch/py-collect/path/svn/testing/test_urlcommand.py (original) +++ py/branch/py-collect/path/svn/testing/test_urlcommand.py Wed Mar 9 09:19:12 2005 @@ -2,9 +2,9 @@ from svntestbase import CommonCommandAndBindingTests, getrepowc class TestSvnCommandPath(CommonCommandAndBindingTests): - def __init__(self): + def setup_class(cls): repo, wc = getrepowc() - self.root = py.path.svnurl(repo) + cls.root = py.path.svnurl(repo) def xtest_copy_file(self): raise py.test.Skipped(msg="XXX fix svnurl first") Modified: py/branch/py-collect/path/svn/testing/test_wccommand.py ============================================================================== --- py/branch/py-collect/path/svn/testing/test_wccommand.py (original) +++ py/branch/py-collect/path/svn/testing/test_wccommand.py Wed Mar 9 09:19:12 2005 @@ -2,8 +2,9 @@ from svntestbase import CommonSvnTests, getrepowc class TestWCSvnCommandPath(CommonSvnTests): - def __init__(self): - repo, self.root = getrepowc() + + def setup_class(cls): + repo, cls.root = getrepowc() def test_status_attributes_simple(self): def assert_nochange(p): Modified: py/branch/py-collect/path/testing/test_api.py ============================================================================== --- py/branch/py-collect/path/testing/test_api.py (original) +++ py/branch/py-collect/path/testing/test_api.py Wed Mar 9 09:19:12 2005 @@ -1,9 +1,11 @@ from py import path, test +import py from py.__impl__.path.svn.testing.test_wccommand import getrepowc class TestAPI: - def __init__(self): - self.root = test.config.tmpdir.ensure('local', dir=1) + + def setup_class(cls): + cls.root = py.test.ensuretemp(cls.__name__) def repr_eval_test(self, p): r = repr(p) Modified: py/branch/py-collect/test/cmdline.py ============================================================================== --- py/branch/py-collect/test/cmdline.py (original) +++ py/branch/py-collect/test/cmdline.py Wed Mar 9 09:19:12 2005 @@ -1,7 +1,4 @@ -from __future__ import generators import py -import sys -from py.__impl__.test import run # # main entry point @@ -9,17 +6,10 @@ def main(): args = py.std.sys.argv[1:] - py.test.config.readconfiguration(*run.getanchors(args)) - filenames = py.test.config.parseargs(args) - if not filenames: - filenames.append(str(py.path.local())) - option = py.test.config.option - try: - if option.session or option.executable: - run.session(args, filenames) - else: - run.inprocess(args, filenames) - except KeyboardInterrupt: + driver, paths = py.test.config.init(args) + try: + driver.runpaths(*paths) + except KeyboardInterrupt: print print "Keybordinterrupt" raise SystemExit, 2 Modified: py/branch/py-collect/test/config.py ============================================================================== --- py/branch/py-collect/test/config.py (original) +++ py/branch/py-collect/test/config.py Wed Mar 9 09:19:12 2005 @@ -12,110 +12,153 @@ # configbasename = 'conftest.py' -class Config: - def __init__(self): - self.configpaths = [defaultconfig] - self.option = optparse.Values() - self.parseargs([]) - self.configpaths.pop() - - def _gettmpdir(self, sessiondir=[]): - try: - return sessiondir[0] - except IndexError: - d = py.path.local.make_numbered_dir(base='pytest-') - sessiondir.append(d) - return d - tmpdir = property(_gettmpdir, None, None, "Temporary Directory") - - def readconfiguration(self, *anchors): - """ read configuration files left-to-right for the given anchor file. """ - self.configpaths = [] - d = {} - for anchor in anchors: - for p in anchor.parts(): - x = p.join(configbasename) - if x.check(file=1): - extpy = py.path.extpy(x) - extpy.resolve() # trigger loading it - if extpy not in d: - self.configpaths.append(extpy) - d[extpy] = True - self.configpaths.sort(lambda x,y: cmp(len(str(x)), len(str(y)))) - self.configpaths.append(defaultconfig) - - def getconfigvalue(self, path, name): - for p in path.parts(reverse=True): - x = p.join(configbasename) - if x.check(file=1): - extpy = py.path.extpy(x, name) - if extpy.check(): - return extpy.resolve() +basetemp = None +def ensuretemp(string, dir=1): + """ return temporary directory path with + the given string as the trailing part. + """ + global basetemp + if basetemp is None: + basetemp = py.path.local.make_numbered_dir(base='pytest-') + return basetemp.ensure(string, dir=dir) + +def getconfigvalue(path, name, default=dummy, trydefaultconfig=True): + """ return config value 'name' from the first conftest file found + from traversing up from the given 'path' + """ + for p in path.parts(reverse=True): + x = p.join(configbasename) + if x.check(file=1): + extpy = py.path.extpy(x, name) + if extpy.check(): + return extpy.resolve() + if trydefaultconfig: extpy = defaultconfig.join(name) if extpy.check(): return extpy.resolve() + if default is dummy: raise ValueError("could not find config value %r" % name) + return default - def getfirst(self, param, default=dummy): - """ return first found parameter. """ - for config in self.configpaths: - x = config.join(param) - if x.check(): - return x.resolve() - if default is dummy: - raise AttributeError, param - return default - #if default is not dummy: - # return getattr(self, param, default) - #return getattr(self, param) - - def parseargs(self, args): - # first a small fight with optparse to merge the - # conftest.py file options correctly - parser = optparse.OptionParser() - for config in self.configpaths: - meth = config.join('options') - if meth.check(): - groupname, groupoptions = meth.resolve() - optgroup = optparse.OptionGroup(parser, groupname) - optgroup.add_options(groupoptions) - parser.add_option_group(optgroup) - - # extract and remove defaults from options - for option in flattenoptions(parser): - if option.dest: - value = self.getfirst(option.dest, option.default) - #print "setting %r to %r" %(option.dest, value) - setattr(self.option, option.dest, value) - #option.default = 'NODEFAULT' - - # parse cmdline args - cmdlineoption, remaining = parser.parse_args(args, self.option) - self.fixoptions() - # override previously computed defaults - #for name in cmdlineoption.__dict__: - # if not name.startswith('_'): - # print "resetting %r to %r" %(name, cmdlineoption.__dict__[name]) - # setattr(self.option, name, cmdlineoption.__dict__[name]) - return remaining - - - def fixoptions(self): - if self.option.session and self.option.usepdb: - raise ValueError, "--session together with --pdb not supported yet." - if self.option.executable and self.option.usepdb: - raise ValueError, "--exec together with --pdb not supported yet." - - # setting a correct executable - if self.option.executable is not None: - exe = py.path.local(py.std.os.path.expanduser(self.option.executable)) - if not exe.check(): - exe = py.path.local.sysfind(self.option.executable) - assert exe.check() - self.option.executable = exe - - +def init(args, ignoreremote=False): + """ return driver object and test paths, determined from + commandline arguments and config files. + """ + cmdlineoption, remaining = parse(args) + if not ignoreremote and (cmdlineoption.session or cmdlineoption.executable): + # execute in child process, i.e. setup a frontend + # pseudo-driver and do the real thing on the other side + from py.__impl__.test.run import FrontendDriver + return FrontendDriver(cmdlineoption, args), remaining + Driver = getdriverclass(args) + remaining = [py.path.local(x) for x in remaining] + if not remaining: + remaining.append(py.path.local()) + driver = Driver(cmdlineoption) + return driver, remaining + +def parse(args=None): + """ return (Options, remaining args) by parsing + the given arguments. + """ + if args is None: + args = [] + anchorpaths = getanchorpaths(args) + configpaths = findconfigpaths(anchorpaths) + parser = makeparser(configpaths) + cmdlineoption, remaining = parser.parse_args(args) + fixoptions(cmdlineoption) + return cmdlineoption, remaining + +# # helpers +# +def getdriverclass(args): + """ return Driver class determined from cmdlines + arguments (in a somewhat heuristic way). + """ + # find driver + Driver = None + options = [] + anchorpaths = getanchorpaths(args) + for anchor in anchorpaths: + tmp = getconfigvalue(anchor, 'Driver', + default=None, trydefaultconfig=False) + if tmp is not None: + if Driver is not None and Driver[1] != tmp: + raise RuntimeError("conflicting Drivers from %s and %s" %( + Driver[0], anchor)) + Driver = (anchor, tmp) + if Driver is None: + Driver = getconfigvalue(anchor, "Driver", trydefaultconfig=True) + else: + Driver = Driver[1] + return Driver + +def fixoptions(option): + """ sanity checks and postprocessing of options. """ + + if option.session and option.usepdb: + raise ValueError, "--session together with --pdb not supported yet." + if option.executable and option.usepdb: + raise ValueError, "--exec together with --pdb not supported yet." + + # setting a correct executable + if option.executable is not None: + exe = py.path.local(py.std.os.path.expanduser(option.executable)) + if not exe.check(): + exe = py.path.local.sysfind(option.executable) + assert exe.check() + option.executable = exe + +def makeparser(configpaths): + # first a small fight with optparse to merge the + # conftest.py file options correctly + parser = optparse.OptionParser() + for config in configpaths: + meth = config.join('options') + if meth.check(): + groupname, groupoptions = meth.resolve() + optgroup = optparse.OptionGroup(parser, groupname) + optgroup.add_options(groupoptions) + parser.add_option_group(optgroup) + return parser + +def findconfigpaths(anchors): + """ return test configuration paths. """ + configpaths = [] + d = {} + for anchor in anchors: + for p in anchor.parts(): + x = p.join(configbasename) + if x.check(file=1): + extpy = py.path.extpy(x) + extpy.resolve() # trigger loading it + if extpy not in d: + configpaths.append(extpy) + d[extpy] = True + configpaths.sort(lambda x,y: cmp(len(str(x)), len(str(y)))) + configpaths.append(defaultconfig) + return configpaths + +def getcollectors(filenames): + """ return filesystem collectors from filenames. """ + current = py.path.local() + for fn in filenames: + fullfn = current.join(fn, abs=1) + yield getfscollector(fullfn) + +def getanchorpaths(args): + """ yield "anchors" from skimming the args for existing files/dirs. """ + current = py.path.local() + l = [] + for arg in args: + anchor = current.join(arg, abs=1) + if anchor.check(): + l.append(anchor) + if not l: + l = [current] + return l def flattenoptions(parser): for group in parser.option_groups: @@ -123,6 +166,3 @@ yield y for x in parser.option_list: yield x - -# the default that is visible globally (XXX?) -config = Config() Modified: py/branch/py-collect/test/defaultconfig.py ============================================================================== --- py/branch/py-collect/test/defaultconfig.py (original) +++ py/branch/py-collect/test/defaultconfig.py Wed Mar 9 09:19:12 2005 @@ -1,6 +1,8 @@ import py Option = py.test.Option +Driver = py.test.TerminalDriver + Module = py.test.Module Directory = py.test.Directory Class = py.test.Class Modified: py/branch/py-collect/test/drive.py ============================================================================== --- py/branch/py-collect/test/drive.py (original) +++ py/branch/py-collect/test/drive.py Wed Mar 9 09:19:12 2005 @@ -1,45 +1,33 @@ import py from py.__impl__.test.tool.outerrcapture import SimpleOutErrCapture -class ShadowOptions(object): - def __init__(self, obj): - self._obj = obj - def __getattr__(self, name): - return getattr(self._obj, name) - class Driver(object): """ A Driver gets test Items from Collectors, # executes the Items and sends the Outcome to the Reporter. """ - def __init__(self): + def __init__(self, option): self._memo = [] - self.option = ShadowOptions(py.test.config.option) + self.option = option def shouldclose(self): return False - def header(self): + def header(self, colitems): """ setup any neccessary resources. """ if not self.option.nomagic: py.magic.invoke(assertion=1) - def footer(self): + def footer(self, colitems): """ teardown any resources we know about. """ py.test.Item.state.teardown_all() if not self.option.nomagic: py.magic.revoke(assertion=1) def start(self, colitem): - if not self.option.nocapture and isinstance(colitem, py.test.Item): - assert not hasattr(colitem, 'iocapture') - colitem.iocapture = SimpleOutErrCapture() + pass def finish(self, colitem, res): - try: - res.out, res.err = colitem.iocapture.reset() - except AttributeError: - pass self._memo.append((colitem, res)) def getresults(self, cls): @@ -48,44 +36,56 @@ def warning(self, msg): raise Warning(msg) - def runpath(self, path): + def runpaths(self, *paths): + #print "runpaths", paths from py.__impl__.test.collect import getfscollector - col = getfscollector(path) - return self.run(col) + cols = [getfscollector(p) for p in paths] + return self.run(cols) - def run(self, *colitems): + def run(self, colitems): """ main loop for running tests. """ try: - self.header() + self.header(colitems) try: for colitem in colitems: self.runone(colitem) finally: - self.footer() + self.footer(colitems) except Exit, ex: pass def runone(self, colitem): if self.shouldclose(): raise SystemExit, "received external close signal" - self.start(colitem) + + capture = None + if not self.option.nocapture and isinstance(colitem, py.test.Item): + capture = SimpleOutErrCapture() try: - try: - res = self.runinner(colitem) - except (KeyboardInterrupt, Exit): - res = None - raise - except colitem.Outcome, res: - res.excinfo = py.code.ExceptionInfo() - pass - except: - excinfo = py.code.ExceptionInfo() - res = colitem.Failed(excinfo=excinfo) - else: - assert (res is None or isinstance(res, (list, colitem.Outcome)) or - isinstance(res, py.builtin.collect)) - finally: - self.finish(colitem, res) + self.start(colitem) + try: + try: + res = self.runinner(colitem) + except (KeyboardInterrupt, Exit): + res = None + raise + except colitem.Outcome, res: + res.excinfo = py.code.ExceptionInfo() + except: + excinfo = py.code.ExceptionInfo() + res = colitem.Failed(excinfo=excinfo) + else: + assert (res is None or + isinstance(res, (list, colitem.Outcome))) + finally: + self.finish(colitem, res) + finally: + if capture is not None: + out, err = capture.reset() + try: + res.out, res.err = out, err + except AttributeError: + pass def runinner(self, colitem): if self.option.collectonly and isinstance(colitem, py.test.Item): Modified: py/branch/py-collect/test/run.py ============================================================================== --- py/branch/py-collect/test/run.py (original) +++ py/branch/py-collect/test/run.py Wed Mar 9 09:19:12 2005 @@ -75,9 +75,8 @@ channel.close() channel.gateway.exit() -def failure_master(args, filenames, failures): - exe = py.test.config.option.executable - gw = py.execnet.PopenGateway(python=exe or sys.executable) +def failure_master(executable, args, failures): + gw = py.execnet.PopenGateway(executable) outproxy = StdouterrProxy(gw) outproxy.setup() try: @@ -85,79 +84,67 @@ from py.__impl__.test.run import failure_slave failure_slave(channel) """) - channel.send((args, filenames, failures)) + channel.send((args, failures)) return waitfinish(channel) finally: outproxy.teardown() def failure_slave(channel): """ we run this on the other side. """ - args, filenames, failures = channel.receive() - filenames = map(py.path.local, filenames) - py.test.config.readconfiguration(*filenames) - py.test.config.parseargs(args) - - if failures: - col = FailureCollector(failures) + args, failures = channel.receive() + driver, paths = py.test.config.init(args, ignoreremote=True) + if failures: + cols = [FailureCollector(failures)] else: - col = list(getcollectors(filenames)) - driver = py.test.Driver(channel) - failures = driver.run(col) + cols = list(getcollectors(paths)) + driver.shouldclose = channel.isclosed + failures = driver.run(cols) channel.send(failures) class FailureCollector(py.test.Collector): def __init__(self, failures): self.failures = failures def __iter__(self): - for root,modpath in self.failures: - extpy = py.path.extpy(root, modpath) - yield self.Item(extpy) + for root, names in self.failures: + current = root + while names: + name = names.pop(0) + try: + current = current.join(name) + except NameError: + print "WARNING: could not find %s on %r" %(name, current) + break + else: + yield current def getcollectors(filenames): current = py.path.local() for fn in filenames: - fullfn = current.join(fn, abs=1) + fullfn = current.join(str(fn), abs=1) yield getfscollector(fullfn) -def getanchors(args): - """ yield "anchors" from skimming the args for existing files/dirs. """ - current = py.path.local() - l = [] - for arg in args: - anchor = current.join(arg, abs=1) - if anchor.check(): - l.append(anchor) - if not l: - l = [current] - return l - -# -# Testing Modes -# -def inprocess(args, filenames): - """ we run this on the other side. """ - print "inprocess" - fncollectors = list(getcollectors(filenames)) - driver = py.test.TerminalDriver() - driver.run(*fncollectors) - -def session(args, filenames): - statcache = {} - # XXX find out rootdir automatically with - # something like py.magic.autopath() ? - rootdir = py.path.local(py.test.config.getfirst('rootdir', py.path.local())) - l = len(str(rootdir)) - failures = [] - while 1: - if py.test.config.option.session: - while not checkpyfilechange(rootdir, statcache): - py.std.time.sleep(0.4) - failures = failure_master(args, filenames, failures) - if not py.test.config.option.session: - break - print "#" * 60 - print "# session mode: %d failures remaining" % len(failures) - for x in failures: - print "Failure at: %r" % (x,) - print "# watching py files below %s" % rootdir - print "# ", "^" * l +class FrontendDriver: + def __init__(self, option, args): + self.option = option + self.args = args + + def runpaths(self, *paths): + statcache = {} + # XXX figure out a better rootdir? + rootdir = py.path.local() + failures = [] + while 1: + if self.option.session: + while not checkpyfilechange(rootdir, statcache): + py.std.time.sleep(0.4) + failures = failure_master(self.option.executable or sys.executable, + self.args, failures) + if not self.option.session: + break + print "#" * 60 + print "# session mode: %d failures remaining" % len(failures) + for x in failures: + name = ":".join(x) # XXX + print "Failure at: %r" % (name,) + print "# watching py files below %s" % rootdir + print "# ", "^" * len(rootdir) Modified: py/branch/py-collect/test/terminal.py ============================================================================== --- py/branch/py-collect/test/terminal.py (original) +++ py/branch/py-collect/test/terminal.py Wed Mar 9 09:19:12 2005 @@ -5,8 +5,8 @@ Item = py.test.Item class TerminalDriver(py.test.Driver): - def __init__(self, file=None): - super(TerminalDriver, self).__init__() + def __init__(self, option, file=None): + super(TerminalDriver, self).__init__(option) if file is None: file = py.std.sys.stdout self.out = getout(file) @@ -69,13 +69,13 @@ def finish(self, colitem, result): end = now() + super(TerminalDriver, self).finish(colitem, result) if self.option.collectonly: cols = self._opencollectors last = cols.pop() #assert last == colitem, "expected %r, got %r" %(last, colitem) return colitem.elapsedtime = end - colitem.start - super(TerminalDriver, self).finish(colitem, result) if self.option.usepdb: if isinstance(result, Item.Failed): print "dispatching to ppdb", colitem @@ -105,8 +105,8 @@ # ------------------- # HEADER information # ------------------- - def header(self): - super(TerminalDriver, self).header() + def header(self, colitems): + super(TerminalDriver, self).header(colitems) self.out.sep("=", "test process starts") option = self.option if option.session: @@ -123,12 +123,15 @@ self.out.line("using py lib: %s " % ( py.path.local(py.__file__).dirpath(), rev)) - for i, x in py.builtin.enumerate(py.test.config.configpaths): - self.out.line("initial testconfig %d: %s" %(i, x)) - additional = py.test.config.getfirst('additionalinfo') - if additional: - for key, descr in additional(): - self.out.line("%s: %s" %(key, descr)) + for x in colitems: + self.out.line("test target: %s" %(x.fspath,)) + + #for i, x in py.builtin.enumerate(py.test.config.configpaths): + # self.out.line("initial testconfig %d: %s" %(i, x)) + #additional = py.test.config.getfirst('additionalinfo') + #if additional: + # for key, descr in additional(): + # self.out.line("%s: %s" %(key, descr)) self.out.sep("=") self.starttime = now() @@ -136,8 +139,8 @@ # FOOTER information # ------------------- - def footer(self): - super(TerminalDriver, self).footer() + def footer(self, colitems): + super(TerminalDriver, self).footer(colitems) self.endtime = now() self.out.line() self.skippedreasons() @@ -243,13 +246,12 @@ def isrecursive(self, entry, recursioncache): # recursion detection key = entry.frame.code.path, entry.frame.lineno - print "checking for recursion at", key + #print "checking for recursion at", key l = recursioncache.setdefault(key, []) if l: f = entry.frame loc = f.f_locals for otherloc in l: - print "comparing %r and %r" %(loc, otherloc) if f.is_true(f.eval(co_equal, __recursioncache_locals_1=loc, __recursioncache_locals_2=otherloc)): Modified: py/branch/py-collect/test/testing/test_collect.py ============================================================================== --- py/branch/py-collect/test/testing/test_collect.py (original) +++ py/branch/py-collect/test/testing/test_collect.py Wed Mar 9 09:19:12 2005 @@ -2,6 +2,8 @@ import py datadir = py.magic.autopath().dirpath('data') +tmpdir = py.test.ensuretemp('test_collect') + def test_failing_import_execfile(): fn = datadir / 'failingimport.py' col = py.test.Module(fn) @@ -77,7 +79,7 @@ # def test_generative_simple(): - o = py.test.config.tmpdir.ensure('generativetest', dir=1) + o = tmpdir.ensure('generativetest', dir=1) tfile = o.join('test_generative.py') tfile.write(py.code.Source(""" def func1(arg, arg2): @@ -120,7 +122,7 @@ assert l2[1].name == '[1]' def test_custom_collection_from_conftest(): - o = py.test.config.tmpdir.ensure('customconfigtest', dir=1) + o = tmpdir.ensure('customconfigtest', dir=1) o.ensure('conftest.py').write("""if 1: import py class MyFunction(py.test.Function): Modified: py/branch/py-collect/test/testing/test_config.py ============================================================================== --- py/branch/py-collect/test/testing/test_config.py (original) +++ py/branch/py-collect/test/testing/test_config.py Wed Mar 9 09:19:12 2005 @@ -23,30 +23,31 @@ assert not obj.option.verbose def test_tmpdir(): - d1 = config.tmpdir - d2 = config.tmpdir + d1 = py.test.ensuretemp('hello') + d2 = py.test.ensuretemp('hello') assert d1 == d2 + assert d1.check(dir=1) -def test_config_order(): - from py.__impl__.test import config - o = py.test.config.tmpdir.ensure('configorder', dir=1) - o.ensure('conftest.py').write('x=1 ; import py ; py._x = [x]') - o.ensure('a/conftest.py').write('x=2 ; import py ; py._x.append(x)') - o.ensure('a/b/c/conftest.py').write('x=3 ; import py ; py._x.append(x)') - cfg = config.Config() - cfg.readconfiguration(o) - assert cfg.getfirst('x') == 1 - assert py._x == [1] - - cfg = config.Config() - cfg.readconfiguration(o.join('a/b/c')) - assert cfg.getfirst('x') == 1 - assert py._x == [1,2,3] - -def test_getconfigvalue(): - from py.__impl__.test import config - cfg = config.Config() - o = py.test.config.tmpdir.ensure('configtest', dir=1) - o.ensure('conftest.py').write('x=1') - assert cfg.getconfigvalue(o, 'x') == 1 - py.test.raises(ValueError, "cfg.getconfigvalue(o, 'y')") +#def test_config_order(): +# from py.__impl__.test import config +# o = py.test.ensuretemp('configorder') +# o.ensure('conftest.py').write('x=1 ; import py ; py._x = [x]') +# o.ensure('a/conftest.py').write('x=2 ; import py ; py._x.append(x)') +# o.ensure('a/b/c/conftest.py').write('x=3 ; import py ; py._x.append(x)') +# cfg = config.Config() +# cfg.readconfiguration(o) +# assert cfg.getfirst('x') == 1 +# assert py._x == [1] +# +# cfg = config.Config() +# cfg.readconfiguration(o.join('a/b/c')) +# assert cfg.getfirst('x') == 1 +# assert py._x == [1,2,3] +# +#def test_getconfigvalue(): +# from py.__impl__.test import config +# cfg = config.Config() +# o = py.test.ensuretemp('configtest') +# o.ensure('conftest.py').write('x=1') +# assert cfg.getconfigvalue(o, 'x') == 1 +# py.test.raises(ValueError, "cfg.getconfigvalue(o, 'y')") Modified: py/branch/py-collect/test/testing/test_drive.py ============================================================================== --- py/branch/py-collect/test/testing/test_drive.py (original) +++ py/branch/py-collect/test/testing/test_drive.py Wed Mar 9 09:19:12 2005 @@ -2,50 +2,59 @@ datadir = py.magic.autopath().dirpath('data') from cStringIO import StringIO +tmpdir = py.test.ensuretemp('test_drive') + class TestDefaultDriver: def test_simple(self): - drive = py.test.Driver() - drive.option.nocapture = True - drive.runpath(datadir / 'filetest.py') - l = drive.getresults(py.test.Item.Failed) + driver, paths = py.test.config.init([]) + driver.runpaths(datadir / 'filetest.py') + l = driver.getresults(py.test.Item.Failed) assert len(l) == 2 - l = drive.getresults(py.test.Item.Passed) + l = driver.getresults(py.test.Item.Passed) assert not l - + +#f = open('/tmp/logfile', 'wa') class TestTerminalDriver: + + def setup_method(self, method): + self.file = StringIO() + option, _ = py.test.config.parse() + self.driver = py.test.TerminalDriver(option, file=self.file) + #print >>f, "driver %r is setup for %r" %(self.driver, method) + #f.flush() + #print "driver is setup", self.driver + + #def teardown_method(self, method): + #print >>f, "driver %r finished method %r" % (self.driver, method) + #f.flush() + def test_terminal(self): - c = StringIO() - drive = py.test.TerminalDriver(file=c) - drive.runpath(datadir / 'filetest.py') - out = c.getvalue() - print "memo" - print drive._memo - print "out" - print out - l = drive.getresults(py.test.Item.Failed) + self.driver.runpaths(datadir / 'filetest.py') + out = self.file.getvalue() + #print "memo" + #print self.driver._memo + #print "out" + #print out + l = self.driver.getresults(py.test.Item.Failed) assert len(l) == 2 assert out.find('2 failed') != -1 def test_exit_first_problem(self): - drive = py.test.TerminalDriver() - if drive.option.usepdb: - py.test.skip("options of sub-runs are not isolated") - drive.option.exitfirstproblem = True - drive.runpath(str(datadir / 'filetest.py')) - l = drive.getresults(py.test.Item.Failed) + driver = self.driver + driver.option.exitfirstproblem = True + driver.runpaths(str(datadir / 'filetest.py')) + l = driver.getresults(py.test.Item.Failed) assert len(l) == 1 - l = drive.getresults(py.test.Item.Passed) + l = driver.getresults(py.test.Item.Passed) assert not l - def test_collectonly(self): - c = StringIO() - drive = py.test.TerminalDriver(file=c) - drive.option.collectonly = True - drive.runpath(str(datadir / 'filetest.py')) - out = c.getvalue() - print out - l = drive.getresults(py.test.Item.Failed) + driver = self.driver + driver.option.collectonly = True + driver.runpaths(str(datadir / 'filetest.py')) + out = self.file.getvalue() + #print out + l = driver.getresults(py.test.Item.Failed) #if l: # x = l[0][1].excinfo # print x.exconly() @@ -56,7 +65,7 @@ assert out.find(line) def test_recursion_detection(self): - o = py.test.config.tmpdir.ensure('recursiontest', dir=1) + o = tmpdir.ensure('recursiontest', dir=1) tfile = o.join('test_recursion.py') tfile.write(py.code.Source(""" def test_1(): @@ -66,62 +75,62 @@ f() f() """)) - c = StringIO() - drive = py.test.TerminalDriver(file=c) - drive.runpath(o) - out = c.getvalue() - print out + #print "hello" + driver = self.driver + #driver.option.nocapture = True + print "calling runpaths", o + driver.runpaths(str(o)) + print "back from runpaths", o + out = self.file.getvalue() + #print out i = out.find('Recursion detected') assert i != -1 def test_generator_yields_None(self): - o = py.test.config.tmpdir.ensure('generatornonetest', dir=1) + o = tmpdir.ensure('generatornonetest', dir=1) tfile = o.join('test_generatornone.py') tfile.write(py.code.Source(""" def test_1(): yield None """)) - c = StringIO() - drive = py.test.TerminalDriver(file=c) - drive.runpath(o) - out = c.getvalue() - print out + driver = self.driver + driver.runpaths(o) + out = self.file.getvalue() + #print out i = out.find('TypeError') assert i != -1 - - -def test_order_of_execution(): - o = py.test.config.tmpdir.ensure('ordertest', dir=1) - tfile = o.join('test_orderofexecution.py') - tfile.write(py.code.Source(""" - l = [] - def test_1(): - l.append(1) - def test_2(): - l.append(2) - def test_3(): - assert l == [1,2] - class Testmygroup: - reslist = l - def test_1(self): - self.reslist.append(1) - def test_2(self): - self.reslist.append(2) - def test_3(self): - self.reslist.append(3) - def test_4(self): - assert self.reslist == [1,2,1,2,3] - """)) - - drive = py.test.Driver() - drive.runpath(o) - l = drive.getresults(py.test.Item.Failed) - assert len(l) == 0 - l = drive.getresults(py.test.Item.Passed) - assert len(l) == 7 - # also test listnames() here ... - item, result = l[-1] - assert item.name == 'test_4' - names = item.listnames() - assert names == ['ordertest', 'test_orderofexecution.py', 'Testmygroup', '()', 'test_4'] + def test_order_of_execution(self): + o = tmpdir.ensure('ordertest', dir=1) + tfile = o.join('test_orderofexecution.py') + tfile.write(py.code.Source(""" + l = [] + def test_1(): + l.append(1) + def test_2(): + l.append(2) + def test_3(): + assert l == [1,2] + class Testmygroup: + reslist = l + def test_1(self): + self.reslist.append(1) + def test_2(self): + self.reslist.append(2) + def test_3(self): + self.reslist.append(3) + def test_4(self): + assert self.reslist == [1,2,1,2,3] + """)) + + driver = self.driver + driver.runpaths(o) + l = driver.getresults(py.test.Item.Failed) + assert len(l) == 0 + l = driver.getresults(py.test.Item.Passed) + assert len(l) == 7 + # also test listnames() here ... + item, result = l[-1] + assert item.name == 'test_4' + names = item.listnames() + assert names == ['ordertest', 'test_orderofexecution.py', 'Testmygroup', '()', 'test_4'] From arigo at codespeak.net Sun Mar 13 11:24:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 13 Mar 2005 11:24:44 +0100 (MET) Subject: [py-svn] r9756 - in py/dist/py: . c-extension/extractdict magic magic/testing Message-ID: <20050313102444.E12EF27B4F@code1.codespeak.net> Author: arigo Date: Sun Mar 13 11:24:44 2005 New Revision: 9756 Added: py/dist/py/c-extension/extractdict/ py/dist/py/c-extension/extractdict/extractdict.c (contents, props changed) py/dist/py/magic/extractdict.py (contents, props changed) py/dist/py/magic/testing/test_extractdict.py (contents, props changed) Modified: py/dist/py/__init__.py Log: py.magic.extractdict(x) -> returns the C-level dictionary of 'x'. Useful to hack built-in types :-) Modified: py/dist/py/__init__.py ============================================================================== --- py/dist/py/__init__.py (original) +++ py/dist/py/__init__.py Sun Mar 13 11:24:44 2005 @@ -39,6 +39,7 @@ 'magic.autopath' : ('./magic/autopath.py', 'autopath'), 'magic.View' : ('./magic/viewtype.py', 'View'), 'magic.AssertionError' : ('./magic/assertion.py', 'AssertionError'), + 'magic.extractdict' : ('./magic/extractdict.py', 'extractdict'), 'code.compile' : ('./code/source.py', 'compile_'), 'code.Source' : ('./code/source.py', 'Source'), Added: py/dist/py/c-extension/extractdict/extractdict.c ============================================================================== --- (empty file) +++ py/dist/py/c-extension/extractdict/extractdict.c Sun Mar 13 11:24:44 2005 @@ -0,0 +1,35 @@ +#include + + +static PyObject* extractdict(PyObject* self, PyObject* arg) +{ + PyObject *dict; + PyObject **p = _PyObject_GetDictPtr(arg); + + if (p == NULL) { + PyErr_Format(PyExc_TypeError, + "'%.100s' object has no __dict__", + arg->ob_type->tp_name); + return NULL; + } + dict = *p; + if (dict == NULL) { + dict = PyDict_New(); + if (dict == NULL) + return NULL; + *p = dict; + } + Py_INCREF(dict); + return dict; +} + + +static PyMethodDef ExtractDictMethods[] = { + {"extractdict", extractdict, METH_O, NULL}, + {NULL, NULL} /* Sentinel */ +}; + +void initextractdict(void) +{ + Py_InitModule("extractdict", ExtractDictMethods); +} Added: py/dist/py/magic/extractdict.py ============================================================================== --- (empty file) +++ py/dist/py/magic/extractdict.py Sun Mar 13 11:24:44 2005 @@ -0,0 +1,5 @@ + +import py +gdir = py.path.local(py.__file__).dirpath() +path = gdir.join('c-extension', 'extractdict', 'extractdict.c') +extractdict = path.getpymodule().extractdict Added: py/dist/py/magic/testing/test_extractdict.py ============================================================================== --- (empty file) +++ py/dist/py/magic/testing/test_extractdict.py Sun Mar 13 11:24:44 2005 @@ -0,0 +1,27 @@ +import py + +def test_extractdict(): + from py.magic import extractdict + d = extractdict(str) + assert 'join' in d + saved = d['join'] + try: + del d['join'] + assert not hasattr('', 'join') + finally: + d['join'] = saved + +def test_typeerror(): + from py.magic import extractdict + py.test.raises(TypeError, extractdict, 5) + +class X(object): + pass + +def test_emptydict(): + from py.magic import extractdict + x = X() + d1 = extractdict(x) + assert d1 is x.__dict__ + d2 = extractdict(x) + assert d2 is d1 From tismer at codespeak.net Mon Mar 14 14:44:18 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 14 Mar 2005 14:44:18 +0100 (MET) Subject: [py-svn] r9760 - py/dist/py/c-extension/extractdict Message-ID: <20050314134418.BDCCC27B75@code1.codespeak.net> Author: tismer Date: Mon Mar 14 14:44:18 2005 New Revision: 9760 Modified: py/dist/py/c-extension/extractdict/extractdict.c Log: small change to make it windows compatible. Modified: py/dist/py/c-extension/extractdict/extractdict.c ============================================================================== --- py/dist/py/c-extension/extractdict/extractdict.c (original) +++ py/dist/py/c-extension/extractdict/extractdict.c Mon Mar 14 14:44:18 2005 @@ -29,7 +29,7 @@ {NULL, NULL} /* Sentinel */ }; -void initextractdict(void) +PyMODINIT_FUNC initextractdict(void) { Py_InitModule("extractdict", ExtractDictMethods); } From hpk at codespeak.net Tue Mar 15 14:19:22 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 15 Mar 2005 14:19:22 +0100 (MET) Subject: [py-svn] r9787 - in py/dist/py/test: . testing Message-ID: <20050315131922.760CE27B92@code1.codespeak.net> Author: hpk Date: Tue Mar 15 14:19:22 2005 New Revision: 9787 Modified: py/dist/py/test/collect.py py/dist/py/test/testing/test_collect.py Log: fixed collect.Errors as suggested by Jan Balster Modified: py/dist/py/test/collect.py ============================================================================== --- py/dist/py/test/collect.py (original) +++ py/dist/py/test/collect.py Tue Mar 15 14:19:22 2005 @@ -24,7 +24,7 @@ self.excinfo = py.code.ExceptionInfo(excinfo) def __repr__(self): - tb = list(self.excinfo)[-1] + tb = list(self.excinfo.traceback)[-1] return '' % (tb.frame.code.path, tb.lineno+1) Modified: py/dist/py/test/testing/test_collect.py ============================================================================== --- py/dist/py/test/testing/test_collect.py (original) +++ py/dist/py/test/testing/test_collect.py Tue Mar 15 14:19:22 2005 @@ -7,6 +7,14 @@ datadir = testdir / 'data' +def test_Error_repr_returns_string(): + try: + raise TypeError + except: + import sys + error = py.test.collect.Error(sys.exc_info()) + assert isinstance(repr(error), py.std.types.StringTypes) + def test_failing_import_execfile(): fn = datadir / 'failingimport.py' col = collect.Module(py.path.extpy(fn)) From hpk at codespeak.net Wed Mar 16 16:52:07 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 16 Mar 2005 16:52:07 +0100 (MET) Subject: [py-svn] r9835 - py/branch/py-collect/test Message-ID: <20050316155207.C15A727B80@code1.codespeak.net> Author: hpk Date: Wed Mar 16 16:52:07 2005 New Revision: 9835 Modified: py/branch/py-collect/test/drive.py py/branch/py-collect/test/run.py Log: incorporated Jan Balster's fixes to session/remote modes Modified: py/branch/py-collect/test/drive.py ============================================================================== --- py/branch/py-collect/test/drive.py (original) +++ py/branch/py-collect/test/drive.py Wed Mar 16 16:52:07 2005 @@ -54,6 +54,11 @@ except Exit, ex: pass + # return [(fspath as string, [names as string])] + return [(str(item.listchain()[0].fspath), item.listnames()) + for item, res in self.getresults(py.test.Item.Failed)] + + def runone(self, colitem): if self.shouldclose(): raise SystemExit, "received external close signal" Modified: py/branch/py-collect/test/run.py ============================================================================== --- py/branch/py-collect/test/run.py (original) +++ py/branch/py-collect/test/run.py Wed Mar 16 16:52:07 2005 @@ -94,7 +94,7 @@ args, failures = channel.receive() driver, paths = py.test.config.init(args, ignoreremote=True) if failures: - cols = [FailureCollector(failures)] + cols = FailureCollector(failures) else: cols = list(getcollectors(paths)) driver.shouldclose = channel.isclosed @@ -105,8 +105,15 @@ def __init__(self, failures): self.failures = failures def __iter__(self): - for root, names in self.failures: - current = root + for rootpath, names in self.failures: + root = py.path.local(rootpath) + if root.check(dir=1): + current = py.test.Directory(root).Directory(root) + elif root.check(file=1): + current = py.test.Module(root).Module(root) + # root is fspath of names[0] -> pop names[0] + # slicing works with empty lists + names = names[1:] while names: name = names.pop(0) try: @@ -143,8 +150,8 @@ break print "#" * 60 print "# session mode: %d failures remaining" % len(failures) - for x in failures: - name = ":".join(x) # XXX + for root, names in failures: + name = ":".join(names) # XXX print "Failure at: %r" % (name,) print "# watching py files below %s" % rootdir - print "# ", "^" * len(rootdir) + print "# ", "^" * len(str(rootdir)) From hpk at codespeak.net Thu Mar 17 18:34:06 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 17 Mar 2005 18:34:06 +0100 (MET) Subject: [py-svn] r9866 - py/dist/py/bin Message-ID: <20050317173406.CBF0927BA2@code1.codespeak.net> Author: hpk Date: Thu Mar 17 18:34:06 2005 New Revision: 9866 Added: py/dist/py/bin/py.countloc (contents, props changed) Log: a very much handson script to count the non-empty lines of code, split into tests and non-tests Added: py/dist/py/bin/py.countloc ============================================================================== --- (empty file) +++ py/dist/py/bin/py.countloc Thu Mar 17 18:34:06 2005 @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# hands on script to compute the non-empty Lines of Code +# for tests and non-test code + +import py +curdir = py.path.local() + + +class Filecounter: + def __init__(self): + self.counts = {} + + def count(self, fn, empty=False): + if empty: + s = len(p.readlines()) + else: + s = 0 + for i in fn.readlines(): + if i.strip(): + s += 1 + self.counts[fn] = s + +if __name__ == '__main__': + testcounter = Filecounter() + counter = Filecounter() + args = py.std.sys.argv[1:] + if not args: + args = ['.'] + locations = [py.path.local(x) for x in args] + + for loc in locations: + for x in loc.visit('*.py', py.path.checker(dotfile=0)): + bn = x.basename + if bn.startswith('test_') or bn.endswith('_test.py'): + testcounter.count(x) + else: + counter.count(x) + numfiles = len(counter.counts) + numtestfiles = len(testcounter.counts) + numlines = sum(counter.counts.values()) + numtestlines = sum(testcounter.counts.values()) + + #for x,y in counter.counts.items(): + # print "%3d %30s" % (y,x) + + items = counter.counts.items() + items.sort(lambda x,y: cmp(x[1], y[1])) + for x, y in items: + print "%3d %30s" % (y,x) + + print "%30s %3d" %("number of testfiles", numtestfiles) + print "%30s %3d" %("number of testlines", numtestlines) + print "%30s %3d" %("number of files", numfiles) + print "%30s %3d" %("number of lines", numlines) From hpk at codespeak.net Sun Mar 20 16:41:21 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 20 Mar 2005 16:41:21 +0100 (MET) Subject: [py-svn] r9924 - in py/dist/py/xmlobj: . testing Message-ID: <20050320154121.AA98F27B56@code1.codespeak.net> Author: hpk Date: Sun Mar 20 16:41:21 2005 New Revision: 9924 Modified: py/dist/py/xmlobj/html.py py/dist/py/xmlobj/testing/test_html.py py/dist/py/xmlobj/visit.py Log: make things a bit more flexible, especially allow css "classes" to be None which means they don't have any. Modified: py/dist/py/xmlobj/html.py ============================================================================== --- py/dist/py/xmlobj/html.py (original) +++ py/dist/py/xmlobj/html.py Sun Mar 20 16:41:21 2005 @@ -2,16 +2,33 @@ """ -from py.xml import Namespace +from py.xml import Namespace, Tag +from py.__impl__.xmlobj.visit import SimpleUnicodeVisitor + +class HtmlVisitor(SimpleUnicodeVisitor): + def repr_attribute(self, attrs, name): + if name == 'class_': + value = getattr(attrs, name) + if value is None: + return + return super(HtmlVisitor, self).repr_attribute(attrs, name) + +class HtmlTag(Tag): + def unicode(self, indent=2): + l = [] + HtmlVisitor(l.append, indent).visit(self) + return u"".join(l) # exported plain html namespace class html(Namespace): + __tagclass__ = HtmlTag __stickyname__ = True __tagspec__ = dict([(x,1) for x in ( "h1,h2,h3,h5,h6,p,b,i,a,div,span,code," "html,head,title,style,table,tr,tt," "td,th,link,img,meta,body,pre,br,ul," - "ol,li,em,form,input,select,option" + "ol,li,em,form,input,select,option," + "button,script" ).split(',') if x]) class Style(object): Modified: py/dist/py/xmlobj/testing/test_html.py ============================================================================== --- py/dist/py/xmlobj/testing/test_html.py (original) +++ py/dist/py/xmlobj/testing/test_html.py Sun Mar 20 16:41:21 2005 @@ -13,6 +13,11 @@ u = unicode(my.body()) assert u == '' +def test_class_None(): + t = html.body(class_=None) + u = unicode(t) + assert u == '' + def test_alternating_style(): alternating = ( html.Style(background="white"), Modified: py/dist/py/xmlobj/visit.py ============================================================================== --- py/dist/py/xmlobj/visit.py (original) +++ py/dist/py/xmlobj/visit.py Sun Mar 20 16:41:21 2005 @@ -65,14 +65,19 @@ attrlist.sort() l = [] for name in attrlist: - if name[0] != '_': - value = getattr(tag.attr, name) - if name.endswith('_'): - name = name[:-1] - l.append(u' %s="%s"' % (name, escape(unicode(value)))) + res = self.repr_attribute(tag.attr, name) + if res is not None: + l.append(res) l.extend(self.getstyle(tag)) return u"".join(l) + def repr_attribute(self, attrs, name): + if name[:2] != '__': + value = getattr(attrs, name) + if name.endswith('_'): + name = name[:-1] + return u' %s="%s"' % (name, escape(unicode(value))) + def getstyle(self, tag): """ return attribute list suitable for styling. """ try: From hpk at codespeak.net Sun Mar 20 22:16:30 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 20 Mar 2005 22:16:30 +0100 (MET) Subject: [py-svn] r9954 - in py/dist/py/magic: . testing Message-ID: <20050320211630.D1E2427B4D@code1.codespeak.net> Author: hpk Date: Sun Mar 20 22:16:30 2005 New Revision: 9954 Modified: py/dist/py/magic/assertion.py py/dist/py/magic/testing/test_assertion.py Log: respect explicit messages for AssertionErrors Modified: py/dist/py/magic/assertion.py ============================================================================== --- py/dist/py/magic/assertion.py (original) +++ py/dist/py/magic/assertion.py Sun Mar 20 22:16:30 2005 @@ -7,20 +7,23 @@ class AssertionError(BuiltinAssertionError): def __init__(self, *args): BuiltinAssertionError.__init__(self, *args) - f = sys._getframe(1) - try: - source = py.code.Frame(f).statement - source = str(source).strip() - except py.error.ENOENT: - source = None - # this can also occur during reinterpretation, when the - # co_filename is set to "". - if source: - self.msg = exprinfo.interpret(source, f, should_fail=True) - if not self.args: - self.args = (self.msg,) - else: - self.msg = None + if args: + self.msg = args[0] + else: + f = sys._getframe(1) + try: + source = py.code.Frame(f).statement + source = str(source).strip() + except py.error.ENOENT: + source = None + # this can also occur during reinterpretation, when the + # co_filename is set to "". + if source: + self.msg = exprinfo.interpret(source, f, should_fail=True) + if not self.args: + self.args = (self.msg,) + else: + self.msg = None def invoke(): py.magic.patch(__builtin__, 'AssertionError', AssertionError) Modified: py/dist/py/magic/testing/test_assertion.py ============================================================================== --- py/dist/py/magic/testing/test_assertion.py (original) +++ py/dist/py/magic/testing/test_assertion.py Sun Mar 20 22:16:30 2005 @@ -16,6 +16,12 @@ s = str(e) assert s.startswith('assert 2 == 3\n') +def test_assert_with_explicit_message(): + try: + assert f() == 3, "hello" + except AssertionError, e: + assert e.msg == 'hello' + def test_assert_within_finally(): class A: def f(): From hpk at codespeak.net Sun Mar 20 23:19:04 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 20 Mar 2005 23:19:04 +0100 (MET) Subject: [py-svn] r9958 - py/dist/py/path/svn Message-ID: <20050320221904.C3F9827B5B@code1.codespeak.net> Author: hpk Date: Sun Mar 20 23:19:04 2005 New Revision: 9958 Modified: py/dist/py/path/svn/wccommand.py Log: fix Modified: py/dist/py/path/svn/wccommand.py ============================================================================== --- py/dist/py/path/svn/wccommand.py (original) +++ py/dist/py/path/svn/wccommand.py Sun Mar 20 23:19:04 2005 @@ -46,7 +46,7 @@ def svnurl(self): """ return current SvnPath for this WC-item. """ info = self.info() - return path.svnurl(info.url) + return py.path.svnurl(info.url) url = property(_geturl, None, None, "url of this WC item") From hpk at codespeak.net Mon Mar 21 00:18:34 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 21 Mar 2005 00:18:34 +0100 (MET) Subject: [py-svn] r9968 - py/dist/py/documentation Message-ID: <20050320231834.81EE827B56@code1.codespeak.net> Author: hpk Date: Mon Mar 21 00:18:34 2005 New Revision: 9968 Modified: py/dist/py/documentation/execnet.txt Log: fix execnet example Modified: py/dist/py/documentation/execnet.txt ============================================================================== --- py/dist/py/documentation/execnet.txt (original) +++ py/dist/py/documentation/execnet.txt Mon Mar 21 00:18:34 2005 @@ -144,8 +144,8 @@ f.close() """ # open a gateway to a fresh child process - contentgateway = py.execnet.SSHGateway('codespeak.net', identity) - channel = contentgateway.remote_exec_async(contentserverbootstrap) + contentgateway = py.execnet.SshGateway('codespeak.net') + channel = contentgateway.remote_exec(contentserverbootstrap) for fn in somefilelist: channel.send(fn) From arigo at codespeak.net Mon Mar 21 20:47:28 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 21 Mar 2005 20:47:28 +0100 (MET) Subject: [py-svn] r10013 - py/dist/py/test Message-ID: <20050321194728.5019727B4B@code1.codespeak.net> Author: arigo Date: Mon Mar 21 20:47:28 2005 New Revision: 10013 Modified: py/dist/py/test/config.py Log: Fix the 'usage:' line of py.test --help. Modified: py/dist/py/test/config.py ============================================================================== --- py/dist/py/test/config.py (original) +++ py/dist/py/test/config.py Mon Mar 21 20:47:28 2005 @@ -71,6 +71,7 @@ # first a small fight with optparse to merge the # pytest.py file options correctly parser = optparse.OptionParser() + parser.set_usage("%prog [test files/dirs] [options]") for config in self.configpaths: meth = config.join('options') if meth.check():