Skip to content

Commit

Permalink
Add --module-name argument to cython command
Browse files Browse the repository at this point in the history
It can be useful to specify the module name for the output file
directly, rather than working it out from the enclosing file tree -
particularly for out of tree build systems, like Meson.

See: rgommers/scipy#31 (comment)
for background.
  • Loading branch information
matthew-brett committed Jan 8, 2022
1 parent ddaaa7b commit 15fa7e2
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
16 changes: 15 additions & 1 deletion Cython/Compiler/CmdLine.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ def create_cython_argparser():
dest='compile_time_env', type=str,
action=ParseCompileTimeEnvAction,
help='Provides compile time env like DEF would do.')
parser.add_argument("--module-name",
dest='module_name', type=str, action='store',
help='Fully qualified module name. If not given, is '
'deduced from the import path if source file is in '
'a package, or equals the filename otherwise.')
parser.add_argument('sources', nargs='*', default=[])

# TODO: add help
Expand Down Expand Up @@ -222,5 +227,14 @@ def parse_command_line(args):
if len(sources) == 0 and not options.show_version:
parser.error("cython: Need at least one source file\n")
if Options.embed and len(sources) > 1:
parser.error("cython: Only one source file allowed when using -embed\n")
parser.error(
"cython: Only one source file allowed when using --embed\n")
if options.module_name:
if options.timestamps:
parser.error(
"cython: Cannot use --module-name with --timestamps\n")
if len(sources) > 1:
parser.error(
"cython: Only one source file allowed when using "
"--module-name\n")
return options, sources
8 changes: 6 additions & 2 deletions Cython/Compiler/Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,9 @@ def compile_multiple(sources, options):
a CompilationResultSet. Performs timestamp checking and/or recursion
if these are specified in the options.
"""
if len(sources) > 1 and options.module_name:
raise RuntimeError('Full module name can only be set '
'for single source compilation')
# run_pipeline creates the context
# context = Context.from_options(options)
sources = [os.path.abspath(source) for source in sources]
Expand All @@ -602,8 +605,9 @@ def compile_multiple(sources, options):
if (not timestamps) or out_of_date:
if verbose:
sys.stderr.write("Compiling %s\n" % source)

result = run_pipeline(source, options, context=context)
result = run_pipeline(source, options,
full_module_name=options.module_name,
context=context)
results.add(source, result)
# Compiling multiple sources in one context doesn't quite
# work properly yet.
Expand Down
1 change: 1 addition & 0 deletions Cython/Compiler/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ def to_fingerprint(item):
formal_grammar=False,
gdb_debug=False,
compile_time_env=None,
module_name=None,
common_utility_include_dir=None,
output_dir=None,
build_dir=None,
Expand Down
22 changes: 21 additions & 1 deletion Cython/Compiler/Tests/TestCmdLine.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,21 @@ def test_warning_extra_dont_overwrite(self):
self.check_default_global_options()
self.check_default_options(options, ['compiler_directives'])

def test_module_name(self):
options, sources = parse_command_line([
'source.pyx'
])
self.assertEqual(options.module_name, None)
self.check_default_global_options()
self.check_default_options(options)
options, sources = parse_command_line([
'--module-name', 'foo.bar',
'source.pyx'
])
self.assertEqual(options.module_name, 'foo.bar')
self.check_default_global_options()
self.check_default_options(options, ['module_name'])

def test_errors(self):
def error(*args):
old_stderr = sys.stderr
Expand All @@ -505,7 +520,6 @@ def error(*args):
sys.stderr = old_stderr
self.assertTrue(stderr.getvalue())

error('-1')
error('-I')
error('--version=-a')
error('--version=--annotate=true')
Expand All @@ -514,3 +528,9 @@ def error(*args):
error('--verbose=1')
error('--cleanup')
error('--debug-disposal-code-wrong-name', 'file3.pyx')
# No source file (source file appears to be module name).
error('--module-name', 'foo.pyx')
# Cannot use --module-name with more than one source file.
error('--module-name', 'foo.bar', 'foo.pyx', 'bar.pyx')
# Cannot use --module-name with --timestamps
error('--module-name', 'foo.bar', '--timestamps', 'foo.pyx')

0 comments on commit 15fa7e2

Please sign in to comment.