Commit 1f6f31cd authored by Kirill Smelkov's avatar Kirill Smelkov

gpython: Preimport golang and gevent from exactly the same place as std python would do

GPython preimports golang and gevent, but until now, it was preimporting
them before adjusting sys.path according to given -c/-m/file/... And
this was leading to difference in behaviour with standard Python where
e.g. `import golang` might result in different files loaded if e.g.
golang/ is there on cwd and -c/-m was given.

-> Rework gpython startup so that golang/gevent preimport happens after
sys.path initialization.

This fixes `tox -e py27-gevent` which was previously failing on
test_defer_excchain_dump_pytest / test_defer_excchain_dump_ipython
because dumped paths were different than expected ones.

It, however, breaks test_defer_excchain_traceback on py27-gevent.  ->
We'll do more fixups to sys.path handling in the next patch which will
fix that failure as well.
parent 51925488
...@@ -44,10 +44,10 @@ from __future__ import print_function, absolute_import ...@@ -44,10 +44,10 @@ from __future__ import print_function, absolute_import
# pymain mimics `python ...` # pymain mimics `python ...`
# #
# argv is what comes via `...` without first [0] for python. # argv is what comes via `...` without first [0] for python.
def pymain(argv): # init, if provided, is called after options are parsed, but before interpreter start.
import sys, code, runpy, six def pymain(argv, init=None):
import sys
from os.path import dirname from os.path import dirname
from six.moves import input as raw_input
run = None # function to run according to -c/-m/file/interactive run = None # function to run according to -c/-m/file/interactive
version = False # set if `-V` version = False # set if `-V`
...@@ -69,6 +69,7 @@ def pymain(argv): ...@@ -69,6 +69,7 @@ def pymain(argv):
sys.argv = ['-c'] + argv # python leaves '-c' as argv[0] sys.argv = ['-c'] + argv # python leaves '-c' as argv[0]
sys.path.insert(0, '') # cwd sys.path.insert(0, '') # cwd
def run(): def run():
import six
# exec with the same globals `python -c ...` does # exec with the same globals `python -c ...` does
g = {'__name__': '__main__', g = {'__name__': '__main__',
'__doc__': None, '__doc__': None,
...@@ -86,6 +87,7 @@ def pymain(argv): ...@@ -86,6 +87,7 @@ def pymain(argv):
sys.argv = [mod] + argv sys.argv = [mod] + argv
sys.path.insert(0, '') # cwd sys.path.insert(0, '') # cwd
def run(): def run():
import runpy
# search sys.path for module and run corresponding .py file as script # search sys.path for module and run corresponding .py file as script
runpy.run_module(mod, init_globals={'__doc__': None}, runpy.run_module(mod, init_globals={'__doc__': None},
run_name='__main__', alter_sys=True) run_name='__main__', alter_sys=True)
...@@ -126,6 +128,8 @@ def pymain(argv): ...@@ -126,6 +128,8 @@ def pymain(argv):
sys.path.insert(0, '') # cwd sys.path.insert(0, '') # cwd
def run(): def run():
import code
from six.moves import input as raw_input
# like code.interact() but with overridden console.raw_input _and_ # like code.interact() but with overridden console.raw_input _and_
# readline imported (code.interact mutually excludes those two). # readline imported (code.interact mutually excludes those two).
try: try:
...@@ -146,6 +150,8 @@ def pymain(argv): ...@@ -146,6 +150,8 @@ def pymain(argv):
# ---- options processed -> start the interpreter ---- # ---- options processed -> start the interpreter ----
if init is not None:
init()
# handle -V/--version # handle -V/--version
if version: if version:
...@@ -298,41 +304,46 @@ def main(): ...@@ -298,41 +304,46 @@ def main():
raise RuntimeError('gpython: unknown -X option %s' % opt) raise RuntimeError('gpython: unknown -X option %s' % opt)
argv = argv_ + argv argv = argv_ + argv
# initialize according to selected runtime # init initializes according to selected runtime
if gpy_runtime == 'gevent': # it is called after options are parsed and sys.path is setup correspondingly.
# make gevent pre-available & stdlib patched # this way golang and gevent are imported from exactly the same place as
import gevent # they would be in standard python after regular import (ex from golang/
from gevent import monkey # under cwd if run under `python -c ...` or interactive console.
# XXX workaround for gevent vs pypy2 crash. def init():
# XXX remove when gevent-1.4.1 is relased (https://github.com/gevent/gevent/pull/1357). if gpy_runtime == 'gevent':
patch_thread=True # make gevent pre-available & stdlib patched
if pypy and sys.version_info.major == 2: import gevent
_ = monkey.patch_thread(existing_locks=False) from gevent import monkey
assert _ in (True, None) # XXX workaround for gevent vs pypy2 crash.
patch_thread=False # XXX remove when gevent-1.4.1 is relased (https://github.com/gevent/gevent/pull/1357).
_ = monkey.patch_all(thread=patch_thread) # XXX sys=True ? patch_thread=True
if _ not in (True, None): # patched or nothing to do if pypy and sys.version_info.major == 2:
# XXX provide details _ = monkey.patch_thread(existing_locks=False)
raise RuntimeError('gevent monkey-patching failed') assert _ in (True, None)
gpy_verextra = 'gevent %s' % gevent.__version__ patch_thread=False
_ = monkey.patch_all(thread=patch_thread) # XXX sys=True ?
elif gpy_runtime == 'threads': if _ not in (True, None): # patched or nothing to do
gpy_verextra = 'threads' # XXX provide details
raise RuntimeError('gevent monkey-patching failed')
else: gpy_verextra = 'gevent %s' % gevent.__version__
raise RuntimeError('gpython: invalid runtime %s' % gpy_runtime)
elif gpy_runtime == 'threads':
# put go, chan, select, ... into builtin namespace gpy_verextra = 'threads'
import golang
from six.moves import builtins else:
for k in golang.__all__: raise RuntimeError('gpython: invalid runtime %s' % gpy_runtime)
setattr(builtins, k, getattr(golang, k))
# put go, chan, select, ... into builtin namespace
# sys.version import golang
sys.version += (' [GPython %s] [%s]' % (golang.__version__, gpy_verextra)) from six.moves import builtins
for k in golang.__all__:
setattr(builtins, k, getattr(golang, k))
# sys.version
sys.version += (' [GPython %s] [%s]' % (golang.__version__, gpy_verextra))
# tail to pymain # tail to pymain
pymain(argv) pymain(argv, init)
if __name__ == '__main__': if __name__ == '__main__':
main() main()
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