Cython has moved to github.
cython-devel
view Cython/Compiler/AnalysedTreeTransforms.py @ 2981:f06147ed2f0b
Fix #508
| author | Dag Sverre Seljebotn <dagss@student.matnat.uio.no> |
|---|---|
| date | Sat Feb 20 13:36:10 2010 +0100 (2 years ago) |
| parents | 7289c41ad3c3 |
| children | 222ff70acc41 |
line source
1 from Cython.Compiler.Visitor import VisitorTransform, ScopeTrackingTransform, TreeVisitor
2 from Nodes import StatListNode, SingleAssignmentNode, CFuncDefNode
3 from ExprNodes import DictNode, DictItemNode, NameNode, UnicodeNode, NoneNode, \
4 ExprNode, AttributeNode, ModuleRefNode, DocstringRefNode
5 from PyrexTypes import py_object_type
6 from Builtin import dict_type
7 from StringEncoding import EncodedString
8 import Naming
10 class AutoTestDictTransform(ScopeTrackingTransform):
11 # Handles autotestdict directive
13 blacklist = ['__cinit__', '__dealloc__', '__richcmp__', '__nonzero__']
15 def visit_ModuleNode(self, node):
16 if node.is_pxd:
17 return node
18 self.scope_type = 'module'
19 self.scope_node = node
20 if self.current_directives['autotestdict']:
21 assert isinstance(node.body, StatListNode)
23 # First see if __test__ is already created
24 if u'__test__' in node.scope.entries:
25 # Do nothing
26 return node
28 pos = node.pos
30 self.tests = []
31 self.testspos = node.pos
33 test_dict_entry = node.scope.declare_var(EncodedString(u'__test__'),
34 py_object_type,
35 pos,
36 visibility='public')
37 create_test_dict_assignment = SingleAssignmentNode(pos,
38 lhs=NameNode(pos, name=EncodedString(u'__test__'),
39 entry=test_dict_entry),
40 rhs=DictNode(pos, key_value_pairs=self.tests))
41 self.visitchildren(node)
42 node.body.stats.append(create_test_dict_assignment)
45 return node
47 def add_test(self, testpos, name, func_ref_node):
48 # func_ref_node must evaluate to the function object containing
49 # the docstring, BUT it should not be the function itself (which
50 # would lead to a new *definition* of the function)
51 pos = self.testspos
52 keystr = u'%s (line %d)' % (name, testpos[1])
53 key = UnicodeNode(pos, value=EncodedString(keystr))
55 value = DocstringRefNode(pos, func_ref_node)
56 self.tests.append(DictItemNode(pos, key=key, value=value))
58 def visit_FuncDefNode(self, node):
59 if node.doc:
60 if isinstance(node, CFuncDefNode) and not node.py_func:
61 # skip non-cpdef cdef functions
62 return node
64 pos = self.testspos
65 if self.scope_type == 'module':
66 parent = ModuleRefNode(pos)
67 name = node.entry.name
68 elif self.scope_type in ('pyclass', 'cclass'):
69 if isinstance(node, CFuncDefNode):
70 name = node.py_func.name
71 else:
72 name = node.name
73 if self.scope_type == 'cclass' and name in self.blacklist:
74 return node
75 mod = ModuleRefNode(pos)
76 if self.scope_type == 'pyclass':
77 clsname = self.scope_node.name
78 else:
79 clsname = self.scope_node.class_name
80 parent = AttributeNode(pos, obj=mod,
81 attribute=clsname,
82 type=py_object_type,
83 is_py_attr=True,
84 is_temp=True)
85 name = "%s.%s" % (clsname, node.entry.name)
86 else:
87 assert False
88 getfunc = AttributeNode(pos, obj=parent,
89 attribute=node.entry.name,
90 type=py_object_type,
91 is_py_attr=True,
92 is_temp=True)
93 self.add_test(node.pos, name, getfunc)
94 return node
