def visit_ModuleNode(self, node):
if node.is_pxd:
return node
-
self.scope_type = 'module'
self.scope_node = node
if not self.current_directives['autotestdict']:
return node
+ self.all_docstrings = self.current_directives['autotestdict.all']
+ self.cdef_docstrings = self.all_docstrings or self.current_directives['autotestdict.cdef']
assert isinstance(node.body, StatListNode)
def visit_FuncDefNode(self, node):
if not node.doc:
return node
- if isinstance(node, CFuncDefNode) and not node.py_func:
- # skip non-cpdef cdef functions
+ if not self.cdef_docstrings:
+ if isinstance(node, CFuncDefNode) and not node.py_func:
+ return node
+ if not self.all_docstrings and '>>>' not in node.doc:
return node
pos = self.testspos
path = node.entry.name
elif self.scope_type in ('pyclass', 'cclass'):
if isinstance(node, CFuncDefNode):
- name = node.py_func.name
+ if node.py_func is not None:
+ name = node.py_func.name
+ else:
+ name = node.entry.name
else:
name = node.name
if self.scope_type == 'cclass' and name in self.blacklist:
'infer_types': None,
'infer_types.verbose': False,
'autotestdict': True,
+ 'autotestdict.cdef': False,
+ 'autotestdict.all': False,
'language_level': 2,
'warn': None,
'final' : ('cclass',), # add 'method' in the future
'internal' : ('cclass',),
'autotestdict' : ('module',),
+ 'autotestdict.all' : ('module',),
+ 'autotestdict.cdef' : ('module',),
'test_assert_path_exists' : ('function',),
'test_fail_if_path_exists' : ('function',),
}
# Directive defaults to True
"""
-Tests doctesthack compiler directive.
+Tests autotestdict compiler directive.
-The doctests are actually run as part of this test;
-which makes the test flow a bit untraditional. Both
-module test and individual tests are run; finally,
+Both module test and individual tests are run; finally,
all_tests_run() is executed which does final validation.
>>> items = list(__test__.items())
>>> items.sort()
>>> for key, value in items:
... print('%s ; %s' % (key, value))
-MyCdefClass.cpdef_method (line 79) ; >>> add_log("cpdef class method")
-MyCdefClass.method (line 76) ; >>> add_log("cdef class method")
-MyClass.method (line 65) ; >>> add_log("class method")
-doc_without_test (line 47) ; Some docs
-mycpdeffunc (line 53) ; >>> add_log("cpdef")
-myfunc (line 44) ; >>> add_log("def")
+MyCdefClass.cpdef_method (line 76) ; >>> add_log("cpdef class method")
+MyCdefClass.method (line 73) ; >>> add_log("cdef class method")
+MyClass.method (line 62) ; >>> add_log("class method")
+mycpdeffunc (line 49) ; >>> add_log("cpdef")
+myfunc (line 40) ; >>> add_log("def")
"""
cdef cdeffunc():
"""
- Please don't include me!
-
>>> True
False
"""
+cdeffunc() # make sure it's being used
def all_tests_run():
log.sort()
- assert log == [u'cdef class', u'cdef class method', u'class method', u'cpdef', u'cpdef class method', u'def'], log
+ assert log == [u'cdef class', u'cdef class method', u'class', u'class method', u'cpdef', u'cpdef class method', u'def'], log
def add_log(s):
log.append(unicode(s))
- if len(log) == len(__test__):
+ if len(log) == len(__test__) + 2:
# Final per-function doctest executed
all_tests_run()
"""
Needs no hack
+ >>> add_log("class")
>>> True
True
"""
cpdef cpdef_method(self):
""">>> add_log("cpdef class method")"""
+ cdef cdef_method(self):
+ """>>> add_log("cdef class method")"""
+
def __cinit__(self):
"""
Should not be included, as it can't be looked up with getattr
>>> True
False
"""
-
-cdeffunc()
--- /dev/null
+# cython: autotestdict.all=True
+
+"""
+Tests autotestdict compiler directive.
+
+Both module test and individual tests are run; finally,
+all_tests_run() is executed which does final validation.
+
+>>> items = list(__test__.items())
+>>> items.sort()
+>>> for key, value in items:
+... print('%s ; %s' % (key, value))
+MyCdefClass.cdef_method (line 79) ; >>> add_log("cdef class method")
+MyCdefClass.cpdef_method (line 76) ; >>> add_log("cpdef class method")
+MyCdefClass.method (line 73) ; >>> add_log("cdef class method")
+MyClass.method (line 62) ; >>> add_log("class method")
+cdeffunc (line 26) ; >>> add_log("cdef")
+doc_without_test (line 43) ; Some docs
+mycpdeffunc (line 49) ; >>> add_log("cpdef")
+myfunc (line 40) ; >>> add_log("def")
+
+"""
+
+log = []
+
+cdef cdeffunc():
+ """>>> add_log("cdef")"""
+cdeffunc() # make sure it's being used
+
+def all_tests_run():
+ log.sort()
+ assert log == [u'cdef', u'cdef class', u'cdef class method', u'class', u'class method', u'cpdef', u'cpdef class method', u'def'], log
+
+def add_log(s):
+ log.append(unicode(s))
+ if len(log) == len(__test__):
+ # Final per-function doctest executed
+ all_tests_run()
+
+def myfunc():
+ """>>> add_log("def")"""
+
+def doc_without_test():
+ """Some docs"""
+
+def nodocstring():
+ pass
+
+cpdef mycpdeffunc():
+ """>>> add_log("cpdef")"""
+
+
+class MyClass:
+ """
+ Needs no hack
+
+ >>> add_log("class")
+ >>> True
+ True
+ """
+
+ def method(self):
+ """>>> add_log("class method")"""
+
+cdef class MyCdefClass:
+ """
+ Needs no hack
+
+ >>> add_log("cdef class")
+ >>> True
+ True
+ """
+ def method(self):
+ """>>> add_log("cdef class method")"""
+
+ cpdef cpdef_method(self):
+ """>>> add_log("cpdef class method")"""
+
+ cdef cdef_method(self):
+ """>>> add_log("cdef class method")"""
+
+ def __cinit__(self):
+ """
+ Should not be included, as it can't be looked up with getattr
+
+ >>> True
+ False
+ """
+
+ def __dealloc__(self):
+ """
+ Should not be included, as it can't be looked up with getattr
+
+ >>> True
+ False
+ """
+
+ def __richcmp__(self, other, int op):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 2
+
+ >>> True
+ False
+ """
+
+ def __nonzero__(self):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 3.1
+
+ >>> True
+ False
+ """
+
+ def __len__(self):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 3.1
+
+ >>> True
+ False
+ """
+
+ def __contains__(self, value):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 3.1
+
+ >>> True
+ False
+ """
+
+cdef class MyOtherCdefClass:
+ """
+ Needs no hack
+
+ >>> True
+ True
+ """
+
+ def __bool__(self):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 2
+
+ >>> True
+ False
+ """
--- /dev/null
+# cython: autotestdict.cdef=True
+
+"""
+Tests autotestdict compiler directive.
+
+Both module test and individual tests are run; finally,
+all_tests_run() is executed which does final validation.
+
+>>> items = list(__test__.items())
+>>> items.sort()
+>>> for key, value in items:
+... print('%s ; %s' % (key, value))
+MyCdefClass.cdef_method (line 78) ; >>> add_log("cdef class method")
+MyCdefClass.cpdef_method (line 75) ; >>> add_log("cpdef class method")
+MyCdefClass.method (line 72) ; >>> add_log("cdef class method")
+MyClass.method (line 61) ; >>> add_log("class method")
+cdeffunc (line 25) ; >>> add_log("cdef")
+mycpdeffunc (line 48) ; >>> add_log("cpdef")
+myfunc (line 39) ; >>> add_log("def")
+
+"""
+
+log = []
+
+cdef cdeffunc():
+ """>>> add_log("cdef")"""
+cdeffunc() # make sure it's being used
+
+def all_tests_run():
+ log.sort()
+ assert log == [u'cdef', u'cdef class', u'cdef class method', u'class', u'class method', u'cpdef', u'cpdef class method', u'def'], log
+
+def add_log(s):
+ log.append(unicode(s))
+ if len(log) == len(__test__) + 1:
+ # Final per-function doctest executed
+ all_tests_run()
+
+def myfunc():
+ """>>> add_log("def")"""
+
+def doc_without_test():
+ """Some docs"""
+
+def nodocstring():
+ pass
+
+cpdef mycpdeffunc():
+ """>>> add_log("cpdef")"""
+
+
+class MyClass:
+ """
+ Needs no hack
+
+ >>> add_log("class")
+ >>> True
+ True
+ """
+
+ def method(self):
+ """>>> add_log("class method")"""
+
+cdef class MyCdefClass:
+ """
+ Needs no hack
+
+ >>> add_log("cdef class")
+ >>> True
+ True
+ """
+ def method(self):
+ """>>> add_log("cdef class method")"""
+
+ cpdef cpdef_method(self):
+ """>>> add_log("cpdef class method")"""
+
+ cdef cdef_method(self):
+ """>>> add_log("cdef class method")"""
+
+ def __cinit__(self):
+ """
+ Should not be included, as it can't be looked up with getattr
+
+ >>> True
+ False
+ """
+
+ def __dealloc__(self):
+ """
+ Should not be included, as it can't be looked up with getattr
+
+ >>> True
+ False
+ """
+
+ def __richcmp__(self, other, int op):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 2
+
+ >>> True
+ False
+ """
+
+ def __nonzero__(self):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 3.1
+
+ >>> True
+ False
+ """
+
+ def __len__(self):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 3.1
+
+ >>> True
+ False
+ """
+
+ def __contains__(self, value):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 3.1
+
+ >>> True
+ False
+ """
+
+cdef class MyOtherCdefClass:
+ """
+ Needs no hack
+
+ >>> True
+ True
+ """
+
+ def __bool__(self):
+ """
+ Should not be included, as it can't be looked up with getattr in Py 2
+
+ >>> True
+ False
+ """
-#cython: doctesthack=True
+#cython: autotestdict=True
"""
-Tests that doctesthack doesn't come into effect when
+Tests that autotestdict doesn't come into effect when
a __test__ is defined manually.
If this doesn't work, then the function doctest should fail.