Skip to content

Commit

Permalink
add compatibility module and make use of CPPYY_BACKEND_LIBRARY if set
Browse files Browse the repository at this point in the history
  • Loading branch information
wlav committed Oct 3, 2017
1 parent a725524 commit 0212ac2
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 8 deletions.
19 changes: 12 additions & 7 deletions doc/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,23 @@ To use them, tell ``pip``::
$ pip install --extra-index https://cern.ch/wlav/wheels cppyy

PyPy 5.7 and 5.8 have a built-in module ``cppyy``.
You can still install the ``cppyy`` package (or, alternatively, just
``cppyy-backend``), but the built-in takes precedence.
To use ``cppyy`` without further setting environment variables, simply load
the backend explicitly, before importing ``cppyy``::
You can still install the ``cppyy`` package, but the built-in module takes
precedence.
To use ``cppyy``, first import a compatibility module::

$ pypy
[PyPy 5.8.0 with GCC 5.4.0] on linux2
>>>> from cppyy_backend import loader
>>>> c = loader.load_cpp_backend()
>>>> import cppyy
>>>> import cppyy_compat, cppyy
>>>>

You will have to set ``LD_LIBRARY_PATH`` appropriately if you get an
``EnvironmentError`` (it will indicate the needed directory).

Note that your python interpreter (whether CPython or ``pypy-c``) may not have
been linked by the C++ compiler.
This can lead to problems during loading of C++ libraries and program shutdown.
In that case, re-linking is highly recommended.

Older versions of PyPy (5.6.0 and earlier) have a built-in ``cppyy`` based on
`Reflex`_, which is less feature-rich and no longer supported.
However, both the :doc:`distribution tools <distribution>` and user-facing
Expand Down
16 changes: 16 additions & 0 deletions python/cppyy/_pypy_cppyy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
""" PyPy-specific touch-ups
"""

import sys

# pypy-c may not have been linked with C++; force its loading before
# doing anything else (note that not linking with C++ spells trouble
# anyway for any C++ libraries ...)
if 'linux' in sys.platform and 'GCC' in sys.version:
# TODO: check executable to see whether linking indeed didn't happen
import ctypes
try:
stdcpp = ctypes.CDLL('libstdc++.so', ctypes.RTLD_GLOBAL)
except Exception:
pass
# TODO: what if Linux/clang and what if Mac?

import os
from cppyy_backend import loader

__all__ = [
Expand All @@ -12,6 +27,7 @@
# first load the dependency libraries of the backend, then
# pull in the built-in low-level cppyy
c = loader.load_cpp_backend()
os.environ['CPPYY_BACKEND_LIBRARY'] = c._name
import _cppyy as _backend # built-in module
_backend._cpp_backend = c

Expand Down
47 changes: 47 additions & 0 deletions python/cppyy_compat/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""Compatibility layer for PyPy 5.8 and 5.7
"""

def pypy58_57_compat():
import imp, os

# first load and move the builtin cppyy module
if not 'cppyy' in sys.modules:
try:
olddir = os.getcwd()
from cppyy_backend import loader
c = loader.load_cpp_backend()
# move to the location of the backend, just in case '.' is
# in the dynloader's path
os.chdir(os.path.dirname(c._name))
imp.init_builtin('cppyy')
except ImportError:
raise EnvironmentError('"%s" missing in LD_LIBRARY_PATH' %\
os.path.dirname(c._name))
finally:
os.chdir(olddir)

sys.modules['_cppyy'] = sys.modules['cppyy']
del sys.modules['cppyy']

# now locate and load the pip cppyy module
decdir = os.path.join(os.path.dirname(__file__), os.path.pardir)
for path in sys.path: # walk over sys.path skips builtins
try:
fp, pathname, description = imp.find_module('cppyy', [path])
sys.modules['cppyy'] = imp.load_module('cppyy_', fp, pathname, description)
break
except ImportError:
pass

# copy over the _cppyy functions into cppyy
old = sys.modules['_cppyy']
new = sys.modules['cppyy']
for name in dir(old):
if not hasattr(new, name):
setattr(new, name, getattr(old, name))

import sys
version = sys.pypy_version_info
if version[0] == 5 and 6 < version[1] <= 8:
pypy58_57_compat()
del version, sys
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
version = sys.pypy_version_info
if version[0] == 5 and version[1] <= 8:
requirements = ['cppyy-backend<0.3']
add_pkg = ['cppyy', 'cppyy_compat']
else:
requirements = ['cppyy-backend']
add_pkg = ['cppyy']
except ImportError:
requirements = ['CPyCppyy']

Expand Down Expand Up @@ -60,5 +62,5 @@
keywords='C++ bindings',

package_dir={'': 'python'},
packages=find_packages('python'),
packages=find_packages('python', include=add_pkg),
)

0 comments on commit 0212ac2

Please sign in to comment.