Commit 13fb1f4a authored by Stefan Behnel's avatar Stefan Behnel Committed by GitHub

Merge pull request #2635 from cython/cy3str

Add new "language_level=3str"
parents df1b2449 7f638bcb
...@@ -34,10 +34,12 @@ Features added ...@@ -34,10 +34,12 @@ Features added
* ``cython.inline()`` supports a direct ``language_level`` keyword argument that * ``cython.inline()`` supports a direct ``language_level`` keyword argument that
was previously only available via a directive. was previously only available via a directive.
* A new directive ``str_is_str=True`` was added that keeps unprefixed string * A new language level name ``3str`` was added that mostly corresponds to language
literals as type 'str' in both Py2 and Py3, and the builtin 'str' type unchanged level 3, but keeps unprefixed string literals as type 'str' in both Py2 and Py3,
even when ``language_level=3`` is enabled. This is meant to help user code to and the builtin 'str' type unchanged. This will become the default in the next
migrate to Python 3 semantics without making support for Python 2.x difficult. Cython release and is meant to help user code a) transition more easily to this
new default and b) migrate to Python 3 source code semantics without making support
for Python 2.x difficult.
* 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.
...@@ -162,10 +164,13 @@ Other changes ...@@ -162,10 +164,13 @@ Other changes
* Cython now emits a warning when no ``language_level`` (2 or 3) is set explicitly, * 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 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 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 to Py3, since that is what most new users will expect these days. The future
major release is intended to make that change, so that it will parse all code default will, however, not enforce unicode literals, because this has proven a
that does not request a specific language level as Python 3 code. The language major obstacle in the support for both Python 2.x and 3.x. The next major
level 2 will continue to be supported for an indefinite time. release is intended to make this change, so that it will parse all code that
does not request a specific language level as Python 3 code, but with ``str``
literals. 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.
......
...@@ -94,23 +94,24 @@ class Context(object): ...@@ -94,23 +94,24 @@ class Context(object):
if language_level is not None: if language_level is not None:
self.set_language_level(language_level) self.set_language_level(language_level)
if self.compiler_directives.get('str_is_str') is not None:
self.set_str_is_str(self.compiler_directives['str_is_str'])
self.gdb_debug_outputwriter = None self.gdb_debug_outputwriter = None
def set_str_is_str(self, str_is_str): def set_language_level(self, level):
from .Future import unicode_literals from .Future import print_function, unicode_literals, absolute_import, division
if str_is_str: future_directives = []
if level == '3str':
future_directives = [print_function, absolute_import, division]
self.future_directives.discard(unicode_literals) self.future_directives.discard(unicode_literals)
level = 3
else: else:
self.future_directives.add(unicode_literals) level = int(level)
if level >= 3:
def set_language_level(self, level): future_directives = [print_function, unicode_literals, absolute_import, division]
self.language_level = level self.language_level = level
if future_directives:
self.future_directives.update(future_directives)
if level >= 3: if level >= 3:
from .Future import print_function, unicode_literals, absolute_import, division
self.future_directives.update([print_function, unicode_literals, absolute_import, division])
self.modules['builtins'] = self.modules['__builtin__'] self.modules['builtins'] = self.modules['__builtin__']
def intern_ustring(self, value, encoding=None): def intern_ustring(self, value, encoding=None):
......
...@@ -198,7 +198,6 @@ _directive_defaults = { ...@@ -198,7 +198,6 @@ _directive_defaults = {
'iterable_coroutine': False, # Make async coroutines backwards compatible with the old asyncio yield-from syntax. 'iterable_coroutine': False, # Make async coroutines backwards compatible with the old asyncio yield-from syntax.
'c_string_type': 'bytes', 'c_string_type': 'bytes',
'c_string_encoding': '', 'c_string_encoding': '',
'str_is_str': None, # fall back to 'language_level == 2'
'type_version_tag': True, # enables Py_TPFLAGS_HAVE_VERSION_TAG on extension types 'type_version_tag': True, # enables Py_TPFLAGS_HAVE_VERSION_TAG on extension types
'unraisable_tracebacks': True, 'unraisable_tracebacks': True,
'old_style_globals': False, 'old_style_globals': False,
...@@ -293,7 +292,7 @@ def normalise_encoding_name(option_name, encoding): ...@@ -293,7 +292,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 'language_level': str, # values can be None/2/3/'3str', where None == 2+warning
'auto_pickle': bool, 'auto_pickle': bool,
'locals': dict, 'locals': dict,
'final' : bool, # final cdef classes and methods 'final' : bool, # final cdef classes and methods
...@@ -314,7 +313,6 @@ directive_types = { ...@@ -314,7 +313,6 @@ directive_types = {
'freelist': int, 'freelist': int,
'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'), 'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'),
'c_string_encoding': normalise_encoding_name, 'c_string_encoding': normalise_encoding_name,
'str_is_str': bool,
} }
for key, val in _directive_defaults.items(): for key, val in _directive_defaults.items():
...@@ -349,7 +347,6 @@ directive_scopes = { # defaults to available everywhere ...@@ -349,7 +347,6 @@ directive_scopes = { # defaults to available everywhere
# Avoid scope-specific to/from_py_functions for c_string. # Avoid scope-specific to/from_py_functions for c_string.
'c_string_type': ('module',), 'c_string_type': ('module',),
'c_string_encoding': ('module',), 'c_string_encoding': ('module',),
'str_is_str': ('module',),
'type_version_tag': ('module', 'cclass'), 'type_version_tag': ('module', 'cclass'),
'language_level': ('module',), 'language_level': ('module',),
# globals() could conceivably be controlled at a finer granularity, # globals() could conceivably be controlled at a finer granularity,
......
...@@ -3669,9 +3669,6 @@ def p_compiler_directive_comments(s): ...@@ -3669,9 +3669,6 @@ def p_compiler_directive_comments(s):
if 'language_level' in new_directives: if 'language_level' in new_directives:
# Make sure we apply the language level already to the first token that follows the comments. # Make sure we apply the language level already to the first token that follows the comments.
s.context.set_language_level(new_directives['language_level']) s.context.set_language_level(new_directives['language_level'])
if 'str_is_str' in new_directives:
# Make sure we apply 'str_is_str' directive already to the first token that follows the comments.
s.context.set_str_is_str(new_directives['str_is_str'])
result.update(new_directives) result.update(new_directives)
......
# cython: language_level=3, binding=True, str_is_str=True # cython: language_level=3str, binding=True
# mode: run # mode: run
# tag: python3, str_is_str # tag: python3, str_is_str
......
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