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
Kirill Smelkov
cython
Commits
2bb984a4
Commit
2bb984a4
authored
Sep 16, 2018
by
scoder
Committed by
GitHub
Sep 16, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2608 from scoder/warn_missing_language_level
Warn when no "language_level" is specified.
parents
e59d4dcf
286abf81
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
51 additions
and
16 deletions
+51
-16
CHANGES.rst
CHANGES.rst
+11
-0
Cython/Build/Inline.py
Cython/Build/Inline.py
+8
-3
Cython/Compiler/Main.py
Cython/Compiler/Main.py
+10
-5
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+2
-1
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+11
-0
Cython/Compiler/Scanning.py
Cython/Compiler/Scanning.py
+2
-2
Cython/Compiler/TreeFragment.py
Cython/Compiler/TreeFragment.py
+2
-1
runtests.py
runtests.py
+2
-2
setup.py
setup.py
+2
-1
tests/run/test_coroutines_pep492.pyx
tests/run/test_coroutines_pep492.pyx
+1
-1
No files found.
CHANGES.rst
View file @
2bb984a4
...
@@ -26,6 +26,9 @@ Features added
...
@@ -26,6 +26,9 @@ Features added
* ``@cython.nogil`` is supported as a C-function decorator in Python code.
* ``@cython.nogil`` is supported as a C-function decorator in Python code.
(Github issue #2557)
(Github issue #2557)
* ``cython.inline()`` supports a direct ``language_level`` keyword argument that
was previously only available via a directive.
* In CPython 3.6 and later, looking up globals in the module dict is almost
* In CPython 3.6 and later, looking up globals in the module dict is almost
as fast as looking up C globals.
as fast as looking up C globals.
(Github issue #2313)
(Github issue #2313)
...
@@ -114,6 +117,14 @@ Bugs fixed
...
@@ -114,6 +117,14 @@ Bugs fixed
Other changes
Other changes
-------------
-------------
* Cython now emits a warning when no ``language_level`` (2 or 3) is set explicitly,
neither as a ``cythonize()`` option nor as a compiler directive. This is meant
to prepare the transition of the default language level from currently Py2
to Py3, since that is what most new users will expect these days. The next
major release is intended to make that change, so that it will parse all code
that does not request a specific language level as Python 3 code. The language
level 2 will continue to be supported for an indefinite time.
* The documentation was restructured, cleaned up and examples are now tested.
* The documentation was restructured, cleaned up and examples are now tested.
The NumPy tutorial was also rewritten to simplify the running example.
The NumPy tutorial was also rewritten to simplify the running example.
Contributed by Gabriel de Marmiesse. (Github issue #2245)
Contributed by Gabriel de Marmiesse. (Github issue #2245)
...
...
Cython/Build/Inline.py
View file @
2bb984a4
...
@@ -139,7 +139,7 @@ def _populate_unbound(kwds, unbound_symbols, locals=None, globals=None):
...
@@ -139,7 +139,7 @@ def _populate_unbound(kwds, unbound_symbols, locals=None, globals=None):
def
cython_inline
(
code
,
get_type
=
unsafe_type
,
def
cython_inline
(
code
,
get_type
=
unsafe_type
,
lib_dir
=
os
.
path
.
join
(
get_cython_cache_dir
(),
'inline'
),
lib_dir
=
os
.
path
.
join
(
get_cython_cache_dir
(),
'inline'
),
cython_include_dirs
=
None
,
cython_compiler_directives
=
None
,
cython_include_dirs
=
None
,
cython_compiler_directives
=
None
,
force
=
False
,
quiet
=
False
,
locals
=
None
,
globals
=
None
,
**
kwds
):
force
=
False
,
quiet
=
False
,
locals
=
None
,
globals
=
None
,
language_level
=
None
,
**
kwds
):
if
get_type
is
None
:
if
get_type
is
None
:
get_type
=
lambda
x
:
'object'
get_type
=
lambda
x
:
'object'
...
@@ -171,6 +171,11 @@ def cython_inline(code, get_type=unsafe_type,
...
@@ -171,6 +171,11 @@ def cython_inline(code, get_type=unsafe_type,
if
not
quiet
:
if
not
quiet
:
# Parsing from strings not fully supported (e.g. cimports).
# Parsing from strings not fully supported (e.g. cimports).
print
(
"Could not parse code as a string (to extract unbound symbols)."
)
print
(
"Could not parse code as a string (to extract unbound symbols)."
)
cython_compiler_directives
=
dict
(
cython_compiler_directives
or
{})
if
language_level
is
not
None
:
cython_compiler_directives
[
'language_level'
]
=
language_level
cimports
=
[]
cimports
=
[]
for
name
,
arg
in
list
(
kwds
.
items
()):
for
name
,
arg
in
list
(
kwds
.
items
()):
if
arg
is
cython_module
:
if
arg
is
cython_module
:
...
@@ -178,7 +183,7 @@ def cython_inline(code, get_type=unsafe_type,
...
@@ -178,7 +183,7 @@ def cython_inline(code, get_type=unsafe_type,
del
kwds
[
name
]
del
kwds
[
name
]
arg_names
=
sorted
(
kwds
)
arg_names
=
sorted
(
kwds
)
arg_sigs
=
tuple
([(
get_type
(
kwds
[
arg
],
ctx
),
arg
)
for
arg
in
arg_names
])
arg_sigs
=
tuple
([(
get_type
(
kwds
[
arg
],
ctx
),
arg
)
for
arg
in
arg_names
])
key
=
orig_code
,
arg_sigs
,
sys
.
version_info
,
sys
.
executable
,
Cython
.
__version__
key
=
orig_code
,
arg_sigs
,
sys
.
version_info
,
sys
.
executable
,
language_level
,
Cython
.
__version__
module_name
=
"_cython_inline_"
+
hashlib
.
md5
(
_unicode
(
key
).
encode
(
'utf-8'
)).
hexdigest
()
module_name
=
"_cython_inline_"
+
hashlib
.
md5
(
_unicode
(
key
).
encode
(
'utf-8'
)).
hexdigest
()
if
module_name
in
sys
.
modules
:
if
module_name
in
sys
.
modules
:
...
@@ -238,7 +243,7 @@ def __invoke(%(params)s):
...
@@ -238,7 +243,7 @@ def __invoke(%(params)s):
build_extension.extensions = cythonize(
build_extension.extensions = cythonize(
[extension],
[extension],
include_path=cython_include_dirs or ['
.
'],
include_path=cython_include_dirs or ['
.
'],
compiler_directives=cython_compiler_directives
or {}
,
compiler_directives=cython_compiler_directives,
quiet=quiet)
quiet=quiet)
build_extension.build_temp = os.path.dirname(pyx_file)
build_extension.build_temp = os.path.dirname(pyx_file)
build_extension.build_lib = lib_dir
build_extension.build_lib = lib_dir
...
...
Cython/Compiler/Main.py
View file @
2bb984a4
...
@@ -67,9 +67,10 @@ class Context(object):
...
@@ -67,9 +67,10 @@ class Context(object):
# language_level int currently 2 or 3 for Python 2/3
# language_level int currently 2 or 3 for Python 2/3
cython_scope
=
None
cython_scope
=
None
language_level
=
None
# warn when not set but default to Py2
def
__init__
(
self
,
include_directories
,
compiler_directives
,
cpp
=
False
,
def
__init__
(
self
,
include_directories
,
compiler_directives
,
cpp
=
False
,
language_level
=
2
,
options
=
None
):
language_level
=
None
,
options
=
None
):
# cython_scope is a hack, set to False by subclasses, in order to break
# cython_scope is a hack, set to False by subclasses, in order to break
# an infinite loop.
# an infinite loop.
# Better code organization would fix it.
# Better code organization would fix it.
...
@@ -91,7 +92,8 @@ class Context(object):
...
@@ -91,7 +92,8 @@ class Context(object):
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
os
.
path
.
pardir
,
'Includes'
)))
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
os
.
path
.
pardir
,
'Includes'
)))
self
.
include_directories
=
include_directories
+
[
standard_include_path
]
self
.
include_directories
=
include_directories
+
[
standard_include_path
]
self
.
set_language_level
(
language_level
)
if
language_level
is
not
None
:
self
.
set_language_level
(
language_level
)
self
.
gdb_debug_outputwriter
=
None
self
.
gdb_debug_outputwriter
=
None
...
@@ -548,9 +550,10 @@ class CompilationOptions(object):
...
@@ -548,9 +550,10 @@ class CompilationOptions(object):
', '
.
join
(
unknown_options
))
', '
.
join
(
unknown_options
))
raise
ValueError
(
message
)
raise
ValueError
(
message
)
directive_defaults
=
Options
.
get_directive_defaults
()
directives
=
dict
(
options
[
'compiler_directives'
])
# copy mutable field
directives
=
dict
(
options
[
'compiler_directives'
])
# copy mutable field
# check for invalid directives
# check for invalid directives
unknown_directives
=
set
(
directives
)
-
set
(
Options
.
get_directive_defaults
()
)
unknown_directives
=
set
(
directives
)
-
set
(
directive_defaults
)
if
unknown_directives
:
if
unknown_directives
:
message
=
"got unknown compiler directive%s: %s"
%
(
message
=
"got unknown compiler directive%s: %s"
%
(
's'
if
len
(
unknown_directives
)
>
1
else
''
,
's'
if
len
(
unknown_directives
)
>
1
else
''
,
...
@@ -562,7 +565,9 @@ class CompilationOptions(object):
...
@@ -562,7 +565,9 @@ class CompilationOptions(object):
warnings
.
warn
(
"C++ mode forced when in Pythran mode!"
)
warnings
.
warn
(
"C++ mode forced when in Pythran mode!"
)
options
[
'cplus'
]
=
True
options
[
'cplus'
]
=
True
if
'language_level'
in
directives
and
'language_level'
not
in
kw
:
if
'language_level'
in
directives
and
'language_level'
not
in
kw
:
options
[
'language_level'
]
=
int
(
directives
[
'language_level'
])
options
[
'language_level'
]
=
directives
[
'language_level'
]
elif
not
options
.
get
(
'language_level'
):
options
[
'language_level'
]
=
directive_defaults
.
get
(
'language_level'
)
if
'formal_grammar'
in
directives
and
'formal_grammar'
not
in
kw
:
if
'formal_grammar'
in
directives
and
'formal_grammar'
not
in
kw
:
options
[
'formal_grammar'
]
=
directives
[
'formal_grammar'
]
options
[
'formal_grammar'
]
=
directives
[
'formal_grammar'
]
if
options
[
'cache'
]
is
True
:
if
options
[
'cache'
]
is
True
:
...
@@ -824,7 +829,7 @@ default_options = dict(
...
@@ -824,7 +829,7 @@ default_options = dict(
emit_linenums
=
False
,
emit_linenums
=
False
,
relative_path_in_code_position_comments
=
True
,
relative_path_in_code_position_comments
=
True
,
c_line_in_traceback
=
True
,
c_line_in_traceback
=
True
,
language_level
=
2
,
language_level
=
None
,
# warn but default to 2
formal_grammar
=
False
,
formal_grammar
=
False
,
gdb_debug
=
False
,
gdb_debug
=
False
,
compile_time_env
=
None
,
compile_time_env
=
None
,
...
...
Cython/Compiler/Options.py
View file @
2bb984a4
...
@@ -197,7 +197,7 @@ _directive_defaults = {
...
@@ -197,7 +197,7 @@ _directive_defaults = {
'autotestdict'
:
True
,
'autotestdict'
:
True
,
'autotestdict.cdef'
:
False
,
'autotestdict.cdef'
:
False
,
'autotestdict.all'
:
False
,
'autotestdict.all'
:
False
,
'language_level'
:
2
,
'language_level'
:
None
,
'fast_getattr'
:
False
,
# Undocumented until we come up with a better way to handle this everywhere.
'fast_getattr'
:
False
,
# Undocumented until we come up with a better way to handle this everywhere.
'py2_import'
:
False
,
# For backward compatibility of Cython's source code in Py3 source mode
'py2_import'
:
False
,
# For backward compatibility of Cython's source code in Py3 source mode
'preliminary_late_includes_cy28'
:
False
,
# Temporary directive in 0.28, to be removed in a later version (see GH#2079).
'preliminary_late_includes_cy28'
:
False
,
# Temporary directive in 0.28, to be removed in a later version (see GH#2079).
...
@@ -299,6 +299,7 @@ def normalise_encoding_name(option_name, encoding):
...
@@ -299,6 +299,7 @@ def normalise_encoding_name(option_name, encoding):
# Override types possibilities above, if needed
# Override types possibilities above, if needed
directive_types
=
{
directive_types
=
{
'language_level'
:
int
,
# values can be None/2/3, where None == 2+warning
'auto_pickle'
:
bool
,
'auto_pickle'
:
bool
,
'final'
:
bool
,
# final cdef classes and methods
'final'
:
bool
,
# final cdef classes and methods
'internal'
:
bool
,
# cdef class visibility in the module dict
'internal'
:
bool
,
# cdef class visibility in the module dict
...
...
Cython/Compiler/Parsing.py
View file @
2bb984a4
...
@@ -3662,6 +3662,17 @@ def p_module(s, pxd, full_module_name, ctx=Ctx):
...
@@ -3662,6 +3662,17 @@ def p_module(s, pxd, full_module_name, ctx=Ctx):
directive_comments
=
p_compiler_directive_comments
(
s
)
directive_comments
=
p_compiler_directive_comments
(
s
)
s
.
parse_comments
=
False
s
.
parse_comments
=
False
if
s
.
context
.
language_level
is
None
:
s
.
context
.
set_language_level
(
2
)
if
pos
[
0
].
filename
:
import
warnings
warnings
.
warn
(
"Cython directive 'language_level' not set, using 2 for now (Py2). "
"This will change in a later release! File: %s"
%
pos
[
0
].
filename
,
FutureWarning
,
stacklevel
=
1
if
cython
.
compiled
else
2
,
)
doc
=
p_doc_string
(
s
)
doc
=
p_doc_string
(
s
)
if
pxd
:
if
pxd
:
level
=
'module_pxd'
level
=
'module_pxd'
...
...
Cython/Compiler/Scanning.py
View file @
2bb984a4
...
@@ -147,6 +147,8 @@ class SourceDescriptor(object):
...
@@ -147,6 +147,8 @@ class SourceDescriptor(object):
"""
"""
A SourceDescriptor should be considered immutable.
A SourceDescriptor should be considered immutable.
"""
"""
filename
=
None
_file_type
=
'pyx'
_file_type
=
'pyx'
_escaped_description
=
None
_escaped_description
=
None
...
@@ -274,8 +276,6 @@ class StringSourceDescriptor(SourceDescriptor):
...
@@ -274,8 +276,6 @@ class StringSourceDescriptor(SourceDescriptor):
Instances of this class can be used instead of a filenames if the
Instances of this class can be used instead of a filenames if the
code originates from a string object.
code originates from a string object.
"""
"""
filename
=
None
def
__init__
(
self
,
name
,
code
):
def
__init__
(
self
,
name
,
code
):
self
.
name
=
name
self
.
name
=
name
#self.set_file_type_from_name(name)
#self.set_file_type_from_name(name)
...
...
Cython/Compiler/TreeFragment.py
View file @
2bb984a4
...
@@ -29,7 +29,8 @@ class StringParseContext(Main.Context):
...
@@ -29,7 +29,8 @@ class StringParseContext(Main.Context):
include_directories
=
[]
include_directories
=
[]
if
compiler_directives
is
None
:
if
compiler_directives
is
None
:
compiler_directives
=
{}
compiler_directives
=
{}
Main
.
Context
.
__init__
(
self
,
include_directories
,
compiler_directives
,
cpp
=
cpp
)
# TODO: see if "language_level=3" also works for our internal code here.
Main
.
Context
.
__init__
(
self
,
include_directories
,
compiler_directives
,
cpp
=
cpp
,
language_level
=
2
)
self
.
module_name
=
name
self
.
module_name
=
name
def
find_module
(
self
,
module_name
,
relative_to
=
None
,
pos
=
None
,
need_pxd
=
1
,
absolute_fallback
=
True
):
def
find_module
(
self
,
module_name
,
relative_to
=
None
,
pos
=
None
,
need_pxd
=
1
,
absolute_fallback
=
True
):
...
...
runtests.py
View file @
2bb984a4
...
@@ -2295,8 +2295,8 @@ def runtests(options, cmd_args, coverage=None):
...
@@ -2295,8 +2295,8 @@ def runtests(options, cmd_args, coverage=None):
sys.stderr.write("Disabling forked testing to support XML test output
\
n
")
sys.stderr.write("Disabling forked testing to support XML test output
\
n
")
options.fork = False
options.fork = False
if WITH_CYTHON
and options.language_level == 3
:
if WITH_CYTHON:
sys.stderr.write("Using Cython language level
3.
\
n
"
)
sys.stderr.write("Using Cython language level
%d.
\
n
" % options.language_level
)
test_bugs = False
test_bugs = False
if options.tickets:
if options.tickets:
...
...
setup.py
View file @
2bb984a4
...
@@ -156,8 +156,9 @@ def compile_cython_modules(profile=False, compile_more=False, cython_with_refnan
...
@@ -156,8 +156,9 @@ def compile_cython_modules(profile=False, compile_more=False, cython_with_refnan
extensions
[
-
1
].
sources
[
0
]
=
pyx_source_file
extensions
[
-
1
].
sources
[
0
]
=
pyx_source_file
from
Cython.Distutils.build_ext
import
new_build_ext
from
Cython.Distutils.build_ext
import
new_build_ext
from
Cython.Compiler.Options
import
get_directive_defaults
get_directive_defaults
()[
'language_level'
]
=
2
if
profile
:
if
profile
:
from
Cython.Compiler.Options
import
get_directive_defaults
get_directive_defaults
()[
'profile'
]
=
True
get_directive_defaults
()[
'profile'
]
=
True
sys
.
stderr
.
write
(
"Enabled profiling for the Cython binary modules
\
n
"
)
sys
.
stderr
.
write
(
"Enabled profiling for the Cython binary modules
\
n
"
)
...
...
tests/run/test_coroutines_pep492.pyx
View file @
2bb984a4
...
@@ -76,7 +76,7 @@ def exec(code_string, l, g):
...
@@ -76,7 +76,7 @@ def exec(code_string, l, g):
old_stderr
=
sys
.
stderr
old_stderr
=
sys
.
stderr
try
:
try
:
sys
.
stderr
=
StringIO
()
sys
.
stderr
=
StringIO
()
ns
=
inline
(
code_string
,
locals
=
l
,
globals
=
g
,
lib_dir
=
os
.
path
.
dirname
(
__file__
))
ns
=
inline
(
code_string
,
locals
=
l
,
globals
=
g
,
lib_dir
=
os
.
path
.
dirname
(
__file__
)
,
language_level
=
3
)
finally
:
finally
:
sys
.
stderr
=
old_stderr
sys
.
stderr
=
old_stderr
g
.
update
(
ns
)
g
.
update
(
ns
)
...
...
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