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
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
cython
Commits
143113fc
Commit
143113fc
authored
Jan 21, 2010
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#479, sub-directives via keywords
parent
5553fc00
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
92 additions
and
62 deletions
+92
-62
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+3
-0
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+82
-61
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+1
-1
tests/compile/c_directives.pyx
tests/compile/c_directives.pyx
+6
-0
No files found.
Cython/Compiler/Options.py
View file @
143113fc
...
...
@@ -64,6 +64,9 @@ directive_defaults = {
'profile'
:
False
,
'infer_types'
:
False
,
'autotestdict'
:
True
,
'warn'
:
None
,
'warn.undeclared'
:
False
,
# test support
'test_assert_path_exists'
:
[],
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
143113fc
...
...
@@ -427,55 +427,74 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
node
.
cython_attribute
=
self
.
directive_names
.
get
(
node
.
name
)
return
node
def
try_to_parse_directive
(
self
,
node
):
def
try_to_parse_directive
s
(
self
,
node
):
# If node is the contents of an directive (in a with statement or
# decorator), returns
(directivename, value)
.
# decorator), returns
a list of (directivename, value) pairs
.
# Otherwise, returns None
optname
=
None
if
isinstance
(
node
,
CallNode
):
self
.
visit
(
node
.
function
)
optname
=
node
.
function
.
as_cython_attribute
()
if
optname
:
directivetype
=
Options
.
directive_types
.
get
(
optname
)
if
directivetype
:
args
,
kwds
=
node
.
explicit_args_kwds
()
if
optname
==
'infer_types'
:
if
kwds
is
not
None
or
len
(
args
)
!=
1
:
raise
PostParseError
(
node
.
function
.
pos
,
'The %s directive takes one compile-time boolean argument'
%
optname
)
elif
isinstance
(
args
[
0
],
BoolNode
):
return
(
optname
,
args
[
0
].
value
)
elif
isinstance
(
args
[
0
],
NoneNode
):
return
(
optname
,
None
)
else
:
raise
PostParseError
(
node
.
function
.
pos
,
'The %s directive takes one compile-time boolean argument'
%
optname
)
elif
directivetype
is
bool
:
if
kwds
is
not
None
or
len
(
args
)
!=
1
or
not
isinstance
(
args
[
0
],
BoolNode
):
raise
PostParseError
(
node
.
function
.
pos
,
'The %s directive takes one compile-time boolean argument'
%
optname
)
return
(
optname
,
args
[
0
].
value
)
elif
directivetype
is
str
:
if
kwds
is
not
None
or
len
(
args
)
!=
1
or
not
isinstance
(
args
[
0
],
(
StringNode
,
UnicodeNode
)):
raise
PostParseError
(
node
.
function
.
pos
,
'The %s directive takes one compile-time string argument'
%
optname
)
return
(
optname
,
str
(
args
[
0
].
value
))
elif
directivetype
is
dict
:
if
len
(
args
)
!=
0
:
raise
PostParseError
(
node
.
function
.
pos
,
'The %s directive takes no prepositional arguments'
%
optname
)
return
optname
,
dict
([(
key
.
value
,
value
)
for
key
,
value
in
kwds
.
key_value_pairs
])
elif
directivetype
is
list
:
if
kwds
and
len
(
kwds
)
!=
0
:
raise
PostParseError
(
node
.
function
.
pos
,
'The %s directive takes no keyword arguments'
%
optname
)
return
optname
,
[
str
(
arg
.
value
)
for
arg
in
args
]
else
:
assert
False
if
optname
:
directivetype
=
Options
.
directive_types
.
get
(
optname
)
if
directivetype
:
args
,
kwds
=
node
.
explicit_args_kwds
()
directives
=
[]
key_value_pairs
=
[]
if
kwds
is
not
None
and
directivetype
is
not
dict
:
for
keyvalue
in
kwds
.
key_value_pairs
:
key
,
value
=
keyvalue
sub_optname
=
"%s.%s"
%
(
optname
,
key
.
value
)
if
Options
.
directive_types
.
get
(
sub_optname
):
directives
.
append
(
self
.
try_to_parse_directive
(
sub_optname
,
[
value
],
None
,
keyvalue
.
pos
))
else
:
key_value_pairs
.
append
(
keyvalue
)
if
not
key_value_pairs
:
kwds
=
None
else
:
kwds
.
key_value_pairs
=
key_value_pairs
if
directives
and
not
kwds
and
not
args
:
return
directives
directives
.
append
(
self
.
try_to_parse_directive
(
optname
,
args
,
kwds
,
node
.
function
.
pos
))
return
directives
return
None
def
try_to_parse_directive
(
self
,
optname
,
args
,
kwds
,
pos
):
directivetype
=
Options
.
directive_types
.
get
(
optname
)
if
optname
==
'infer_types'
:
if
kwds
is
not
None
or
len
(
args
)
!=
1
:
raise
PostParseError
(
pos
,
'The %s directive takes one compile-time boolean argument'
%
optname
)
elif
isinstance
(
args
[
0
],
BoolNode
):
return
(
optname
,
args
[
0
].
value
)
elif
isinstance
(
args
[
0
],
NoneNode
):
return
(
optname
,
None
)
else
:
raise
PostParseError
(
pos
,
'The %s directive takes one compile-time boolean argument'
%
optname
)
elif
directivetype
is
bool
:
if
kwds
is
not
None
or
len
(
args
)
!=
1
or
not
isinstance
(
args
[
0
],
BoolNode
):
raise
PostParseError
(
pos
,
'The %s directive takes one compile-time boolean argument'
%
optname
)
return
(
optname
,
args
[
0
].
value
)
elif
directivetype
is
str
:
if
kwds
is
not
None
or
len
(
args
)
!=
1
or
not
isinstance
(
args
[
0
],
(
StringNode
,
UnicodeNode
)):
raise
PostParseError
(
pos
,
'The %s directive takes one compile-time string argument'
%
optname
)
return
(
optname
,
str
(
args
[
0
].
value
))
elif
directivetype
is
dict
:
if
len
(
args
)
!=
0
:
raise
PostParseError
(
pos
,
'The %s directive takes no prepositional arguments'
%
optname
)
return
optname
,
dict
([(
key
.
value
,
value
)
for
key
,
value
in
kwds
.
key_value_pairs
])
elif
directivetype
is
list
:
if
kwds
and
len
(
kwds
)
!=
0
:
raise
PostParseError
(
pos
,
'The %s directive takes no keyword arguments'
%
optname
)
return
optname
,
[
str
(
arg
.
value
)
for
arg
in
args
]
else
:
assert
False
def
visit_with_directives
(
self
,
body
,
directives
):
olddirectives
=
self
.
directives
newdirectives
=
copy
.
copy
(
olddirectives
)
...
...
@@ -495,9 +514,9 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
# Split the decorators into two lists -- real decorators and directives
realdecs
=
[]
for
dec
in
node
.
decorators
:
directive
=
self
.
try_to_parse_directive
(
dec
.
decorator
)
if
directive
is
not
None
:
directives
.
append
(
directive
)
new_directives
=
self
.
try_to_parse_directives
(
dec
.
decorator
)
if
new_directives
is
not
None
:
directives
.
extend
(
new_directives
)
else
:
realdecs
.
append
(
dec
)
if
realdecs
and
isinstance
(
node
,
CFuncDefNode
):
...
...
@@ -533,26 +552,28 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
def
visit_CVarDefNode
(
self
,
node
):
if
node
.
decorators
:
for
dec
in
node
.
decorators
:
directive
=
self
.
try_to_parse_directive
(
dec
.
decorator
)
if
directive
is
not
None
and
directive
[
0
]
==
u'locals'
:
node
.
directive_locals
=
directive
[
1
]
else
:
self
.
context
.
nonfatal_error
(
PostParseError
(
dec
.
pos
,
"Cdef functions can only take cython.locals() decorator."
))
continue
for
directive
in
self
.
try_to_parse_directives
(
dec
.
decorator
)
or
[]:
if
directive
is
not
None
and
directive
[
0
]
==
u'locals'
:
node
.
directive_locals
=
directive
[
1
]
else
:
self
.
context
.
nonfatal_error
(
PostParseError
(
dec
.
pos
,
"Cdef functions can only take cython.locals() decorator."
))
return
node
# Handle with statements
def
visit_WithStatNode
(
self
,
node
):
directive
=
self
.
try_to_parse_directive
(
node
.
manager
)
if
directive
is
not
None
:
if
node
.
target
is
not
None
:
self
.
context
.
nonfatal_error
(
PostParseError
(
node
.
pos
,
"Compiler directive with statements cannot contain 'as'"
))
else
:
name
,
value
=
directive
if
self
.
check_directive_scope
(
node
.
pos
,
name
,
'with statement'
):
return
self
.
visit_with_directives
(
node
.
body
,
{
name
:
value
})
directive_dict
=
{}
for
directive
in
self
.
try_to_parse_directives
(
node
.
manager
)
or
[]:
if
directive
is
not
None
:
if
node
.
target
is
not
None
:
self
.
context
.
nonfatal_error
(
PostParseError
(
node
.
pos
,
"Compiler directive with statements cannot contain 'as'"
))
else
:
name
,
value
=
directive
if
self
.
check_directive_scope
(
node
.
pos
,
name
,
'with statement'
):
directive_dict
[
name
]
=
value
if
directive_dict
:
return
self
.
visit_with_directives
(
node
.
body
,
directive_dict
)
return
self
.
visit_Node
(
node
)
class
WithTransform
(
CythonTransform
,
SkipDeclarations
):
...
...
Cython/Compiler/Parsing.py
View file @
143113fc
...
...
@@ -2579,7 +2579,7 @@ def p_code(s, level=None):
repr
(
s
.
sy
),
repr
(
s
.
systring
)))
return
body
COMPILER_DIRECTIVE_COMMENT_RE
=
re
.
compile
(
r"^#\
s*cy
thon:\
s*(
\w
+\
s*=.*)$
")
COMPILER_DIRECTIVE_COMMENT_RE
=
re
.
compile
(
r"^#\
s*cy
thon:\
s*(
(
\w|[.])
+\
s*=.*)$
")
def p_compiler_directive_comments(s):
result = {}
...
...
tests/compile/c_directives.pyx
View file @
143113fc
# cython: boundscheck = False
# cython: ignoreme = OK
# cython: warn.undeclared = False
# This testcase is most useful if you inspect the generated C file
...
...
@@ -32,3 +33,8 @@ def i(object[int] buf):
with
bc
(
True
):
print
buf
[
3
]
# bs
from
cython
cimport
warn
as
my_warn
@
my_warn
(
undeclared
=
True
)
def
j
():
pass
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