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
Xavier Thompson
cython
Commits
f019888c
Commit
f019888c
authored
Aug 04, 2019
by
realead
Committed by
Stefan Behnel
Aug 04, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace custom command line parser with argparse (GH-3001)
parent
78e417e5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
594 additions
and
233 deletions
+594
-233
Cython/Build/Cythonize.py
Cython/Build/Cythonize.py
+2
-27
Cython/Compiler/CmdLine.py
Cython/Compiler/CmdLine.py
+205
-205
Cython/Compiler/Tests/TestCmdLine.py
Cython/Compiler/Tests/TestCmdLine.py
+387
-1
No files found.
Cython/Build/Cythonize.py
View file @
f019888c
...
...
@@ -120,33 +120,8 @@ def run_distutils(args):
def
create_args_parser
():
from
argparse
import
ArgumentParser
,
Action
class
ParseDirectivesAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
old_directives
=
dict
(
getattr
(
namespace
,
self
.
dest
,
Options
.
get_directive_defaults
()))
directives
=
Options
.
parse_directive_list
(
values
,
relaxed_bool
=
True
,
current_settings
=
old_directives
)
setattr
(
namespace
,
self
.
dest
,
directives
)
class
ParseOptionsAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
options
=
dict
(
getattr
(
namespace
,
self
.
dest
,
{}))
for
opt
in
values
.
split
(
','
):
if
'='
in
opt
:
n
,
v
=
opt
.
split
(
'='
,
1
)
v
=
v
.
lower
()
not
in
(
'false'
,
'f'
,
'0'
,
'no'
)
else
:
n
,
v
=
opt
,
True
options
[
n
]
=
v
setattr
(
namespace
,
self
.
dest
,
options
)
class
ParseCompileTimeEnvAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
old_env
=
dict
(
getattr
(
namespace
,
self
.
dest
,
{}))
new_env
=
Options
.
parse_compile_time_env
(
values
,
current_settings
=
old_env
)
setattr
(
namespace
,
self
.
dest
,
new_env
)
from
argparse
import
ArgumentParser
from
..Compiler.CmdLine
import
ParseDirectivesAction
,
ParseOptionsAction
,
ParseCompileTimeEnvAction
parser
=
ArgumentParser
()
...
...
Cython/Compiler/CmdLine.py
View file @
f019888c
...
...
@@ -5,222 +5,222 @@
from
__future__
import
absolute_import
import
os
import
sys
from
argparse
import
ArgumentParser
,
Action
,
SUPPRESS
from
.
import
Options
usage
=
"""
\
Cython (https://cython.org/) is a compiler for code written in the
Cython language. Cython is based on Pyrex by Greg Ewing.
Usage: cython [options] sourcefile.{pyx,py} ...
Options:
-V, --version Display version number of cython compiler
-l, --create-listing Write error messages to a listing file
-I, --include-dir <directory> Search for include files in named directory
(multiple include directories are allowed).
-o, --output-file <filename> Specify name of generated C file
-t, --timestamps Only compile newer source files
-f, --force Compile all source files (overrides implied -t)
-v, --verbose Be verbose, print file names on multiple compilation
-p, --embed-positions If specified, the positions in Cython files of each
function definition is embedded in its docstring.
--cleanup <level> Release interned objects on python exit, for memory debugging.
Level indicates aggressiveness, default 0 releases nothing.
-w, --working <directory> Sets the working directory for Cython (the directory modules
are searched from)
--gdb Output debug information for cygdb
--gdb-outdir <directory> Specify gdb debug information output directory. Implies --gdb.
-D, --no-docstrings Strip docstrings from the compiled module.
-a, --annotate Produce a colorized HTML version of the source.
--annotate-fullc Produce a colorized HTML version of the source which
includes entire generated C/C++-code.
--annotate-coverage <cov.xml> Annotate and include coverage information from cov.xml.
--line-directives Produce #line directives pointing to the .pyx source
--cplus Output a C++ rather than C file.
--embed[=<method_name>] Generate a main() function that embeds the Python interpreter.
-2 Compile based on Python-2 syntax and code semantics.
-3 Compile based on Python-3 syntax and code semantics.
--3str Compile based on Python-3 syntax and code semantics without
assuming unicode by default for string literals under Python 2.
--lenient Change some compile time errors to runtime errors to
improve Python compatibility
--capi-reexport-cincludes Add cincluded headers to any auto-generated header files.
--fast-fail Abort the compilation on the first error
--warning-errors, -Werror Make all warnings into errors
--warning-extra, -Wextra Enable extra warnings
-X, --directive <name>=<value>[,<name=value,...] Overrides a compiler directive
-E, --compile-time-env name=value[,<name=value,...] Provides compile time env like DEF would do.
"""
# The following experimental options are supported only on MacOSX:
# -C, --compile Compile generated .c file to .o file
# --link Link .o file to produce extension module (implies -C)
# -+, --cplus Use C++ compiler for compiling and linking
# Additional .o files to link may be supplied when using -X."""
def
bad_usage
():
sys
.
stderr
.
write
(
usage
)
sys
.
exit
(
1
)
class
ParseDirectivesAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
old_directives
=
dict
(
getattr
(
namespace
,
self
.
dest
,
Options
.
get_directive_defaults
()))
directives
=
Options
.
parse_directive_list
(
values
,
relaxed_bool
=
True
,
current_settings
=
old_directives
)
setattr
(
namespace
,
self
.
dest
,
directives
)
def
parse_command_line
(
args
):
pending_arg
=
[]
def
pop_arg
():
if
not
args
or
pending_arg
:
bad_usage
()
if
'='
in
args
[
0
]
and
args
[
0
].
startswith
(
'--'
):
# allow "--long-option=xyz"
name
,
value
=
args
.
pop
(
0
).
split
(
'='
,
1
)
pending_arg
.
append
(
value
)
return
name
return
args
.
pop
(
0
)
def
pop_value
(
default
=
None
):
if
pending_arg
:
return
pending_arg
.
pop
()
elif
default
is
not
None
:
return
default
elif
not
args
:
bad_usage
()
return
args
.
pop
(
0
)
def
get_param
(
option
):
tail
=
option
[
2
:]
if
tail
:
return
tail
class
ParseOptionsAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
options
=
dict
(
getattr
(
namespace
,
self
.
dest
,
{}))
for
opt
in
values
.
split
(
','
):
if
'='
in
opt
:
n
,
v
=
opt
.
split
(
'='
,
1
)
v
=
v
.
lower
()
not
in
(
'false'
,
'f'
,
'0'
,
'no'
)
else
:
n
,
v
=
opt
,
True
options
[
n
]
=
v
setattr
(
namespace
,
self
.
dest
,
options
)
class
ParseCompileTimeEnvAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
old_env
=
dict
(
getattr
(
namespace
,
self
.
dest
,
{}))
new_env
=
Options
.
parse_compile_time_env
(
values
,
current_settings
=
old_env
)
setattr
(
namespace
,
self
.
dest
,
new_env
)
class
ActivateAllWarningsAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
directives
=
getattr
(
namespace
,
'compiler_directives'
,
{})
directives
.
update
(
Options
.
extra_warnings
)
namespace
.
compiler_directives
=
directives
class
SetLenientAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
namespace
.
error_on_unknown_names
=
False
namespace
.
error_on_uninitialized
=
False
class
SetGDBDebugAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
namespace
.
gdb_debug
=
True
namespace
.
output_dir
=
os
.
curdir
class
SetGDBDebugOutputAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
namespace
.
gdb_debug
=
True
namespace
.
output_dir
=
values
class
SetAnnotateCoverageAction
(
Action
):
def
__call__
(
self
,
parser
,
namespace
,
values
,
option_string
=
None
):
namespace
.
annotate
=
True
namespace
.
annotate_coverage_xml
=
values
def
create_cython_argparser
():
description
=
"Cython (https://cython.org/) is a compiler for code written in the "
\
"Cython language. Cython is based on Pyrex by Greg Ewing."
parser
=
ArgumentParser
(
description
=
description
,
argument_default
=
SUPPRESS
)
parser
.
add_argument
(
"-V"
,
"--version"
,
dest
=
'show_version'
,
action
=
'store_const'
,
const
=
1
,
help
=
'Display version number of cython compiler'
)
parser
.
add_argument
(
"-l"
,
"--create-listing"
,
dest
=
'use_listing_file'
,
action
=
'store_const'
,
const
=
1
,
help
=
'Write error messages to a listing file'
)
parser
.
add_argument
(
"-I"
,
"--include-dir"
,
dest
=
'include_path'
,
action
=
'append'
,
help
=
'Search for include files in named directory '
'(multiple include directories are allowed).'
)
parser
.
add_argument
(
"-o"
,
"--output-file"
,
dest
=
'output_file'
,
action
=
'store'
,
type
=
str
,
help
=
'Specify name of generated C file'
)
parser
.
add_argument
(
"-t"
,
"--timestamps"
,
dest
=
'timestamps'
,
action
=
'store_const'
,
const
=
1
,
help
=
'Only compile newer source files'
)
parser
.
add_argument
(
"-f"
,
"--force"
,
dest
=
'timestamps'
,
action
=
'store_const'
,
const
=
0
,
help
=
'Compile all source files (overrides implied -t)'
)
parser
.
add_argument
(
"-v"
,
"--verbose"
,
dest
=
'verbose'
,
action
=
'count'
,
help
=
'Be verbose, print file names on multiple compilation'
)
parser
.
add_argument
(
"-p"
,
"--embed-positions"
,
dest
=
'embed_pos_in_docstring'
,
action
=
'store_const'
,
const
=
1
,
help
=
'If specified, the positions in Cython files of each '
'function definition is embedded in its docstring.'
)
parser
.
add_argument
(
"--cleanup"
,
dest
=
'generate_cleanup_code'
,
action
=
'store'
,
type
=
int
,
help
=
'Release interned objects on python exit, for memory debugging. '
'Level indicates aggressiveness, default 0 releases nothing.'
)
parser
.
add_argument
(
"-w"
,
"--working"
,
dest
=
'working_path'
,
action
=
'store'
,
type
=
str
,
help
=
'Sets the working directory for Cython (the directory modules are searched from)'
)
parser
.
add_argument
(
"--gdb"
,
action
=
SetGDBDebugAction
,
nargs
=
0
,
help
=
'Output debug information for cygdb'
)
parser
.
add_argument
(
"--gdb-outdir"
,
action
=
SetGDBDebugOutputAction
,
type
=
str
,
help
=
'Specify gdb debug information output directory. Implies --gdb.'
)
parser
.
add_argument
(
"-D"
,
"--no-docstrings"
,
dest
=
'docstrings'
,
action
=
'store_false'
,
help
=
'Strip docstrings from the compiled module.'
)
parser
.
add_argument
(
'-a'
,
'--annotate'
,
action
=
'store_const'
,
const
=
'default'
,
dest
=
'annotate'
,
help
=
'Produce a colorized HTML version of the source.'
)
parser
.
add_argument
(
'--annotate-fullc'
,
action
=
'store_const'
,
const
=
'fullc'
,
dest
=
'annotate'
,
help
=
'Produce a colorized HTML version of the source '
'which includes entire generated C/C++-code.'
)
parser
.
add_argument
(
"--annotate-coverage"
,
dest
=
'annotate_coverage_xml'
,
action
=
SetAnnotateCoverageAction
,
type
=
str
,
help
=
'Annotate and include coverage information from cov.xml.'
)
parser
.
add_argument
(
"--line-directives"
,
dest
=
'emit_linenums'
,
action
=
'store_true'
,
help
=
'Produce #line directives pointing to the .pyx source'
)
parser
.
add_argument
(
"-+"
,
"--cplus"
,
dest
=
'cplus'
,
action
=
'store_const'
,
const
=
1
,
help
=
'Output a C++ rather than C file.'
)
parser
.
add_argument
(
'--embed'
,
action
=
'store_const'
,
const
=
'main'
,
help
=
'Generate a main() function that embeds the Python interpreter. '
'Pass --embed=<method_name> for a name other than main().'
)
parser
.
add_argument
(
'-2'
,
dest
=
'language_level'
,
action
=
'store_const'
,
const
=
2
,
help
=
'Compile based on Python-2 syntax and code semantics.'
)
parser
.
add_argument
(
'-3'
,
dest
=
'language_level'
,
action
=
'store_const'
,
const
=
3
,
help
=
'Compile based on Python-3 syntax and code semantics.'
)
parser
.
add_argument
(
'--3str'
,
dest
=
'language_level'
,
action
=
'store_const'
,
const
=
'3str'
,
help
=
'Compile based on Python-3 syntax and code semantics without '
'assuming unicode by default for string literals under Python 2.'
)
parser
.
add_argument
(
"--lenient"
,
action
=
SetLenientAction
,
nargs
=
0
,
help
=
'Change some compile time errors to runtime errors to '
'improve Python compatibility'
)
parser
.
add_argument
(
"--capi-reexport-cincludes"
,
dest
=
'capi_reexport_cincludes'
,
action
=
'store_true'
,
help
=
'Add cincluded headers to any auto-generated header files.'
)
parser
.
add_argument
(
"--fast-fail"
,
dest
=
'fast_fail'
,
action
=
'store_true'
,
help
=
'Abort the compilation on the first error'
)
parser
.
add_argument
(
"-Werror"
,
"--warning-errors"
,
dest
=
'warning_errors'
,
action
=
'store_true'
,
help
=
'Make all warnings into errors'
)
parser
.
add_argument
(
"-Wextra"
,
"--warning-extra"
,
action
=
ActivateAllWarningsAction
,
nargs
=
0
,
help
=
'Enable extra warnings'
)
parser
.
add_argument
(
'-X'
,
'--directive'
,
metavar
=
'NAME=VALUE,...'
,
dest
=
'compiler_directives'
,
type
=
str
,
action
=
ParseDirectivesAction
,
help
=
'Overrides a compiler directive'
)
parser
.
add_argument
(
'-E'
,
'--compile-time-env'
,
metavar
=
'NAME=VALUE,...'
,
dest
=
'compile_time_env'
,
type
=
str
,
action
=
ParseCompileTimeEnvAction
,
help
=
'Provides compile time env like DEF would do.'
)
parser
.
add_argument
(
'sources'
,
nargs
=
'*'
,
default
=
[])
# TODO: add help
parser
.
add_argument
(
"-z"
,
"--pre-import"
,
dest
=
'pre_import'
,
action
=
'store'
,
type
=
str
,
help
=
SUPPRESS
)
parser
.
add_argument
(
"--convert-range"
,
dest
=
'convert_range'
,
action
=
'store_true'
,
help
=
SUPPRESS
)
parser
.
add_argument
(
"--no-c-in-traceback"
,
dest
=
'c_line_in_traceback'
,
action
=
'store_false'
,
help
=
SUPPRESS
)
parser
.
add_argument
(
"--cimport-from-pyx"
,
dest
=
'cimport_from_pyx'
,
action
=
'store_true'
,
help
=
SUPPRESS
)
parser
.
add_argument
(
"--old-style-globals"
,
dest
=
'old_style_globals'
,
action
=
'store_true'
,
help
=
SUPPRESS
)
# debug stuff:
from
.
import
DebugFlags
for
name
in
vars
(
DebugFlags
):
if
name
.
startswith
(
"debug"
):
option_name
=
name
.
replace
(
'_'
,
'-'
)
parser
.
add_argument
(
"--"
+
option_name
,
action
=
'store_true'
,
help
=
SUPPRESS
)
return
parser
def
parse_command_line_raw
(
parser
,
args
):
# special handling for --embed and --embed=xxxx as they aren't correctly parsed
def
filter_out_embed_options
(
args
):
with_embed
,
without_embed
=
[],
[]
for
x
in
args
:
if
x
==
'--embed'
or
x
.
startswith
(
'--embed='
):
with_embed
.
append
(
x
)
else
:
without_embed
.
append
(
x
)
return
with_embed
,
without_embed
with_embed
,
args_without_embed
=
filter_out_embed_options
(
args
)
arguments
,
unknown
=
parser
.
parse_known_args
(
args_without_embed
)
sources
=
arguments
.
sources
del
arguments
.
sources
# unknown can be either debug, embed or input files or really unknown
for
option
in
unknown
:
if
option
.
startswith
(
'-'
):
parser
.
error
(
"unknown option "
+
option
)
else
:
return
pop_arg
()
sources
.
append
(
option
)
# embed-stuff must be handled extra:
for
x
in
with_embed
:
if
x
==
'--embed'
:
name
=
'main'
# default value
else
:
name
=
x
[
len
(
'--embed='
):]
setattr
(
arguments
,
'embed'
,
name
)
return
arguments
,
sources
def
parse_command_line
(
args
):
parser
=
create_cython_argparser
()
arguments
,
sources
=
parse_command_line_raw
(
parser
,
args
)
options
=
Options
.
CompilationOptions
(
Options
.
default_options
)
sources
=
[]
while
args
:
if
args
[
0
].
startswith
(
"-"
):
option
=
pop_arg
()
if
option
in
(
"-V"
,
"--version"
):
options
.
show_version
=
1
elif
option
in
(
"-l"
,
"--create-listing"
):
options
.
use_listing_file
=
1
elif
option
in
(
"-+"
,
"--cplus"
):
options
.
cplus
=
1
elif
option
==
"--embed"
:
Options
.
embed
=
pop_value
(
"main"
)
elif
option
.
startswith
(
"-I"
):
options
.
include_path
.
append
(
get_param
(
option
))
elif
option
==
"--include-dir"
:
options
.
include_path
.
append
(
pop_value
())
elif
option
in
(
"-w"
,
"--working"
):
options
.
working_path
=
pop_value
()
elif
option
in
(
"-o"
,
"--output-file"
):
options
.
output_file
=
pop_value
()
elif
option
in
(
"-t"
,
"--timestamps"
):
options
.
timestamps
=
1
elif
option
in
(
"-f"
,
"--force"
):
options
.
timestamps
=
0
elif
option
in
(
"-v"
,
"--verbose"
):
options
.
verbose
+=
1
elif
option
in
(
"-p"
,
"--embed-positions"
):
Options
.
embed_pos_in_docstring
=
1
elif
option
in
(
"-z"
,
"--pre-import"
):
Options
.
pre_import
=
pop_value
()
elif
option
==
"--cleanup"
:
Options
.
generate_cleanup_code
=
int
(
pop_value
())
elif
option
in
(
"-D"
,
"--no-docstrings"
):
Options
.
docstrings
=
False
elif
option
in
(
"-a"
,
"--annotate"
):
Options
.
annotate
=
"default"
elif
option
==
"--annotate-fullc"
:
Options
.
annotate
=
"fullc"
elif
option
==
"--annotate-coverage"
:
Options
.
annotate
=
True
Options
.
annotate_coverage_xml
=
pop_value
()
elif
option
==
"--convert-range"
:
Options
.
convert_range
=
True
elif
option
==
"--line-directives"
:
options
.
emit_linenums
=
True
elif
option
==
"--no-c-in-traceback"
:
options
.
c_line_in_traceback
=
False
elif
option
==
"--gdb"
:
options
.
gdb_debug
=
True
options
.
output_dir
=
os
.
curdir
elif
option
==
"--gdb-outdir"
:
options
.
gdb_debug
=
True
options
.
output_dir
=
pop_value
()
elif
option
==
"--lenient"
:
Options
.
error_on_unknown_names
=
False
Options
.
error_on_uninitialized
=
False
elif
option
==
'-2'
:
options
.
language_level
=
2
elif
option
==
'-3'
:
options
.
language_level
=
3
elif
option
==
'--3str'
:
options
.
language_level
=
'3str'
elif
option
==
"--capi-reexport-cincludes"
:
options
.
capi_reexport_cincludes
=
True
elif
option
==
"--fast-fail"
:
Options
.
fast_fail
=
True
elif
option
==
"--cimport-from-pyx"
:
Options
.
cimport_from_pyx
=
True
elif
option
in
(
'-Werror'
,
'--warning-errors'
):
Options
.
warning_errors
=
True
elif
option
in
(
'-Wextra'
,
'--warning-extra'
):
options
.
compiler_directives
.
update
(
Options
.
extra_warnings
)
elif
option
==
"--old-style-globals"
:
Options
.
old_style_globals
=
True
elif
option
==
"--directive"
or
option
.
startswith
(
'-X'
):
if
option
.
startswith
(
'-X'
)
and
option
[
2
:].
strip
():
x_args
=
option
[
2
:]
else
:
x_args
=
pop_value
()
try
:
options
.
compiler_directives
=
Options
.
parse_directive_list
(
x_args
,
relaxed_bool
=
True
,
current_settings
=
options
.
compiler_directives
)
except
ValueError
as
e
:
sys
.
stderr
.
write
(
"Error in compiler directive: %s
\
n
"
%
e
.
args
[
0
])
sys
.
exit
(
1
)
elif
option
==
"--compile-time-env"
or
option
.
startswith
(
'-E'
):
if
option
.
startswith
(
'-E'
)
and
option
[
2
:].
strip
():
x_args
=
option
[
2
:]
else
:
x_args
=
pop_value
()
try
:
options
.
compile_time_env
=
Options
.
parse_compile_time_env
(
x_args
,
current_settings
=
options
.
compile_time_env
)
except
ValueError
as
e
:
sys
.
stderr
.
write
(
"Error in compile-time-env: %s
\
n
"
%
e
.
args
[
0
])
sys
.
exit
(
1
)
elif
option
.
startswith
(
'--debug'
):
option
=
option
[
2
:].
replace
(
'-'
,
'_'
)
from
.
import
DebugFlags
if
option
in
dir
(
DebugFlags
):
setattr
(
DebugFlags
,
option
,
True
)
else
:
sys
.
stderr
.
write
(
"Unknown debug flag: %s
\
n
"
%
option
)
bad_usage
()
elif
option
in
(
'-h'
,
'--help'
):
sys
.
stdout
.
write
(
usage
)
sys
.
exit
(
0
)
for
name
,
value
in
vars
(
arguments
).
items
():
if
name
.
startswith
(
'debug'
):
from
.
import
DebugFlags
if
name
in
dir
(
DebugFlags
):
setattr
(
DebugFlags
,
name
,
value
)
else
:
sys
.
stderr
.
write
(
"Unknown compiler flag: %s
\
n
"
%
option
)
sys
.
exit
(
1
)
parser
.
error
(
"Unknown debug flag: %s
\
n
"
%
name
)
elif
hasattr
(
Options
,
name
):
setattr
(
Options
,
name
,
value
)
else
:
sources
.
append
(
pop_arg
())
if
pending_arg
:
bad_usage
()
setattr
(
options
,
name
,
value
)
if
options
.
use_listing_file
and
len
(
sources
)
>
1
:
sys
.
stderr
.
write
(
"cython: Only one source file allowed when using -o
\
n
"
)
sys
.
exit
(
1
)
parser
.
error
(
"cython: Only one source file allowed when using -o
\
n
"
)
if
len
(
sources
)
==
0
and
not
options
.
show_version
:
bad_usage
(
)
parser
.
error
(
"cython: Need at least one source file
\
n
"
)
if
Options
.
embed
and
len
(
sources
)
>
1
:
sys
.
stderr
.
write
(
"cython: Only one source file allowed when using -embed
\
n
"
)
sys
.
exit
(
1
)
parser
.
error
(
"cython: Only one source file allowed when using -embed
\
n
"
)
return
options
,
sources
Cython/Compiler/Tests/TestCmdLine.py
View file @
f019888c
import
os
import
sys
import
copy
from
unittest
import
TestCase
try
:
from
StringIO
import
StringIO
...
...
@@ -14,6 +15,9 @@ class CmdLineParserTest(TestCase):
def
setUp
(
self
):
backup
=
{}
for
name
,
value
in
vars
(
Options
).
items
():
# we need a deep copy of _directive_defaults, because they can be changed
if
name
==
'_directive_defaults'
:
value
=
copy
.
deepcopy
(
value
)
backup
[
name
]
=
value
self
.
_options_backup
=
backup
...
...
@@ -22,6 +26,23 @@ class CmdLineParserTest(TestCase):
for
name
,
orig_value
in
self
.
_options_backup
.
items
():
if
getattr
(
Options
,
name
,
no_value
)
!=
orig_value
:
setattr
(
Options
,
name
,
orig_value
)
# strip Options from new keys that might have been added:
for
name
in
vars
(
Options
).
keys
():
if
name
not
in
self
.
_options_backup
:
delattr
(
Options
,
name
)
def
check_default_global_options
(
self
,
white_list
=
[]):
no_value
=
object
()
for
name
,
orig_value
in
self
.
_options_backup
.
items
():
if
name
not
in
white_list
:
self
.
assertEqual
(
getattr
(
Options
,
name
,
no_value
),
orig_value
,
msg
=
"error in option "
+
name
)
def
check_default_options
(
self
,
options
,
white_list
=
[]):
default_options
=
Options
.
CompilationOptions
(
Options
.
default_options
)
no_value
=
object
()
for
name
in
default_options
.
__dict__
.
keys
():
if
name
not
in
white_list
:
self
.
assertEqual
(
getattr
(
options
,
name
,
no_value
),
getattr
(
default_options
,
name
),
msg
=
"error in option "
+
name
)
def
test_short_options
(
self
):
options
,
sources
=
parse_command_line
([
...
...
@@ -97,6 +118,31 @@ class CmdLineParserTest(TestCase):
self
.
assertEqual
(
Options
.
annotate_coverage_xml
,
'cov.xml'
)
self
.
assertTrue
(
options
.
gdb_debug
)
self
.
assertEqual
(
options
.
output_dir
,
'/gdb/outdir'
)
self
.
assertEqual
(
options
.
compiler_directives
[
'wraparound'
],
False
)
def
test_embed_before_positional
(
self
):
options
,
sources
=
parse_command_line
([
'--embed'
,
'source.pyx'
,
])
self
.
assertEqual
(
sources
,
[
'source.pyx'
])
self
.
assertEqual
(
Options
.
embed
,
'main'
)
def
test_two_embeds
(
self
):
options
,
sources
=
parse_command_line
([
'--embed'
,
'--embed=huhu'
,
'source.pyx'
,
])
self
.
assertEqual
(
sources
,
[
'source.pyx'
])
self
.
assertEqual
(
Options
.
embed
,
'huhu'
)
def
test_two_embeds2
(
self
):
options
,
sources
=
parse_command_line
([
'--embed=huhu'
,
'--embed'
,
'source.pyx'
,
])
self
.
assertEqual
(
sources
,
[
'source.pyx'
])
self
.
assertEqual
(
Options
.
embed
,
'main'
)
def
test_no_annotate
(
self
):
options
,
sources
=
parse_command_line
([
...
...
@@ -125,6 +171,345 @@ class CmdLineParserTest(TestCase):
])
self
.
assertEqual
(
Options
.
annotate
,
'fullc'
)
def
test_short_w
(
self
):
options
,
sources
=
parse_command_line
([
'-w'
,
'my_working_path'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
working_path
,
'my_working_path'
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'working_path'
])
def
test_short_o
(
self
):
options
,
sources
=
parse_command_line
([
'-o'
,
'my_output'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
output_file
,
'my_output'
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'output_file'
])
def
test_short_z
(
self
):
options
,
sources
=
parse_command_line
([
'-z'
,
'my_preimport'
,
'source.pyx'
])
self
.
assertEqual
(
Options
.
pre_import
,
'my_preimport'
)
self
.
check_default_global_options
([
'pre_import'
])
self
.
check_default_options
(
options
)
def
test_convert_range
(
self
):
options
,
sources
=
parse_command_line
([
'--convert-range'
,
'source.pyx'
])
self
.
assertEqual
(
Options
.
convert_range
,
True
)
self
.
check_default_global_options
([
'convert_range'
])
self
.
check_default_options
(
options
)
def
test_line_directives
(
self
):
options
,
sources
=
parse_command_line
([
'--line-directives'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
emit_linenums
,
True
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'emit_linenums'
])
def
test_no_c_in_traceback
(
self
):
options
,
sources
=
parse_command_line
([
'--no-c-in-traceback'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
c_line_in_traceback
,
False
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'c_line_in_traceback'
])
def
test_gdb
(
self
):
options
,
sources
=
parse_command_line
([
'--gdb'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
gdb_debug
,
True
)
self
.
assertEqual
(
options
.
output_dir
,
os
.
curdir
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'gdb_debug'
,
'output_dir'
])
def
test_3str
(
self
):
options
,
sources
=
parse_command_line
([
'--3str'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
language_level
,
'3str'
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'language_level'
])
def
test_capi_reexport_cincludes
(
self
):
options
,
sources
=
parse_command_line
([
'--capi-reexport-cincludes'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
capi_reexport_cincludes
,
True
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'capi_reexport_cincludes'
])
def
test_fast_fail
(
self
):
options
,
sources
=
parse_command_line
([
'--fast-fail'
,
'source.pyx'
])
self
.
assertEqual
(
Options
.
fast_fail
,
True
)
self
.
check_default_global_options
([
'fast_fail'
])
self
.
check_default_options
(
options
)
def
test_cimport_from_pyx
(
self
):
options
,
sources
=
parse_command_line
([
'--cimport-from-pyx'
,
'source.pyx'
])
self
.
assertEqual
(
Options
.
cimport_from_pyx
,
True
)
self
.
check_default_global_options
([
'cimport_from_pyx'
])
self
.
check_default_options
(
options
)
def
test_Werror
(
self
):
options
,
sources
=
parse_command_line
([
'-Werror'
,
'source.pyx'
])
self
.
assertEqual
(
Options
.
warning_errors
,
True
)
self
.
check_default_global_options
([
'warning_errors'
])
self
.
check_default_options
(
options
)
def
test_warning_errors
(
self
):
options
,
sources
=
parse_command_line
([
'--warning-errors'
,
'source.pyx'
])
self
.
assertEqual
(
Options
.
warning_errors
,
True
)
self
.
check_default_global_options
([
'warning_errors'
])
self
.
check_default_options
(
options
)
def
test_Wextra
(
self
):
options
,
sources
=
parse_command_line
([
'-Wextra'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compiler_directives
,
Options
.
extra_warnings
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compiler_directives'
])
def
test_warning_extra
(
self
):
options
,
sources
=
parse_command_line
([
'--warning-extra'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compiler_directives
,
Options
.
extra_warnings
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compiler_directives'
])
def
test_old_style_globals
(
self
):
options
,
sources
=
parse_command_line
([
'--old-style-globals'
,
'source.pyx'
])
self
.
assertEqual
(
Options
.
old_style_globals
,
True
)
self
.
check_default_global_options
([
'old_style_globals'
])
self
.
check_default_options
(
options
)
def
test_directive_multiple
(
self
):
options
,
source
=
parse_command_line
([
'-X'
,
'cdivision=True'
,
'-X'
,
'c_string_type=bytes'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compiler_directives
[
'cdivision'
],
True
)
self
.
assertEqual
(
options
.
compiler_directives
[
'c_string_type'
],
'bytes'
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compiler_directives'
])
def
test_directive_multiple_v2
(
self
):
options
,
source
=
parse_command_line
([
'-X'
,
'cdivision=True,c_string_type=bytes'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compiler_directives
[
'cdivision'
],
True
)
self
.
assertEqual
(
options
.
compiler_directives
[
'c_string_type'
],
'bytes'
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compiler_directives'
])
def
test_directive_value_yes
(
self
):
options
,
source
=
parse_command_line
([
'-X'
,
'cdivision=YeS'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compiler_directives
[
'cdivision'
],
True
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compiler_directives'
])
def
test_directive_value_no
(
self
):
options
,
source
=
parse_command_line
([
'-X'
,
'cdivision=no'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compiler_directives
[
'cdivision'
],
False
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compiler_directives'
])
def
test_directive_value_invalid
(
self
):
self
.
assertRaises
(
ValueError
,
parse_command_line
,
[
'-X'
,
'cdivision=sadfasd'
,
'source.pyx'
])
def
test_directive_key_invalid
(
self
):
self
.
assertRaises
(
ValueError
,
parse_command_line
,
[
'-X'
,
'abracadabra'
,
'source.pyx'
])
def
test_directive_no_value
(
self
):
self
.
assertRaises
(
ValueError
,
parse_command_line
,
[
'-X'
,
'cdivision'
,
'source.pyx'
])
def
test_compile_time_env_short
(
self
):
options
,
source
=
parse_command_line
([
'-E'
,
'MYSIZE=10'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compile_time_env
[
'MYSIZE'
],
10
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compile_time_env'
])
def
test_compile_time_env_long
(
self
):
options
,
source
=
parse_command_line
([
'--compile-time-env'
,
'MYSIZE=10'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compile_time_env
[
'MYSIZE'
],
10
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compile_time_env'
])
def
test_compile_time_env_multiple
(
self
):
options
,
source
=
parse_command_line
([
'-E'
,
'MYSIZE=10'
,
'-E'
,
'ARRSIZE=11'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compile_time_env
[
'MYSIZE'
],
10
)
self
.
assertEqual
(
options
.
compile_time_env
[
'ARRSIZE'
],
11
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compile_time_env'
])
def
test_compile_time_env_multiple_v2
(
self
):
options
,
source
=
parse_command_line
([
'-E'
,
'MYSIZE=10,ARRSIZE=11'
,
'source.pyx'
])
self
.
assertEqual
(
options
.
compile_time_env
[
'MYSIZE'
],
10
)
self
.
assertEqual
(
options
.
compile_time_env
[
'ARRSIZE'
],
11
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compile_time_env'
])
def
test_option_first
(
self
):
options
,
sources
=
parse_command_line
([
'-V'
,
'file.pyx'
])
self
.
assertEqual
(
sources
,
[
'file.pyx'
])
def
test_file_inbetween
(
self
):
options
,
sources
=
parse_command_line
([
'-V'
,
'file.pyx'
,
'-a'
])
self
.
assertEqual
(
sources
,
[
'file.pyx'
])
def
test_option_trailing
(
self
):
options
,
sources
=
parse_command_line
([
'file.pyx'
,
'-V'
])
self
.
assertEqual
(
sources
,
[
'file.pyx'
])
def
test_multiple_files
(
self
):
options
,
sources
=
parse_command_line
([
'file1.pyx'
,
'-V'
,
'file2.pyx'
,
'-a'
,
'file3.pyx'
])
self
.
assertEqual
(
sources
,
[
'file1.pyx'
,
'file2.pyx'
,
'file3.pyx'
])
def
test_debug_flags
(
self
):
options
,
sources
=
parse_command_line
([
'--debug-disposal-code'
,
'--debug-coercion'
,
'file3.pyx'
])
from
Cython.Compiler
import
DebugFlags
for
name
in
[
'debug_disposal_code'
,
'debug_temp_alloc'
,
'debug_coercion'
]:
self
.
assertEqual
(
getattr
(
DebugFlags
,
name
),
name
in
[
'debug_disposal_code'
,
'debug_coercion'
])
setattr
(
DebugFlags
,
name
,
0
)
# restore original value
def
test_gdb_overwrites_gdb_outdir
(
self
):
options
,
sources
=
parse_command_line
([
'--gdb-outdir=my_dir'
,
'--gdb'
,
'file3.pyx'
])
self
.
assertEqual
(
options
.
gdb_debug
,
True
)
self
.
assertEqual
(
options
.
output_dir
,
os
.
curdir
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'gdb_debug'
,
'output_dir'
])
def
test_gdb_first
(
self
):
options
,
sources
=
parse_command_line
([
'--gdb'
,
'--gdb-outdir=my_dir'
,
'file3.pyx'
])
self
.
assertEqual
(
options
.
gdb_debug
,
True
)
self
.
assertEqual
(
options
.
output_dir
,
'my_dir'
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'gdb_debug'
,
'output_dir'
])
def
test_coverage_overwrites_annotation
(
self
):
options
,
sources
=
parse_command_line
([
'--annotate-fullc'
,
'--annotate-coverage=my.xml'
,
'file3.pyx'
])
self
.
assertEqual
(
Options
.
annotate
,
True
)
self
.
assertEqual
(
Options
.
annotate_coverage_xml
,
'my.xml'
)
self
.
check_default_global_options
([
'annotate'
,
'annotate_coverage_xml'
])
self
.
check_default_options
(
options
)
def
test_coverage_first
(
self
):
options
,
sources
=
parse_command_line
([
'--annotate-coverage=my.xml'
,
'--annotate-fullc'
,
'file3.pyx'
])
self
.
assertEqual
(
Options
.
annotate
,
'fullc'
)
self
.
assertEqual
(
Options
.
annotate_coverage_xml
,
'my.xml'
)
self
.
check_default_global_options
([
'annotate'
,
'annotate_coverage_xml'
])
self
.
check_default_options
(
options
)
def
test_annotate_first_fullc_second
(
self
):
options
,
sources
=
parse_command_line
([
'--annotate'
,
'--annotate-fullc'
,
'file3.pyx'
])
self
.
assertEqual
(
Options
.
annotate
,
'fullc'
)
self
.
check_default_global_options
([
'annotate'
])
self
.
check_default_options
(
options
)
def
test_annotate_fullc_first
(
self
):
options
,
sources
=
parse_command_line
([
'--annotate-fullc'
,
'--annotate'
,
'file3.pyx'
])
self
.
assertEqual
(
Options
.
annotate
,
'default'
)
self
.
check_default_global_options
([
'annotate'
])
self
.
check_default_options
(
options
)
def
test_warning_extra_dont_overwrite
(
self
):
options
,
sources
=
parse_command_line
([
'-X'
,
'cdivision=True'
,
'--warning-extra'
,
'-X'
,
'c_string_type=bytes'
,
'source.pyx'
])
self
.
assertTrue
(
len
(
options
.
compiler_directives
),
len
(
Options
.
extra_warnings
)
+
1
)
self
.
check_default_global_options
()
self
.
check_default_options
(
options
,
[
'compiler_directives'
])
def
test_errors
(
self
):
def
error
(
*
args
):
old_stderr
=
sys
.
stderr
...
...
@@ -143,3 +528,4 @@ class CmdLineParserTest(TestCase):
error
(
'--verbose=1'
)
error
(
'--verbose=1'
)
error
(
'--cleanup'
)
error
(
'--debug-disposal-code-wrong-name'
,
'file3.pyx'
)
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