Commit c8e6f375 authored by Stefan Behnel's avatar Stefan Behnel

Warn when no "language_level" is specified to prepare the transition to language_level=3.

Closes #2593.
parent e59d4dcf
......@@ -67,9 +67,10 @@ class Context(object):
# language_level int currently 2 or 3 for Python 2/3
cython_scope = None
language_level = None # warn when not set but default to Py2
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
# an infinite loop.
# Better code organization would fix it.
......@@ -91,7 +92,8 @@ class Context(object):
os.path.join(os.path.dirname(__file__), os.path.pardir, 'Includes')))
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
......@@ -548,9 +550,10 @@ class CompilationOptions(object):
', '.join(unknown_options))
raise ValueError(message)
directive_defaults = Options.get_directive_defaults()
directives = dict(options['compiler_directives']) # copy mutable field
# check for invalid directives
unknown_directives = set(directives) - set(Options.get_directive_defaults())
unknown_directives = set(directives) - set(directive_defaults)
if unknown_directives:
message = "got unknown compiler directive%s: %s" % (
's' if len(unknown_directives) > 1 else '',
......@@ -562,7 +565,9 @@ class CompilationOptions(object):
warnings.warn("C++ mode forced when in Pythran mode!")
options['cplus'] = True
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:
options['formal_grammar'] = directives['formal_grammar']
if options['cache'] is True:
......@@ -824,7 +829,7 @@ default_options = dict(
emit_linenums = False,
relative_path_in_code_position_comments = True,
c_line_in_traceback = True,
language_level = 2,
language_level = None, # warn but default to 2
formal_grammar = False,
gdb_debug = False,
compile_time_env = None,
......
......@@ -197,7 +197,7 @@ _directive_defaults = {
'autotestdict': True,
'autotestdict.cdef': 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.
'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).
......@@ -299,6 +299,7 @@ def normalise_encoding_name(option_name, encoding):
# Override types possibilities above, if needed
directive_types = {
'language_level': int, # values can be None/2/3, where None == 2+warning
'auto_pickle': bool,
'final' : bool, # final cdef classes and methods
'internal' : bool, # cdef class visibility in the module dict
......
......@@ -3662,6 +3662,17 @@ def p_module(s, pxd, full_module_name, ctx=Ctx):
directive_comments = p_compiler_directive_comments(s)
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)
if pxd:
level = 'module_pxd'
......
......@@ -147,6 +147,8 @@ class SourceDescriptor(object):
"""
A SourceDescriptor should be considered immutable.
"""
filename = None
_file_type = 'pyx'
_escaped_description = None
......@@ -274,8 +276,6 @@ class StringSourceDescriptor(SourceDescriptor):
Instances of this class can be used instead of a filenames if the
code originates from a string object.
"""
filename = None
def __init__(self, name, code):
self.name = name
#self.set_file_type_from_name(name)
......
......@@ -29,7 +29,8 @@ class StringParseContext(Main.Context):
include_directories = []
if compiler_directives is None:
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
def find_module(self, module_name, relative_to=None, pos=None, need_pxd=1, absolute_fallback=True):
......
......@@ -2295,8 +2295,8 @@ def runtests(options, cmd_args, coverage=None):
sys.stderr.write("Disabling forked testing to support XML test output\n")
options.fork = False
if WITH_CYTHON and options.language_level == 3:
sys.stderr.write("Using Cython language level 3.\n")
if WITH_CYTHON:
sys.stderr.write("Using Cython language level %d.\n" % options.language_level)
test_bugs = False
if options.tickets:
......
......@@ -156,8 +156,9 @@ def compile_cython_modules(profile=False, compile_more=False, cython_with_refnan
extensions[-1].sources[0] = pyx_source_file
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:
from Cython.Compiler.Options import get_directive_defaults
get_directive_defaults()['profile'] = True
sys.stderr.write("Enabled profiling for the Cython binary modules\n")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment