Author: Philip Jenvey <pjen...@underboss.org>
Branch: 
Changeset: r65673:eec382ffd965
Date: 2013-07-25 13:45 -0700
http://bitbucket.org/pypy/pypy/changeset/eec382ffd965/

Log:    Merged in squeaky/pypy/pythoninspect-fix (pull request #168)

        Fix PYTHONINSPECT behaviour

diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -32,6 +32,12 @@
 
 .. branch: ssl_moving_write_buffer
 
+.. branch: pythoninspect-fix
+Make PyPy respect PYTHONINSPECT variable set via os.putenv in the same process
+to start interactive prompt when the script execution finishes. This adds
+new __pypy__.os.real_getenv call that bypasses Python cache and looksup env
+in the underlying OS. Translatorshell now works on PyPy.
+
 .. branch: add-statvfs
 Added os.statvfs and os.fstatvfs
 
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -556,8 +556,15 @@
         # or
         #     * PYTHONINSPECT is set and stdin is a tty.
         #
+        try:
+            # we need a version of getenv that bypasses Python caching
+            from __pypy__.os import real_getenv
+        except ImportError:
+            # dont fail on CPython here
+            real_getenv = os.getenv
+
         return (interactive or
-                ((inspect or (readenv and os.getenv('PYTHONINSPECT')))
+                ((inspect or (readenv and real_getenv('PYTHONINSPECT')))
                  and sys.stdin.isatty()))
 
     success = True
diff --git a/pypy/interpreter/test/test_app_main.py 
b/pypy/interpreter/test/test_app_main.py
--- a/pypy/interpreter/test/test_app_main.py
+++ b/pypy/interpreter/test/test_app_main.py
@@ -48,7 +48,7 @@
     pdir = _get_next_path(ext='')
     p = pdir.ensure(dir=1).join('__main__.py')
     p.write(str(py.code.Source(source)))
-    # return relative path for testing purposes 
+    # return relative path for testing purposes
     return py.path.local().bestrelpath(pdir)
 
 demo_script = getscript("""
@@ -706,6 +706,20 @@
         assert 'hello world\n' in data
         assert '42\n' in data
 
+    def test_putenv_fires_interactive_within_process(self):
+        try:
+            import __pypy__
+        except ImportError:
+            py.test.skip("This can be only tested on PyPy with real_getenv")
+
+        # should be noninteractive when piped in
+        data = 'import os\nos.putenv("PYTHONINSPECT", "1")\n'
+        self.run('', senddata=data, expect_prompt=False)
+
+        # should go interactive with -c
+        data = data.replace('\n', ';')
+        self.run("-c '%s'" % data, expect_prompt=True)
+
     def test_option_S_copyright(self):
         data = self.run('-S -i', expect_prompt=True, expect_banner=True)
         assert 'copyright' not in data
@@ -971,7 +985,7 @@
             pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c')
             app_main.setup_bootstrap_path(pypy_c)
             newpath = sys.path[:]
-            # we get at least lib_pypy 
+            # we get at least lib_pypy
             # lib-python/X.Y.Z, and maybe more (e.g. plat-linux2)
             assert len(newpath) >= 2
             for p in newpath:
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -50,6 +50,13 @@
     }
 
 
+class OsModule(MixedModule):
+    appleveldefs = {}
+    interpleveldefs = {
+        'real_getenv': 'interp_os.real_getenv'
+    }
+
+
 class Module(MixedModule):
     appleveldefs = {
     }
@@ -82,6 +89,7 @@
         "time": TimeModule,
         "thread": ThreadModule,
         "intop": IntOpModule,
+        "os": OsModule,
     }
 
     def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/interp_os.py 
b/pypy/module/__pypy__/interp_os.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_os.py
@@ -0,0 +1,9 @@
+import os
+
+from pypy.interpreter.gateway import unwrap_spec
+
+
+@unwrap_spec(name='str0')
+def real_getenv(space, name):
+    """Get an OS environment value skipping Python cache"""
+    return space.wrap(os.environ.get(name))
diff --git a/pypy/module/__pypy__/test/test_os.py 
b/pypy/module/__pypy__/test/test_os.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_os.py
@@ -0,0 +1,16 @@
+class AppTestOs:
+    spaceconfig = dict(usemodules=['__pypy__'])
+
+    def test_real_getenv(self):
+        import __pypy__.os
+        import os
+
+        key = 'UNLIKELY_SET'
+        assert key not in os.environ
+        os.putenv(key, '42')
+        # this one skips Python cache
+        assert __pypy__.os.real_getenv(key) == '42'
+        # this one can only see things set on interpter start (cached)
+        assert os.getenv(key) is None
+        os.unsetenv(key)
+        assert __pypy__.os.real_getenv(key) is None
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to