Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
833e3b2c
Commit
833e3b2c
authored
Oct 01, 2009
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
doctesthack directive
parent
5117b05e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
112 additions
and
31 deletions
+112
-31
Cython/Compiler/AnalysedTreeTransforms.py
Cython/Compiler/AnalysedTreeTransforms.py
+37
-14
Cython/Compiler/Visitor.py
Cython/Compiler/Visitor.py
+31
-0
tests/run/doctesthack.pyx
tests/run/doctesthack.pyx
+20
-17
tests/run/doctesthack_skip.pyx
tests/run/doctesthack_skip.pyx
+24
-0
No files found.
Cython/Compiler/AnalysedTreeTransforms.py
View file @
833e3b2c
from
Cython.Compiler.Visitor
import
VisitorTransform
,
Cython
Transform
,
TreeVisitor
from
Cython.Compiler.Visitor
import
VisitorTransform
,
ScopeTracking
Transform
,
TreeVisitor
from
Nodes
import
StatListNode
,
SingleAssignmentNode
from
Nodes
import
StatListNode
,
SingleAssignmentNode
from
ExprNodes
import
(
DictNode
,
DictItemNode
,
NameNode
,
UnicodeNode
,
NoneNode
,
from
ExprNodes
import
(
DictNode
,
DictItemNode
,
NameNode
,
UnicodeNode
,
NoneNode
,
ExprNode
,
AttributeNode
)
ExprNode
,
AttributeNode
)
...
@@ -7,12 +7,20 @@ from Builtin import dict_type
...
@@ -7,12 +7,20 @@ from Builtin import dict_type
from
StringEncoding
import
EncodedString
from
StringEncoding
import
EncodedString
import
Naming
import
Naming
class
DoctestHackTransform
(
Cython
Transform
):
class
DoctestHackTransform
(
ScopeTracking
Transform
):
# Handles doctesthack directive
# Handles doctesthack directive
def
visit_ModuleNode
(
self
,
node
):
def
visit_ModuleNode
(
self
,
node
):
self
.
scope_type
=
'module'
self
.
scope_node
=
node
if
self
.
current_directives
[
'doctesthack'
]:
if
self
.
current_directives
[
'doctesthack'
]:
assert
isinstance
(
node
.
body
,
StatListNode
)
assert
isinstance
(
node
.
body
,
StatListNode
)
# First see if __test__ is already created
if
u'__test__'
in
node
.
scope
.
entries
:
# Do nothing
return
node
pos
=
node
.
pos
pos
=
node
.
pos
self
.
tests
=
[]
self
.
tests
=
[]
...
@@ -32,26 +40,41 @@ class DoctestHackTransform(CythonTransform):
...
@@ -32,26 +40,41 @@ class DoctestHackTransform(CythonTransform):
return
node
return
node
def
add_test
(
self
,
testpos
,
name
,
funcname
):
def
add_test
(
self
,
testpos
,
name
,
func_ref_node
):
# func_ref_node must evaluate to the function object containing
# the docstring, BUT it should not be the function itself (which
# would lead to a new *definition* of the function)
pos
=
self
.
testspos
pos
=
self
.
testspos
keystr
=
u'%s (line %d)'
%
(
name
,
testpos
[
1
])
keystr
=
u'%s (line %d)'
%
(
name
,
testpos
[
1
])
key
=
UnicodeNode
(
pos
,
value
=
EncodedString
(
keystr
))
key
=
UnicodeNode
(
pos
,
value
=
EncodedString
(
keystr
))
getfunc
=
AttributeNode
(
pos
,
obj
=
ModuleRefNode
(
pos
),
value
=
DocstringRefNode
(
pos
,
func_ref_node
)
attribute
=
funcname
,
type
=
py_object_type
,
is_py_attr
=
True
,
is_temp
=
True
)
value
=
DocstringRefNode
(
pos
,
getfunc
)
self
.
tests
.
append
(
DictItemNode
(
pos
,
key
=
key
,
value
=
value
))
self
.
tests
.
append
(
DictItemNode
(
pos
,
key
=
key
,
value
=
value
))
def
visit_ClassDefNode
(
self
,
node
):
return
node
def
visit_FuncDefNode
(
self
,
node
):
def
visit_FuncDefNode
(
self
,
node
):
if
node
.
doc
:
if
node
.
doc
:
self
.
add_test
(
node
.
pos
,
node
.
entry
.
name
,
node
.
entry
.
name
)
pos
=
self
.
testspos
if
self
.
scope_type
==
'module'
:
parent
=
ModuleRefNode
(
pos
)
name
=
node
.
entry
.
name
elif
self
.
scope_type
in
(
'pyclass'
,
'cclass'
):
mod
=
ModuleRefNode
(
pos
)
if
self
.
scope_type
==
'pyclass'
:
clsname
=
self
.
scope_node
.
name
else
:
clsname
=
self
.
scope_node
.
class_name
parent
=
AttributeNode
(
pos
,
obj
=
mod
,
attribute
=
clsname
,
type
=
py_object_type
,
is_py_attr
=
True
,
is_temp
=
True
)
name
=
"%s.%s"
%
(
clsname
,
node
.
entry
.
name
)
getfunc
=
AttributeNode
(
pos
,
obj
=
parent
,
attribute
=
node
.
entry
.
name
,
type
=
py_object_type
,
is_py_attr
=
True
,
is_temp
=
True
)
self
.
add_test
(
node
.
pos
,
name
,
getfunc
)
return
node
return
node
...
...
Cython/Compiler/Visitor.py
View file @
833e3b2c
...
@@ -275,6 +275,37 @@ class CythonTransform(VisitorTransform):
...
@@ -275,6 +275,37 @@ class CythonTransform(VisitorTransform):
self
.
visitchildren
(
node
)
self
.
visitchildren
(
node
)
return
node
return
node
class
ScopeTrackingTransform
(
CythonTransform
):
# Keeps track of type of scopes
scope_type
=
None
# can be either of 'module', 'function', 'cclass', 'pyclass'
scope_node
=
None
def
visit_ModuleNode
(
self
,
node
):
self
.
scope_type
=
'module'
self
.
scope_node
=
node
self
.
visitchildren
(
node
)
return
node
def
visit_scope
(
self
,
node
,
scope_type
):
prev
=
self
.
scope_type
,
self
.
scope_node
self
.
scope_type
=
scope_type
self
.
scope_node
=
node
self
.
visitchildren
(
node
)
self
.
scope_type
,
self
.
scope_node
=
prev
return
node
def
visit_CClassDefNode
(
self
,
node
):
return
self
.
visit_scope
(
node
,
'cclass'
)
def
visit_PyClassDefNode
(
self
,
node
):
return
self
.
visit_scope
(
node
,
'pyclass'
)
def
visit_FuncDefNode
(
self
,
node
):
return
self
.
visit_scope
(
node
,
'function'
)
def
visit_CStructOrUnionDefNode
(
self
,
node
):
return
self
.
visit_scope
(
node
,
'struct'
)
...
...
tests/run/doctesthack.pyx
View file @
833e3b2c
...
@@ -12,18 +12,20 @@ all_tests_run() is executed which does final validation.
...
@@ -12,18 +12,20 @@ all_tests_run() is executed which does final validation.
>>> items.sort()
>>> items.sort()
>>> for key, value in items:
>>> for key, value in items:
... print key, ';', value
... print key, ';', value
mycpdeffunc (line 40) ; >>> add_log("cpdef")
MyCdefClass.method (line 67) ; >>> add_log("cdef class method")
myfunc (line 34) ; >>> add_log("def")
MyClass.method (line 57) ; >>> add_log("class method")
doc_without_test (line 39) ; Some docs
mycpdeffunc (line 45) ; >>> add_log("cpdef")
myfunc (line 36) ; >>> add_log("def")
"""
"""
log
=
[]
log
=
[]
#__test__ = {'a':'445', 'b':'3'}
def
all_tests_run
():
def
all_tests_run
():
log
.
sort
()
log
.
sort
()
assert
log
==
[
u'cpdef'
,
u'def'
],
log
assert
log
==
[
u'c
def class method'
,
u'class method'
,
u'c
pdef'
,
u'def'
],
log
def
add_log
(
s
):
def
add_log
(
s
):
log
.
append
(
unicode
(
s
))
log
.
append
(
unicode
(
s
))
...
@@ -34,6 +36,9 @@ def add_log(s):
...
@@ -34,6 +36,9 @@ def add_log(s):
def
myfunc
():
def
myfunc
():
""">>> add_log("def")"""
""">>> add_log("def")"""
def
doc_without_test
():
"""Some docs"""
def
nodocstring
():
def
nodocstring
():
pass
pass
...
@@ -50,17 +55,15 @@ class MyClass:
...
@@ -50,17 +55,15 @@ class MyClass:
"""
"""
def
method
(
self
):
def
method
(
self
):
""">>> add_log("class method")"""
cdef
class
MyCdefClass
:
"""
"""
Needs no hack
>>> True
>>> True
Fals
e
Tru
e
"""
"""
def
method
(
self
):
## cdef class MyCdefClass:
""">>> add_log("cdef class method")"""
## """
## >>> add_log("cdef class")
## """
## def method(self):
## """
## >>> add_log("cdef class method")
## """
tests/run/doctesthack_skip.pyx
0 → 100644
View file @
833e3b2c
#cython: doctesthack=True
"""
Tests that doctesthack doesn't come into effect when
a __test__ is defined manually.
If this doesn't work, then the function doctest should fail.
>>> True
True
"""
def
func
():
"""
>>> True
False
"""
__test__
=
{
u"one"
:
"""
>>> True
True
"""
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment