[pypy-commit] pypy default: merge
hakanardo
noreply at buildbot.pypy.org
Tue May 1 11:27:33 CEST 2012
Author: Hakan Ardo <hakan at debian.org>
Branch:
Changeset: r54840:699a431ea9a8
Date: 2012-05-01 11:23 +0200
http://bitbucket.org/pypy/pypy/changeset/699a431ea9a8/
Log: merge
diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst
--- a/pypy/doc/cppyy.rst
+++ b/pypy/doc/cppyy.rst
@@ -21,6 +21,26 @@
.. _`llvm`: http://llvm.org/
+Motivation
+==========
+
+The cppyy module offers two unique features, which result in great
+performance as well as better functionality and cross-language integration
+than would otherwise be possible.
+First, cppyy is written in RPython and therefore open to optimizations by the
+JIT up until the actual point of call into C++.
+This means that there are no conversions necessary between a garbage collected
+and a reference counted environment, as is needed for the use of existing
+extension modules written or generated for CPython.
+It also means that if variables are already unboxed by the JIT, they can be
+passed through directly to C++.
+Second, Reflex (and cling far more so) adds dynamic features to C++, thus
+greatly reducing impedance mismatches between the two languages.
+In fact, Reflex is dynamic enough that you could write the runtime bindings
+generation in python (as opposed to RPython) and this is used to create very
+natural "pythonizations" of the bound code.
+
+
Installation
============
@@ -195,10 +215,12 @@
>>>> d = cppyy.gbl.BaseFactory("name", 42, 3.14)
>>>> type(d)
<class '__main__.Derived'>
- >>>> d.m_i
- 42
- >>>> d.m_d
- 3.14
+ >>>> isinstance(d, cppyy.gbl.Base1)
+ True
+ >>>> isinstance(d, cppyy.gbl.Base2)
+ True
+ >>>> d.m_i, d.m_d
+ (42, 3.14)
>>>> d.m_name == "name"
True
>>>>
@@ -295,6 +317,9 @@
To select a specific virtual method, do like with normal python classes
that override methods: select it from the class that you need, rather than
calling the method on the instance.
+ To select a specific overload, use the __dispatch__ special function, which
+ takes the name of the desired method and its signature (which can be
+ obtained from the doc string) as arguments.
* **namespaces**: Are represented as python classes.
Namespaces are more open-ended than classes, so sometimes initial access may
diff --git a/pypy/doc/extending.rst b/pypy/doc/extending.rst
--- a/pypy/doc/extending.rst
+++ b/pypy/doc/extending.rst
@@ -116,13 +116,21 @@
Reflex
======
-This method is only experimental for now, and is being exercised on a branch,
-`reflex-support`_, so you will have to build PyPy yourself.
+This method is still experimental and is being exercised on a branch,
+`reflex-support`_, which adds the `cppyy`_ module.
The method works by using the `Reflex package`_ to provide reflection
information of the C++ code, which is then used to automatically generate
-bindings at runtime, which can then be used from python.
+bindings at runtime.
+From a python standpoint, there is no difference between generating bindings
+at runtime, or having them "statically" generated and available in scripts
+or compiled into extension modules: python classes and functions are always
+runtime structures, created when a script or module loads.
+However, if the backend itself is capable of dynamic behavior, it is a much
+better functional match to python, allowing tighter integration and more
+natural language mappings.
Full details are `available here`_.
+.. _`cppyy`: cppyy.html
.. _`reflex-support`: cppyy.html
.. _`Reflex package`: http://root.cern.ch/drupal/content/reflex
.. _`available here`: cppyy.html
@@ -130,16 +138,33 @@
Pros
----
-If it works, it is mostly automatic, and hence easy in use.
-The bindings can make use of direct pointers, in which case the calls are
-very fast.
+The cppyy module is written in RPython, which makes it possible to keep the
+code execution visible to the JIT all the way to the actual point of call into
+C++, thus allowing for a very fast interface.
+Reflex is currently in use in large software environments in High Energy
+Physics (HEP), across many different projects and packages, and its use can be
+virtually completely automated in a production environment.
+One of its uses in HEP is in providing language bindings for CPython.
+Thus, it is possible to use Reflex to have bound code work on both CPython and
+on PyPy.
+In the medium-term, Reflex will be replaced by `cling`_, which is based on
+`llvm`_.
+This will affect the backend only; the python-side interface is expected to
+remain the same, except that cling adds a lot of dynamic behavior to C++,
+enabling further language integration.
+
+.. _`cling`: http://root.cern.ch/drupal/content/cling
+.. _`llvm`: http://llvm.org/
Cons
----
-C++ is a large language, and these bindings are not yet feature-complete.
-Although missing features should do no harm if you don't use them, if you do
-need a particular feature, it may be necessary to work around it in python
-or with a C++ helper function.
+C++ is a large language, and cppyy is not yet feature-complete.
+Still, the experience gained in developing the equivalent bindings for CPython
+means that adding missing features is a simple matter of engineering, not a
+question of research.
+The module is written so that currently missing features should do no harm if
+you don't use them, if you do need a particular feature, it may be necessary
+to work around it in python or with a C++ helper function.
Although Reflex works on various platforms, the bindings with PyPy have only
been tested on Linux.
diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py
--- a/pypy/module/rctime/test/test_rctime.py
+++ b/pypy/module/rctime/test/test_rctime.py
@@ -64,6 +64,7 @@
def test_localtime(self):
import time as rctime
+ import os
raises(TypeError, rctime.localtime, "foo")
rctime.localtime()
rctime.localtime(None)
@@ -75,6 +76,10 @@
assert 0 <= (t1 - t0) < 1.2
t = rctime.time()
assert rctime.localtime(t) == rctime.localtime(t)
+ if os.name == 'nt':
+ raises(ValueError, rctime.localtime, -1)
+ else:
+ rctime.localtime(-1)
def test_mktime(self):
import time as rctime
@@ -108,8 +113,8 @@
assert long(rctime.mktime(rctime.gmtime(t))) - rctime.timezone == long(t)
ltime = rctime.localtime()
assert rctime.mktime(tuple(ltime)) == rctime.mktime(ltime)
-
- assert rctime.mktime(rctime.localtime(-1)) == -1
+ if os.name != 'nt':
+ assert rctime.mktime(rctime.localtime(-1)) == -1
def test_asctime(self):
import time as rctime
diff --git a/pypy/module/select/__init__.py b/pypy/module/select/__init__.py
--- a/pypy/module/select/__init__.py
+++ b/pypy/module/select/__init__.py
@@ -2,6 +2,7 @@
from pypy.interpreter.mixedmodule import MixedModule
import sys
+import os
class Module(MixedModule):
@@ -9,11 +10,13 @@
}
interpleveldefs = {
- 'poll' : 'interp_select.poll',
'select': 'interp_select.select',
'error' : 'space.fromcache(interp_select.Cache).w_error'
}
+ if os.name =='posix':
+ interpleveldefs['poll'] = 'interp_select.poll'
+
if sys.platform.startswith('linux'):
interpleveldefs['epoll'] = 'interp_epoll.W_Epoll'
from pypy.module.select.interp_epoll import cconfig, public_symbols
diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -214,6 +214,8 @@
def test_poll(self):
import select
+ if not hasattr(select, 'poll'):
+ skip("no select.poll() on this platform")
readend, writeend = self.getpair()
try:
class A(object):
diff --git a/pypy/rlib/debug.py b/pypy/rlib/debug.py
--- a/pypy/rlib/debug.py
+++ b/pypy/rlib/debug.py
@@ -1,10 +1,12 @@
import sys, time
from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.rarithmetic import is_valid_int
def ll_assert(x, msg):
"""After translation to C, this becomes an RPyAssert."""
+ assert type(x) is bool, "bad type! got %r" % (type(x),)
assert x, msg
class Entry(ExtRegistryEntry):
@@ -21,8 +23,13 @@
hop.exception_cannot_occur()
hop.genop('debug_assert', vlist)
+class FatalError(Exception):
+ pass
+
def fatalerror(msg):
# print the RPython traceback and abort with a fatal error
+ if not we_are_translated():
+ raise FatalError(msg)
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem.lloperation import llop
llop.debug_print_traceback(lltype.Void)
@@ -33,6 +40,8 @@
def fatalerror_notb(msg):
# a variant of fatalerror() that doesn't print the RPython traceback
+ if not we_are_translated():
+ raise FatalError(msg)
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem.lloperation import llop
llop.debug_fatalerror(lltype.Void, msg)
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -916,7 +916,7 @@
ll_assert(not self.is_in_nursery(obj),
"object in nursery after collection")
# similarily, all objects should have this flag:
- ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS,
+ ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS != 0,
"missing GCFLAG_TRACK_YOUNG_PTRS")
# the GCFLAG_VISITED should not be set between collections
ll_assert(self.header(obj).tid & GCFLAG_VISITED == 0,
diff --git a/pypy/rpython/memory/gc/semispace.py b/pypy/rpython/memory/gc/semispace.py
--- a/pypy/rpython/memory/gc/semispace.py
+++ b/pypy/rpython/memory/gc/semispace.py
@@ -640,7 +640,7 @@
between collections."""
tid = self.header(obj).tid
if tid & GCFLAG_EXTERNAL:
- ll_assert(tid & GCFLAG_FORWARDED, "bug: external+!forwarded")
+ ll_assert(tid & GCFLAG_FORWARDED != 0, "bug: external+!forwarded")
ll_assert(not (self.tospace <= obj < self.free),
"external flag but object inside the semispaces")
else:
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -8,7 +8,6 @@
from pypy.rpython.memory.gcheader import GCHeaderBuilder
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rlib import rgc
-from pypy.rlib.debug import ll_assert
from pypy.rlib.objectmodel import we_are_translated
from pypy.translator.backendopt import graphanalyze
from pypy.translator.backendopt.support import var_needsgc
More information about the pypy-commit
mailing list