summaryrefslogtreecommitdiff
path: root/Cython/Compiler
diff options
context:
space:
mode:
Diffstat (limited to 'Cython/Compiler')
-rw-r--r--Cython/Compiler/Main.py9
-rw-r--r--Cython/Compiler/Options.py3
-rw-r--r--Cython/Compiler/Parsing.py3
-rw-r--r--Cython/Compiler/Symtab.py18
4 files changed, 27 insertions, 6 deletions
diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py
index 411ef0a8f..1dfc4baf1 100644
--- a/Cython/Compiler/Main.py
+++ b/Cython/Compiler/Main.py
@@ -94,9 +94,18 @@ class Context(object):
if language_level is not None:
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
+ def set_str_is_str(self, str_is_str):
+ from .Future import unicode_literals
+ if str_is_str:
+ self.future_directives.discard(unicode_literals)
+ else:
+ self.future_directives.add(unicode_literals)
+
def set_language_level(self, level):
self.language_level = level
if level >= 3:
diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py
index a113f7182..966d282ed 100644
--- a/Cython/Compiler/Options.py
+++ b/Cython/Compiler/Options.py
@@ -198,6 +198,7 @@ _directive_defaults = {
'iterable_coroutine': False, # Make async coroutines backwards compatible with the old asyncio yield-from syntax.
'c_string_type': 'bytes',
'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
'unraisable_tracebacks': True,
'old_style_globals': False,
@@ -313,6 +314,7 @@ directive_types = {
'freelist': int,
'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'),
'c_string_encoding': normalise_encoding_name,
+ 'str_is_str': bool,
}
for key, val in _directive_defaults.items():
@@ -347,6 +349,7 @@ directive_scopes = { # defaults to available everywhere
# Avoid scope-specific to/from_py_functions for c_string.
'c_string_type': ('module',),
'c_string_encoding': ('module',),
+ 'str_is_str': ('module',),
'type_version_tag': ('module', 'cclass'),
'language_level': ('module',),
# globals() could conceivably be controlled at a finer granularity,
diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py
index 4200ee494..d47677587 100644
--- a/Cython/Compiler/Parsing.py
+++ b/Cython/Compiler/Parsing.py
@@ -3652,6 +3652,9 @@ def p_compiler_directive_comments(s):
if 'language_level' in new_directives:
# 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'])
+ 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)
diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py
index 2af2b9d95..eab11e05f 100644
--- a/Cython/Compiler/Symtab.py
+++ b/Cython/Compiler/Symtab.py
@@ -21,6 +21,7 @@ from .PyrexTypes import py_object_type, unspecified_type
from .TypeSlots import (
pyfunction_signature, pymethod_signature, richcmp_special_methods,
get_special_method_signature, get_property_accessor_signature)
+from . import Future
from . import Code
@@ -1002,10 +1003,12 @@ class BuiltinScope(Scope):
cname, type = definition
self.declare_var(name, type, None, cname)
- def lookup(self, name, language_level=None):
- # 'language_level' is passed by ModuleScope
- if language_level == 3:
- if name == 'str':
+ def lookup(self, name, language_level=None, str_is_str=None):
+ # 'language_level' and 'str_is_str' are passed by ModuleScope
+ if name == 'str':
+ if str_is_str is None:
+ str_is_str = language_level in (None, 2)
+ if not str_is_str:
name = 'unicode'
return Scope.lookup(self, name)
@@ -1174,15 +1177,18 @@ class ModuleScope(Scope):
def global_scope(self):
return self
- def lookup(self, name, language_level=None):
+ def lookup(self, name, language_level=None, str_is_str=None):
entry = self.lookup_here(name)
if entry is not None:
return entry
if language_level is None:
language_level = self.context.language_level if self.context is not None else 3
+ if str_is_str is None:
+ str_is_str = language_level == 2 or (
+ self.context is not None and Future.unicode_literals not in self.context.future_directives)
- return self.outer_scope.lookup(name, language_level=language_level)
+ return self.outer_scope.lookup(name, language_level=language_level, str_is_str=str_is_str)
def declare_tuple_type(self, pos, components):
components = tuple(components)