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): ...@@ -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,
......
...@@ -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
......
...@@ -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'
......
...@@ -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)
......
...@@ -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):
......
...@@ -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:
......
...@@ -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")
......
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