[py-svn] r56913 - in py/branch/event/py: . test2 test2/testing

hpk at codespeak.net hpk at codespeak.net
Sat Aug 2 10:52:32 CEST 2008


Author: hpk
Date: Sat Aug  2 10:52:28 2008
New Revision: 56913

Added:
   py/branch/event/py/test2/pycollect.py
      - copied, changed from r56912, py/branch/event/py/test2/collect.py
Removed:
   py/branch/event/py/test2/doctest.py
Modified:
   py/branch/event/py/__init__.py
   py/branch/event/py/test2/collect.py
   py/branch/event/py/test2/item.py
   py/branch/event/py/test2/testing/test_collect.py
   py/branch/event/py/test2/testing/test_doctest.py
Log:
split python and non-python code realted collection nodes into two files, 
merge small item and doctest files, so that now there is collect.py and pycollect.py


Modified: py/branch/event/py/__init__.py
==============================================================================
--- py/branch/event/py/__init__.py	(original)
+++ py/branch/event/py/__init__.py	Sat Aug  2 10:52:28 2008
@@ -50,23 +50,23 @@
 
     # for customization of collecting/running tests
     'test.collect.Collector' : ('./test/collect.py', 'Collector'),
-    'test2.collect.Collector' : ('./test2/collect.py', 'Collector'),
     'test.collect.Directory' : ('./test/collect.py', 'Directory'),
-    'test2.collect.Directory' : ('./test2/collect.py', 'Directory'),
     'test.collect.Module'    : ('./test/collect.py', 'Module'),
-    'test2.collect.Module'    : ('./test2/collect.py', 'Module'),
     'test.collect.DoctestFile' : ('./test/collect.py', 'DoctestFile'),
-    'test2.collect.DoctestFile' : ('./test2/collect.py', 'DoctestFile'),
     'test.collect.Class'     : ('./test/collect.py', 'Class'),
-    'test2.collect.Class'     : ('./test2/collect.py', 'Class'),
     'test.collect.Instance'  : ('./test/collect.py', 'Instance'),
-    'test2.collect.Instance'  : ('./test2/collect.py', 'Instance'),
     'test.collect.Generator' : ('./test/collect.py', 'Generator'),
-    'test2.collect.Generator' : ('./test2/collect.py', 'Generator'),
     'test.collect.Item'      : ('./test/item.py', 'Item'),
-    'test2.collect.Item'      : ('./test2/item.py', 'Item'),
     'test.collect.Function'  : ('./test/item.py', 'Function'),
-    'test2.collect.Function'  : ('./test2/item.py', 'Function'),
+    'test2.collect.Collector' : ('./test2/collect.py', 'Collector'),
+    'test2.collect.Directory' : ('./test2/collect.py', 'Directory'),
+    'test2.collect.Module'    : ('./test2/pycollect.py', 'Module'),
+    'test2.collect.DoctestFile' : ('./test2/pycollect.py', 'DoctestFile'),
+    'test2.collect.Class'     : ('./test2/pycollect.py', 'Class'),
+    'test2.collect.Instance'  : ('./test2/pycollect.py', 'Instance'),
+    'test2.collect.Generator' : ('./test2/pycollect.py', 'Generator'),
+    'test2.collect.Item'      : ('./test2/collect.py', 'Item'),
+    'test2.collect.Function'  : ('./test2/pycollect.py', 'Function'),
 
     # thread related API (still in early design phase)
     '_thread.WorkerPool'      : ('./thread/pool.py', 'WorkerPool'),

Modified: py/branch/event/py/test2/collect.py
==============================================================================
--- py/branch/event/py/test2/collect.py	(original)
+++ py/branch/event/py/test2/collect.py	Sat Aug  2 10:52:28 2008
@@ -23,9 +23,7 @@
             ... 
 
 """ 
-from __future__ import generators 
 import py
-from py.__.test2 import pypresent
 
 def configproperty(name):
     def fget(self):
@@ -279,249 +277,24 @@
             name2items[name] = res 
         return res
 
-class PyobjMixin(object):
-    def obj(): 
-        def fget(self):
-            try: 
-                return self._obj   
-            except AttributeError: 
-                self._obj = obj = self._getobj() 
-                return obj 
-        def fset(self, value): 
-            self._obj = value 
-        return property(fget, fset, None, "underlying python object") 
-    obj = obj()
-
-    def _getobj(self):
-        return getattr(self.parent.obj, self.name)
-
-    def repr_path(self):
-        fspath = pypresent.getrelpath(self._config.topdir, self.fspath)
-        modpath = pypresent.getmodpath(self)
-        return (fspath, modpath)
-
-
-class PyCollectorMixin(PyobjMixin, Collector): 
-    def funcnamefilter(self, name): 
-        return name.startswith('test') 
-    def classnamefilter(self, name): 
-        return name.startswith('Test')
-
-    def _buildname2items(self): 
-        # NB. we avoid random getattrs and peek in the __dict__ instead
-        d = {}
-        dicts = [getattr(self.obj, '__dict__', {})]
-        for basecls in py.std.inspect.getmro(self.obj.__class__):
-            dicts.append(basecls.__dict__)
-        seen = {}
-        for dic in dicts:
-            for name, obj in dic.items():
-                if name in seen:
-                    continue
-                seen[name] = True
-                res = self.makeitem(name, obj)
-                if res is not None:
-                    d[name] = res 
-        return d
-
-    def makeitem(self, name, obj, usefilters=True):
-        if (not usefilters or self.classnamefilter(name)) and \
-            py.std.inspect.isclass(obj):
-            return self.Class(name, parent=self)
-        elif (not usefilters or self.funcnamefilter(name)) and callable(obj): 
-            if obj.func_code.co_flags & 32: # generator function 
-                return self.Generator(name, parent=self)
-            else: 
-                return self.Function(name, parent=self)
-
-    def _prepare(self): 
-        if not hasattr(self, '_name2items'): 
-            ex = getattr(self, '_name2items_exception', None)
-            if ex is not None: 
-                raise ex[0], ex[1], ex[2]
-            try: 
-                self._name2items = self._buildname2items()
-            except (SystemExit, KeyboardInterrupt): 
-                raise 
-            except:
-                self._name2items_exception = py.std.sys.exc_info()
-                raise
-
-    def listdir(self): 
-        self._prepare()
-        itemlist = self._name2items.values()
-        itemlist.sort()
-        return [x.name for x in itemlist]
-
-    def join(self, name): 
-        self._prepare()
-        return self._name2items.get(name, None) 
-
-class Module(FSCollector, PyCollectorMixin):
-    _stickyfailure = None
-
+from py.__.test2.runner import basic_run_report, forked_run_report
+class Item(Node): 
+    """ a basic test item. """
     def repr_path(self):
-        return (self.fspath, None)
-
-    def listdir(self):
-        if getattr(self.obj, 'disabled', 0):
-            return []
-        return super(Module, self).listdir()
-
-    def join(self, name):
-        res = super(Module, self).join(name)
-        if res is None:
-            attr = getattr(self.obj, name, None)
-            if attr is not None:
-                res = self.makeitem(name, attr, usefilters=False)
-        return res
+        """ return (filepath, testpath) tuple with
+            filepath: a fspath representation (None if not applicable)
+            testpath: a path representation of the test path. 
     
-    def _getobj(self):
-        failure = self._stickyfailure
-        if failure is not None: 
-            raise failure[0], failure[1], failure[2]
-        try: 
-            self._obj = obj = self.fspath.pyimport() 
-        except KeyboardInterrupt: 
-            raise
-        except:
-            self._stickyfailure = py.std.sys.exc_info()
-            raise 
-        return self._obj 
-
-    def setup(self): 
-        if hasattr(self.obj, 'setup_module'): 
-            self.obj.setup_module(self.obj) 
-
-    def teardown(self): 
-        if hasattr(self.obj, 'teardown_module'): 
-            self.obj.teardown_module(self.obj) 
-
-
-class Class(PyCollectorMixin, Collector): 
-
-    def listdir(self): 
-        if getattr(self.obj, 'disabled', 0):
-            return []
-        return ["()"]
-
-    def join(self, name):
-        assert name == '()'
-        return self.Instance(name, self)
-
-    def setup(self): 
-        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 = 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) 
-
-    def _getsortvalue(self):
-        # try to locate the class in the source - not nice, but probably
-        # the most useful "solution" that we have
-        try:
-            file = (py.std.inspect.getsourcefile(self.obj) or
-                    py.std.inspect.getfile(self.obj))
-            if not file:
-                raise IOError
-            lines, lineno = py.std.inspect.findsource(self.obj)
-            return py.path.local(file), lineno
-        except IOError:
-            pass
-
-class Instance(PyCollectorMixin, Collector): 
-    def _getobj(self): 
-        return self.parent.obj()  
-    def Function(self): 
-        return getattr(self.obj, 'Function', 
-                       Collector.Function.__get__(self)) # XXX for python 2.2
-    def _keywords(self):
-        return []
-    Function = property(Function)
-
-
-class FunctionMixin(PyobjMixin):
-    """ mixin for the code common to Function and Generator.
-    """
-    _sortvalue = None
-    def _getsortvalue(self):  
-        if self._sortvalue is None:
-            code = py.code.Code(self.obj) 
-            self._sortvalue = code.path, code.firstlineno 
-        return self._sortvalue 
-
-    def setup(self): 
-        """ perform setup for this test function. """
-        if hasattr(self.obj, 'im_self'):
-            name = 'setup_method' 
-        else: 
-            name = 'setup_function' 
-        obj = self.parent.obj 
-        setup_func_or_method = getattr(obj, name, None)
-        if setup_func_or_method is not None: 
-            return setup_func_or_method(self.obj) 
-
-    def teardown(self): 
-        """ perform teardown for this test function. """
-        if hasattr(self.obj, 'im_self'):
-            name = 'teardown_method' 
-        else: 
-            name = 'teardown_function' 
-        obj = self.parent.obj 
-        teardown_func_or_meth = getattr(obj, name, None)
-        if teardown_func_or_meth is not None: 
-            return teardown_func_or_meth(self.obj) 
-
-    def prunetraceback(self, traceback):
-        if not self._config.option.fulltrace: 
-            code = py.code.Code(self.obj) 
-            path, firstlineno = code.path, code.firstlineno 
-            ntraceback = traceback.cut(path=path, firstlineno=firstlineno)
-            if ntraceback == traceback:
-                ntraceback = ntraceback.cut(path=path)
-            traceback = ntraceback.filter()
-        return traceback 
-
-class Generator(FunctionMixin, PyCollectorMixin, Collector): 
-    def listdir(self): 
-        self._prepare()
-        itemlist = self._name2items
-        return [itemlist["[%d]" % num].name for num in xrange(len(itemlist))]
-    
-    def _buildname2items(self):
-        d = {} 
-        # XXX test generators are collectors yet participate in 
-        # the test-item setup and teardown protocol 
-        # if not for this we could probably avoid global setupstate
-        self._setupstate.prepare(self) 
-        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,))
-            name = "[%d]" % i  
-            d[name] = self.Function(name, self, args, callobj=call)
-        return d
-        
-    def getcallargs(self, obj):
-        if isinstance(obj, (tuple, list)):
-            call, args = obj[0], obj[1:]
-        else:
-            call, args = obj, ()
-        return call, args 
-
-class DoctestFile(PyCollectorMixin, FSCollector): 
-    def listdir(self):
-        return [self.fspath.basename]
+            this is used by reporters. 
+        """
+        xxx 
 
-    def join(self, name):
-        from py.__.test2.doctest import DoctestText
-        if name == self.fspath.basename: 
-            item = DoctestText(self.fspath.basename, parent=self)
-            item._content = self.fspath.read()
-            return item
+    def repr_run(self, excinfo):
+        """ return string failure represenation for this item. 
+        """
+        xxx 
 
+    def _getrunner(self):
+        if self._config.option.boxed:
+            return forked_run_report
+        return basic_run_report

Deleted: /py/branch/event/py/test2/doctest.py
==============================================================================
--- /py/branch/event/py/test2/doctest.py	Sat Aug  2 10:52:28 2008
+++ (empty file)
@@ -1,33 +0,0 @@
-import py
-
-class DoctestText(py.test2.collect.Item):
-
-    def _setcontent(self, content):
-        self._content = content 
-
-    #def buildname2items(self):
-    #    parser = py.compat.doctest.DoctestParser()
-    #    l = parser.get_examples(self._content)
-    #    d = {}
-    #    globs = {}
-    #    locs
-    #    for i, example in py.builtin.enumerate(l):
-    #        ex = ExampleItem(example)
-    #        d[str(i)] = ex
-
-    def run(self):
-        mod = py.std.types.ModuleType(self.name) 
-        #for line in s.split('\n'): 
-        #    if line.startswith(prefix): 
-        #        exec py.code.Source(line[len(prefix):]).compile() in mod.__dict__ 
-        #        line = ""
-        #    else: 
-        #        l.append(line)
-        self.execute(mod, self._content) 
-       
-    def execute(self, mod, docstring):
-        mod.__doc__ = docstring 
-        failed, tot = py.compat.doctest.testmod(mod, verbose=1)
-        if failed: 
-            py.test2.fail("doctest %s: %s failed out of %s" %(
-                         self.fspath, failed, tot))

Modified: py/branch/event/py/test2/item.py
==============================================================================
--- py/branch/event/py/test2/item.py	(original)
+++ py/branch/event/py/test2/item.py	Sat Aug  2 10:52:28 2008
@@ -1,45 +1,4 @@
 import py
 from py.__.test2.collect import FunctionMixin, Node
-from py.__.test2.runner import basic_run_report, forked_run_report
 from py.__.test2 import pypresent
 
-_dummy = object()
-
-class Item(Node): 
-    def repr_path(self):
-        """ return (filepath, testpath) tuple with
-            filepath: a fspath representation (None if not applicable)
-            testpath: a path representation of the test path. 
-    
-            this is used by reporters. 
-        """
-        xxx 
-
-    def repr_run(self, excinfo):
-        """ return string failure represenation for this item. 
-        """
-        xxx 
-
-    def _getrunner(self):
-        if self._config.option.boxed:
-            return forked_run_report
-        return basic_run_report
-
-class Function(FunctionMixin, Item): 
-    """ a Function Item is responsible for setting up  
-        and executing a Python callable test object.
-    """
-    def __init__(self, name, parent, args=(), callobj=_dummy):
-        super(Function, self).__init__(name, parent) 
-        self._args = args
-        if callobj is not _dummy: 
-            self._obj = callobj 
-
-    def execute(self):
-        """ execute the given test function. """
-        self.obj(*self._args)
-
-    def repr_run(self, runinfo):
-        """ return a textual representation of run info. """ 
-        return pypresent.python_repr_run(runinfo)
-

Copied: py/branch/event/py/test2/pycollect.py (from r56912, py/branch/event/py/test2/collect.py)
==============================================================================
--- py/branch/event/py/test2/collect.py	(original)
+++ py/branch/event/py/test2/pycollect.py	Sat Aug  2 10:52:28 2008
@@ -1,283 +1,9 @@
 """
-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 session 
-is smalll.  Collectors usually return a list of child 
-collectors/items whereas items usually return None 
-indicating a successful test run.  
-
-The is a schematic example of a tree of collectors and test items:: 
-
-    Directory
-        Module 
-            Class 
-                Instance   
-                    Function  
-                    Generator 
-                        ... 
-            Function 
-            Generator 
-                Function 
-        Directory       
-            ... 
-
+Python related Collect nodes. 
 """ 
-from __future__ import generators 
 import py
-from py.__.test2 import pypresent
-
-def configproperty(name):
-    def fget(self):
-        #print "retrieving %r property from %s" %(name, self.fspath)
-        return self._config.getvalue(name, self.fspath) 
-    return property(fget)
-
-class SetupState(object):
-    """ shared state for setting up/tearing down tests. """
-    def __init__(self):
-        self.stack = []
-
-    def teardown_all(self): 
-        while self.stack: 
-            col = self.stack.pop() 
-            col.teardown() 
-
-    def teardown_exact(self, item):
-        if self.stack[-1] == item:
-            col = self.stack.pop()
-            col.teardown()
-     
-    def prepare(self, colitem): 
-        """ setup objects along the collector chain to the test-method
-            Teardown any unneccessary previously setup objects."""
-
-        needed_collectors = colitem.listchain() 
-        while self.stack: 
-            if self.stack == needed_collectors[:len(self.stack)]: 
-                break 
-            col = self.stack.pop() 
-            col.teardown()
-        for col in needed_collectors[len(self.stack):]: 
-            #print "setting up", col
-            col.setup() 
-            self.stack.append(col) 
-
-class Node(object): 
-    """ base class for Nodes in the collection tree.  
-        Nodes with Children are "Collectors" and 
-        leaves are runnable Test Items.  
-    """
-    _setupstate = SetupState() 
-    def __init__(self, name, parent=None, config=None):
-        self.name = name 
-        self.parent = parent
-        if config is None:
-            config = getattr(parent, '_config')
-        self._config = config 
-        self.fspath = getattr(parent, 'fspath', None) 
-
-    def __getstate__(self):
-        config = self._config
-        return (config, config.get_collector_trail(self))
-    def __setstate__(self, (config, trail)):
-        newnode = config._getcollector(trail)
-        self.__dict__.update(newnode.__dict__)
-
-    def __repr__(self): 
-        return "<%s %r>" %(self.__class__.__name__, self.name) 
-
-    # methods for ordering nodes
-
-    def __eq__(self, other): 
-        if not isinstance(other, Node):
-            return False 
-        return self.name == other.name and self.parent == other.parent 
-
-    def __ne__(self, other):
-        return not self == other
-    
-    def __hash__(self):
-        return hash((self.name, self.parent))
-
-    def __cmp__(self, other): 
-        if not isinstance(other, Node):
-            return -1
-        s1 = self._getsortvalue()
-        s2 = other._getsortvalue()
-        return cmp(s1, s2) 
- 
-    def setup(self): 
-        pass
-
-    def teardown(self): 
-        pass
-
-    def listchain(self): 
-        """ return list of all parent collectors up to self. """ 
-        l = [self]
-        while 1: 
-            x = l[-1]
-            if x.parent is not None: 
-                l.append(x.parent) 
-            else: 
-                l.reverse() 
-                return l 
-
-    def listnames(self): 
-        return [x.name for x in self.listchain()]
-
-    def _getitembynames(self, namelist):
-        cur = self
-        for name in namelist:
-            if name:
-                next = cur.join(name)
-                if next is None: 
-                    existingnames = cur.listdir()
-                    msg = ("Collector %r does not have name %r "
-                           "existing names are: %s" %
-                           (cur, name, existingnames))
-                    raise AssertionError(msg) 
-                cur = next
-        return cur
-
-    def _keywords(self):
-        return [self.name]
-
-    def _skipbykeyword(self, keywordexpr): 
-        """ return True if they given keyword expression means to 
-            skip this collector/item. 
-        """
-        if not keywordexpr:
-            return
-        chain = self.listchain()
-        for key in filter(None, keywordexpr.split()):
-            eor = key[:1] == '-'
-            if eor:
-                key = key[1:]
-            if not (eor ^ self._matchonekeyword(key, chain)):
-                return True
-
-    def _matchonekeyword(self, key, chain):
-        elems = key.split(".")
-        # XXX O(n^2), anyone cares?
-        chain = [item._keywords() for item in chain if item._keywords()]
-        for start, _ in enumerate(chain):
-            if start + len(elems) > len(chain):
-                return False
-            for num, elem in enumerate(elems):
-                for keyword in chain[num + start]:
-                    ok = False
-                    if elem in keyword:
-                        ok = True
-                        break
-                if not ok:
-                    break
-            if num == len(elems) - 1 and ok:
-                return True
-        return False
-
-    def _getsortvalue(self): 
-        return self.name 
-
-    def _get_collector_trail(self):
-        """ Shortcut
-        """
-        return self._config.get_collector_trail(self)
-
-    def prunetraceback(self, traceback):
-        return traceback 
-
-class Collector(Node):
-    """ 
-        Collector instances generate children through 
-        their listdir() and join() methods and thus 
-        form a tree.  attributes::
-
-        parent: attribute pointing to the parent collector
-                (or None if this is the root collector)
-        name:   basename of this collector object
-    """
-    Module = configproperty('Module')
-    DoctestFile = configproperty('DoctestFile')
-    Directory = configproperty('Directory')
-    Class = configproperty('Class')
-    Instance = configproperty('Instance')
-    Function = configproperty('Function')
-    Generator = configproperty('Generator')
-
-    def run(self):
-        """ deprecated: use listdir(). """
-        py.std.warnings.warn("deprecated: use listdir()", category=DeprecationWarning)
-        return self.listdir()
-
-    def multijoin(self, namelist): 
-        """ return a list of colitems for the given namelist. """ 
-        return [self.join(name) for name in namelist]
-
-    def listdir(self):
-        """ returns a list of names available from this collector.
-            You can return an empty list.  Callers of this method
-            must take care to catch exceptions properly.  
-        """
-        raise NotImplementedError("abstract")
-
-    def join(self, name):
-        """  return a child collector or item for the given name.  
-             If the return value is None there is no such child. 
-        """
-        raise NotImplementedError("abstract")
-
-class FSCollector(Collector): 
-    def __init__(self, fspath, parent=None, config=None): 
-        fspath = py.path.local(fspath) 
-        super(FSCollector, self).__init__(fspath.basename, parent, config=config) 
-        self.fspath = fspath 
-
-class Directory(FSCollector): 
-    def filefilter(self, path): 
-        if path.check(file=1):
-            b = path.purebasename 
-            ext = path.ext
-            return (b.startswith('test_') or 
-                    b.endswith('_test')) and ext in ('.txt', '.py')
-    
-    def recfilter(self, path): 
-        if path.check(dir=1, dotfile=0):
-            return path.basename not in ('CVS', '_darcs', '{arch}')
-
-    def repr_path(self):
-        return (self.fspath, None)
-
-    def listdir(self):
-        files = []
-        dirs = []
-        for p in self.fspath.listdir():
-            if self.filefilter(p):
-                files.append(p.basename)
-            elif self.recfilter(p):
-                dirs.append(p.basename) 
-        files.sort()
-        dirs.sort()
-        return files + dirs
-
-    def join(self, name):
-        name2items = self.__dict__.setdefault('_name2items', {})
-        try:
-            res = name2items[name]
-        except KeyError:
-            p = self.fspath.join(name)
-            res = None
-            if p.check(file=1): 
-                if p.ext == '.py':
-                    res = self.Module(p, parent=self) 
-                elif p.ext == '.txt':
-                    res = self.DoctestFile(p, parent=self)
-            elif p.check(dir=1): 
-                Directory = py.test2.config.getvalue('Directory', p) 
-                res = Directory(p, parent=self) 
-            name2items[name] = res 
-        return res
+from py.__.test2.collect import Collector, FSCollector, Item
+from py.__.test2 import pypresent 
 
 class PyobjMixin(object):
     def obj(): 
@@ -300,7 +26,6 @@
         modpath = pypresent.getmodpath(self)
         return (fspath, modpath)
 
-
 class PyCollectorMixin(PyobjMixin, Collector): 
     def funcnamefilter(self, name): 
         return name.startswith('test') 
@@ -514,14 +239,63 @@
             call, args = obj, ()
         return call, args 
 
+_dummy = object()
+class Function(FunctionMixin, Item): 
+    """ a Function Item is responsible for setting up  
+        and executing a Python callable test object.
+    """
+    def __init__(self, name, parent, args=(), callobj=_dummy):
+        super(Function, self).__init__(name, parent) 
+        self._args = args
+        if callobj is not _dummy: 
+            self._obj = callobj 
+
+    def execute(self):
+        """ execute the given test function. """
+        self.obj(*self._args)
+
+    def repr_run(self, runinfo):
+        """ return a textual representation of run info. """ 
+        return pypresent.python_repr_run(runinfo)
+
 class DoctestFile(PyCollectorMixin, FSCollector): 
     def listdir(self):
         return [self.fspath.basename]
 
     def join(self, name):
-        from py.__.test2.doctest import DoctestText
         if name == self.fspath.basename: 
             item = DoctestText(self.fspath.basename, parent=self)
             item._content = self.fspath.read()
             return item
 
+class DoctestText(Item):
+    def _setcontent(self, content):
+        self._content = content 
+
+    #def buildname2items(self):
+    #    parser = py.compat.doctest.DoctestParser()
+    #    l = parser.get_examples(self._content)
+    #    d = {}
+    #    globs = {}
+    #    locs
+    #    for i, example in py.builtin.enumerate(l):
+    #        ex = ExampleItem(example)
+    #        d[str(i)] = ex
+
+    def run(self):
+        mod = py.std.types.ModuleType(self.name) 
+        #for line in s.split('\n'): 
+        #    if line.startswith(prefix): 
+        #        exec py.code.Source(line[len(prefix):]).compile() in mod.__dict__ 
+        #        line = ""
+        #    else: 
+        #        l.append(line)
+        self.execute(mod, self._content) 
+       
+    def execute(self, mod, docstring):
+        mod.__doc__ = docstring 
+        failed, tot = py.compat.doctest.testmod(mod, verbose=1)
+        if failed: 
+            py.test2.fail("doctest %s: %s failed out of %s" %(
+                         self.fspath, failed, tot))
+

Modified: py/branch/event/py/test2/testing/test_collect.py
==============================================================================
--- py/branch/event/py/test2/testing/test_collect.py	(original)
+++ py/branch/event/py/test2/testing/test_collect.py	Sat Aug  2 10:52:28 2008
@@ -1,10 +1,10 @@
 from __future__ import generators
 import py
 from py.__.test2 import repevent, outcome 
-from py.__.test2.doctest import DoctestText
 import setupdata, suptest
 from py.__.test2.conftesthandle import Conftest
 from py.__.test2.collect import SetupState
+from py.__.test2.pycollect import DoctestText
 
 class DummyConfig:
     def __init__(self):

Modified: py/branch/event/py/test2/testing/test_doctest.py
==============================================================================
--- py/branch/event/py/test2/testing/test_doctest.py	(original)
+++ py/branch/event/py/test2/testing/test_doctest.py	Sat Aug  2 10:52:28 2008
@@ -1,6 +1,6 @@
 
 import py
-from py.__.test2.doctest import DoctestText
+from py.__.test2.pycollect import DoctestText
 from py.__.test2.outcome import Skipped, Failed, Passed, Outcome
 
 def test_simple_docteststring():



More information about the pytest-commit mailing list