[PATCH 07 of 10 PyPy] demandimport: add support for PyPy

Yuya Nishihara yuya at tcha.org
Mon Dec 28 08:32:34 CST 2015


On Wed, 23 Dec 2015 16:22:22 -0800, Bryan O'Sullivan wrote:
> PyPy's implementation of __import__ differs subtly from that of CPython.
> If invoked without a name or fromlist, it throws an ImportError,
> whereas CPython returns a reference to the level-appropriate importing
> package.
> 
> Here, we achieve the same behaviour by hand.
> 
> diff --git a/mercurial/demandimport.py b/mercurial/demandimport.py
> --- a/mercurial/demandimport.py
> +++ b/mercurial/demandimport.py
> @@ -133,6 +133,8 @@ class _demandmod(object):
>          self._load()
>          setattr(self._module, attr, val)
>  
> +_pypy = '__pypy__' in sys.builtin_module_names
> +
>  def _demandimport(name, globals=None, locals=None, fromlist=None, level=level):
>      if not locals or name in ignore or fromlist == ('*',):
>          # these cases we can't really delay
> @@ -191,7 +193,21 @@ def _demandimport(name, globals=None, lo
>                  return _hgextimport(_origimport, name, globals, locals,
>                                      fromlist, level)
>  
> -            mod = _hgextimport(_origimport, name, globals, locals, level=level)
> +            if _pypy:
> +                # PyPy's __import__ throws an exception if invoked
> +                # with an empty name and no fromlist.  Recreate the
> +                # desired behaviour by hand.
> +                mn = globalname
> +                mod = sys.modules[mn]
> +                if getattr(mod, '__path__', nothing) is nothing:
> +                    mn = mn.rsplit('.', 1)[0]
> +                    mod = sys.modules[mn]
> +                if level > 1:
> +                    mn = mn.rsplit('.', level - 1)[0]
> +                    mod = sys.modules[mn]

This can't complain about invalid import lines, but it won't be important.

Pushed the series to the clowncopter, many thanks for PyPy hacks.


More information about the Mercurial-devel mailing list