1 from Visitor
import ScopeTrackingTransform
2 from Nodes
import StatListNode
, SingleAssignmentNode
, CFuncDefNode
, DefNode
3 from ExprNodes
import DictNode
, DictItemNode
, NameNode
, UnicodeNode
4 from PyrexTypes
import py_object_type
5 from StringEncoding
import EncodedString
8 class AutoTestDictTransform(ScopeTrackingTransform
):
9 # Handles autotestdict directive
11 blacklist
= ['__cinit__', '__dealloc__', '__richcmp__',
12 '__nonzero__', '__bool__',
13 '__len__', '__contains__']
15 def visit_ModuleNode(self
, node
):
18 self
.scope_type
= 'module'
19 self
.scope_node
= node
21 if not self
.current_directives
['autotestdict']:
23 self
.all_docstrings
= self
.current_directives
['autotestdict.all']
24 self
.cdef_docstrings
= self
.all_docstrings
or self
.current_directives
['autotestdict.cdef']
26 assert isinstance(node
.body
, StatListNode
)
28 # First see if __test__ is already created
29 if u
'__test__' in node
.scope
.entries
:
36 self
.testspos
= node
.pos
38 test_dict_entry
= node
.scope
.declare_var(EncodedString(u
'__test__'),
42 create_test_dict_assignment
= SingleAssignmentNode(pos
,
43 lhs
=NameNode(pos
, name
=EncodedString(u
'__test__'),
44 entry
=test_dict_entry
),
45 rhs
=DictNode(pos
, key_value_pairs
=self
.tests
))
46 self
.visitchildren(node
)
47 node
.body
.stats
.append(create_test_dict_assignment
)
50 def add_test(self
, testpos
, path
, doctest
):
52 keystr
= u
'%s (line %d)' % (path
, testpos
[1])
53 key
= UnicodeNode(pos
, value
=EncodedString(keystr
))
54 value
= UnicodeNode(pos
, value
=doctest
)
55 self
.tests
.append(DictItemNode(pos
, key
=key
, value
=value
))
57 def visit_ExprNode(self
, node
):
58 # expressions cannot contain functions and lambda expressions
59 # do not have a docstring
62 def visit_FuncDefNode(self
, node
):
63 if not node
.doc
or (isinstance(node
, DefNode
) and node
.fused_py_func
):
65 if not self
.cdef_docstrings
:
66 if isinstance(node
, CFuncDefNode
) and not node
.py_func
:
68 if not self
.all_docstrings
and '>>>' not in node
.doc
:
72 if self
.scope_type
== 'module':
73 path
= node
.entry
.name
74 elif self
.scope_type
in ('pyclass', 'cclass'):
75 if isinstance(node
, CFuncDefNode
):
76 if node
.py_func
is not None:
77 name
= node
.py_func
.name
79 name
= node
.entry
.name
82 if self
.scope_type
== 'cclass' and name
in self
.blacklist
:
84 if self
.scope_type
== 'pyclass':
85 class_name
= self
.scope_node
.name
87 class_name
= self
.scope_node
.class_name
88 if isinstance(node
.entry
.scope
, Symtab
.PropertyScope
):
89 property_method_name
= node
.entry
.scope
.name
90 path
= "%s.%s.%s" % (class_name
, node
.entry
.scope
.name
,
93 path
= "%s.%s" % (class_name
, node
.entry
.name
)
96 self
.add_test(node
.pos
, path
, node
.doc
)