[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