From 4d7fbe2582c47d8b1c0765ca13655e6fc76f8398 Mon Sep 17 00:00:00 2001
From: Robert Bradshaw <robertwb@gmail.com>
Date: Wed, 27 Jul 2016 23:54:43 -0700
Subject: [PATCH] Allow old_style_globals to be set via a directive.

---
 Cython/Compiler/Builtin.py    | 8 ++++----
 Cython/Compiler/ModuleNode.py | 2 ++
 Cython/Compiler/Options.py    | 6 +++++-
 Cython/Compiler/Symtab.py     | 6 +++++-
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py
index 843f83edc..256b5bf7d 100644
--- a/Cython/Compiler/Builtin.py
+++ b/Cython/Compiler/Builtin.py
@@ -208,12 +208,12 @@ builtin_function_table = [
 
     # Put in namespace append optimization.
     BuiltinFunction('__Pyx_PyObject_Append', "OO",  "O",     "__Pyx_PyObject_Append"),
+
+    # This is conditionally looked up based on a compiler directive.
+    BuiltinFunction('__Pyx_globals',    "",     "O",     "__Pyx_Globals",
+                    utility_code=globals_utility_code),
 ]
 
-if not Options.old_style_globals:
-    builtin_function_table.append(
-        BuiltinFunction('globals',    "",     "O",     "__Pyx_Globals",
-                        utility_code=globals_utility_code))
 
 # Builtin types
 #  bool
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
index 049ff3f9c..133fe5e61 100644
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -103,6 +103,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
             self.scope.merge_in(scope)
 
     def analyse_declarations(self, env):
+        if self.directives:
+            env.old_style_globals = self.directives['old_style_globals']
         if not Options.docstrings:
             env.doc = self.doc = None
         elif Options.embed_pos_in_docstring:
diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py
index 18e4ea944..cdbf13e34 100644
--- a/Cython/Compiler/Options.py
+++ b/Cython/Compiler/Options.py
@@ -106,7 +106,7 @@ embed = None
 
 # In previous iterations of Cython, globals() gave the first non-Cython module
 # globals in the call stack.  Sage relies on this behavior for variable injection.
-old_style_globals = False
+old_style_globals = ShouldBeFromDirective('old_style_globals')
 
 # Allows cimporting from a pyx file without a pxd file.
 cimport_from_pyx = False
@@ -173,6 +173,7 @@ _directive_defaults = {
     'c_string_encoding': '',
     'type_version_tag': True,   # enables Py_TPFLAGS_HAVE_VERSION_TAG on extension types
     'unraisable_tracebacks': False,
+    'old_style_globals': False,
 
     # set __file__ and/or __path__ to known source/target path at import time (instead of not having them available)
     'set_initial_path' : None,  # SOURCEFILE or "/full/path/to/module"
@@ -304,6 +305,9 @@ directive_scopes = { # defaults to available everywhere
     'c_string_encoding': ('module',),
     'type_version_tag': ('module', 'cclass'),
     'language_level': ('module',),
+    # globals() could conceivably be controlled at a finer granularity,
+    # but that would complicate the implementation
+    'old_style_globals': ('module',),
 }
 
 
diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py
index a99f8b38c..974493162 100644
--- a/Cython/Compiler/Symtab.py
+++ b/Cython/Compiler/Symtab.py
@@ -1034,6 +1034,7 @@ class ModuleScope(Scope):
     is_module_scope = 1
     has_import_star = 0
     is_cython_builtin = 0
+    old_style_globals = 0
 
     def __init__(self, name, parent_module, context):
         from . import Builtin
@@ -1128,7 +1129,10 @@ class ModuleScope(Scope):
             for entry in self.cached_builtins:
                 if entry.name == name:
                     return entry
-        entry = self.declare(None, None, py_object_type, pos, 'private')
+        if name == 'globals' and not self.old_style_globals:
+            return self.outer_scope.lookup('__Pyx_globals')
+        else:
+            entry = self.declare(None, None, py_object_type, pos, 'private')
         if Options.cache_builtins and name not in Code.uncachable_builtins:
             entry.is_builtin = 1
             entry.is_const = 1 # cached
-- 
2.30.9