Author: Wim Lavrijsen <wlavrij...@lbl.gov>
Branch: cppyy-packaging
Changeset: r94750:749cd13269b0
Date: 2018-06-10 16:10 -0700
http://bitbucket.org/pypy/pypy/changeset/749cd13269b0/

Log:    py3 fixes

diff --git a/pypy/module/_cppyy/__init__.py b/pypy/module/_cppyy/__init__.py
--- a/pypy/module/_cppyy/__init__.py
+++ b/pypy/module/_cppyy/__init__.py
@@ -14,7 +14,7 @@
         '_set_function_generator': 'interp_cppyy.set_function_generator',
         '_register_class'        : 'interp_cppyy.register_class',
         '_get_nullptr'           : 'interp_cppyy.get_nullptr',
-        'CPPInstanceBase'        : 'interp_cppyy.W_CPPInstance',
+        'CPPInstance'            : 'interp_cppyy.W_CPPInstance',
         'addressof'              : 'interp_cppyy.addressof',
         '_bind_object'           : 'interp_cppyy._bind_object',
         'bind_object'            : 'interp_cppyy.bind_object',
diff --git a/pypy/module/_cppyy/converter.py b/pypy/module/_cppyy/converter.py
--- a/pypy/module/_cppyy/converter.py
+++ b/pypy/module/_cppyy/converter.py
@@ -391,7 +391,7 @@
     def from_memory(self, space, w_obj, w_pycppclass, offset):
         address = self._get_raw_address(space, w_obj, offset)
         charpptr = rffi.cast(rffi.CCHARPP, address)
-        return space.newbytes(rffi.charp2str(charpptr[0]))
+        return space.newtext(rffi.charp2str(charpptr[0]))
 
     def free_argument(self, space, arg, call_local):
         lltype.free(rffi.cast(rffi.CCHARPP, arg)[0], flavor='raw')
@@ -408,7 +408,7 @@
         strsize = self.size
         if charpptr[self.size-1] == '\0':
             strsize = self.size-1  # rffi will add \0 back
-        return space.newbytes(rffi.charpsize2str(charpptr, strsize))
+        return space.newtext(rffi.charpsize2str(charpptr, strsize))
 
 
 class VoidPtrConverter(TypeConverter):
diff --git a/pypy/module/_cppyy/ffitypes.py b/pypy/module/_cppyy/ffitypes.py
--- a/pypy/module/_cppyy/ffitypes.py
+++ b/pypy/module/_cppyy/ffitypes.py
@@ -79,10 +79,13 @@
 
             value = rffi.cast(rffi.CHAR, space.c_int_w(w_value))
         else:
-            value = space.text_w(w_value)
+            if space.isinstance_w(w_value, space.w_text):
+                value = space.text_w(w_value)
+            else:
+                value = space.bytes_w(w_value)
             if len(value) != 1:
                 raise oefmt(space.w_ValueError,
-                        "char expected, got string of size %d", len(value))
+                            "char expected, got string of size %d", len(value))
 
         value = rffi.cast(rffi.CHAR, value[0])
         return value     # turn it into a "char" to the annotator
@@ -110,10 +113,13 @@
 
             value = rffi.cast(rffi.CHAR, space.c_int_w(w_value))
         else:
-            value = space.text_w(w_value)
+            if space.isinstance_w(w_value, space.w_text):
+                value = space.text_w(w_value)
+            else:
+                value = space.bytes_w(w_value)
             if len(value) != 1:
                 raise oefmt(space.w_ValueError,
-                        "char expected, got string of size %d", len(value))
+                            "usigned char expected, got string of size %d", 
len(value))
 
         value = rffi.cast(rffi.CHAR, value[0])
         return value     # turn it into a "char" to the annotator
diff --git a/pypy/module/_cppyy/helper.py b/pypy/module/_cppyy/helper.py
--- a/pypy/module/_cppyy/helper.py
+++ b/pypy/module/_cppyy/helper.py
@@ -1,3 +1,4 @@
+import sys
 from rpython.rlib import rstring
 
 
@@ -116,6 +117,17 @@
     # TODO: perhaps absorb or "pythonify" these operators?
     return cppname
 
+if sys.hexversion < 0x3000000:
+    CPPYY__div__  = "__div__"
+    CPPYY__idiv__ = "__idiv__"
+    CPPYY__long__ = "__long__"
+    CPPYY__bool__ = "__nonzero__"
+else:
+    CPPYY__div__  = "__truediv__"
+    CPPYY__idiv__ = "__itruediv__"
+    CPPYY__long__ = "__int__"
+    CPPYY__bool__ = "__bool__"
+
 # _operator_mappings["[]"]  = "__setitem__"      # depends on return type
 # _operator_mappings["+"]   = "__add__"          # depends on # of args (see 
__pos__)
 # _operator_mappings["-"]   = "__sub__"          # id. (eq. __neg__)
@@ -123,7 +135,7 @@
 
 # _operator_mappings["[]"]  = "__getitem__"      # depends on return type
 _operator_mappings["()"]  = "__call__"
-_operator_mappings["/"]   = "__div__"            # __truediv__ in p3
+_operator_mappings["/"]   = CPPYY__div__
 _operator_mappings["%"]   = "__mod__"
 _operator_mappings["**"]  = "__pow__"            # not C++
 _operator_mappings["<<"]  = "__lshift__"
@@ -136,7 +148,7 @@
 _operator_mappings["+="]  = "__iadd__"
 _operator_mappings["-="]  = "__isub__"
 _operator_mappings["*="]  = "__imul__"
-_operator_mappings["/="]  = "__idiv__"           # __itruediv__ in p3
+_operator_mappings["/="]  = CPPYY__idiv__
 _operator_mappings["%="]  = "__imod__"
 _operator_mappings["**="] = "__ipow__"
 _operator_mappings["<<="] = "__ilshift__"
@@ -154,7 +166,7 @@
 # the following type mappings are "exact"
 _operator_mappings["const char*"] = "__str__"
 _operator_mappings["int"]         = "__int__"
-_operator_mappings["long"]        = "__long__"   # __int__ in p3
+_operator_mappings["long"]        = CPPYY__long__
 _operator_mappings["double"]      = "__float__"
 
 # the following type mappings are "okay"; the assumption is that they
@@ -163,13 +175,13 @@
 _operator_mappings["char*"]              = "__str__"
 _operator_mappings["short"]              = "__int__"
 _operator_mappings["unsigned short"]     = "__int__"
-_operator_mappings["unsigned int"]       = "__long__"      # __int__ in p3
-_operator_mappings["unsigned long"]      = "__long__"      # id.
-_operator_mappings["long long"]          = "__long__"      # id.
-_operator_mappings["unsigned long long"] = "__long__"      # id.
+_operator_mappings["unsigned int"]       = CPPYY__long__
+_operator_mappings["unsigned long"]      = CPPYY__long__
+_operator_mappings["long long"]          = CPPYY__long__
+_operator_mappings["unsigned long long"] = CPPYY__long__
 _operator_mappings["float"]              = "__float__"
 
-_operator_mappings["bool"] = "__nonzero__"       # __bool__ in p3
+_operator_mappings["bool"] = CPPYY__bool__
 
 # the following are not python, but useful to expose
 _operator_mappings["->"]  = "__follow__"
diff --git a/pypy/module/_cppyy/interp_cppyy.py 
b/pypy/module/_cppyy/interp_cppyy.py
--- a/pypy/module/_cppyy/interp_cppyy.py
+++ b/pypy/module/_cppyy/interp_cppyy.py
@@ -1470,7 +1470,9 @@
     __init__ = interp2app(W_CPPInstance.instance__init__),
     __eq__ = interp2app(W_CPPInstance.instance__eq__),
     __ne__ = interp2app(W_CPPInstance.instance__ne__),
+    # should be based on python version, but syntax is simpler this way
     __nonzero__ = interp2app(W_CPPInstance.instance__nonzero__),
+    __bool__ = interp2app(W_CPPInstance.instance__nonzero__),
     __len__ = interp2app(W_CPPInstance.instance__len__),
     __cmp__ = interp2app(W_CPPInstance.instance__cmp__),
     __repr__ = interp2app(W_CPPInstance.instance__repr__),
diff --git a/pypy/module/_cppyy/pythonify.py b/pypy/module/_cppyy/pythonify.py
--- a/pypy/module/_cppyy/pythonify.py
+++ b/pypy/module/_cppyy/pythonify.py
@@ -4,10 +4,22 @@
 import sys
 
 
-# Metaclasses are needed to store C++ static data members as properties. Since
-# the interp-level does not support metaclasses, they are created at app-level.
-# These are the metaclass base classes:
-class CPPScope(type):
+# Metaclasses are needed to store C++ static data members as properties and to
+# provide Python language features such as a customized __dir__ for namespaces
+# and __getattr__ for both. These features are used for lazy lookup/creation.
+# Since the interp-level does not support metaclasses, this is all done at the
+# app-level.
+#
+# C++ namespaces: are represented as Python classes, with CPPNamespace as the
+#   base class, which is at the moment just a label, and CPPNamespaceMeta as
+#   the base class of their invididualized meta class.
+#
+# C++ classes: are represented as Python classes, with CPPClass as the base
+#   class, which is a subclass of the interp-level CPPInstance. The former
+#   sets up the Python-class behavior for bound classes, the latter adds the
+#   bound object behavior that lives at the class level.
+
+class CPPScopeMeta(type):
     def __getattr__(self, name):
         try:
             return get_scoped_pycppitem(self, name)  # will cache on self
@@ -15,18 +27,57 @@
             raise AttributeError("%s object has no attribute '%s' (details: 
%s)" %
                                  (self, name, str(e)))
 
-class CPPMetaNamespace(CPPScope):
+class CPPNamespaceMeta(CPPScopeMeta):
     def __dir__(self):
         return self.__cppdecl__.__dir__()
 
-class CPPClass(CPPScope):
+class CPPClassMeta(CPPScopeMeta):
     pass
 
-# namespace base class (class base class defined in _post_import_startup()
-class CPPNamespace(object):
-    __metatype__ = CPPMetaNamespace
+# from six.py ---
+# Copyright (c) 2010-2017 Benjamin Peterson
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in 
all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
 
+def with_metaclass(meta, *bases):
+    """Create a base class with a metaclass."""
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(type):
 
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+
+        @classmethod
+        def __prepare__(cls, name, this_bases):
+            return meta.__prepare__(name, bases)
+    return type.__new__(metaclass, 'temporary_class', (), {})
+# --- end from six.py
+
+# C++ namespace base class (the C++ class base class defined in 
_post_import_startup)
+class CPPNamespace(with_metaclass(CPPNamespaceMeta, object)):
+     pass
+
+
+# TODO: this can be moved to the interp level (and share template argument
+# construction with function templates there)
 class CPPTemplate(object):
     def __init__(self, name, scope=None):
         self._name = name
@@ -123,7 +174,7 @@
 
     # create a metaclass to allow properties (for static data write access)
     import _cppyy
-    ns_meta = type(name+'_meta', (CPPMetaNamespace,), {})
+    ns_meta = type(CPPNamespace)(name+'_meta', (CPPNamespaceMeta,), {})
 
     # create the python-side C++ namespace representation, cache in scope if 
given
     d = {"__cppdecl__" : decl,
@@ -164,7 +215,7 @@
     # get a list of base classes for class creation
     bases = [get_pycppclass(base) for base in decl.get_base_names()]
     if not bases:
-        bases = [CPPInstance,]
+        bases = [CPPClass,]
     else:
         # it's possible that the required class now has been built if one of
         # the base classes uses it in e.g. a function interface
@@ -202,10 +253,10 @@
 
     # create a metaclass to allow properties (for static data write access)
     metabases = [type(base) for base in bases]
-    metacpp = type(CPPScope)(cl_name+'_meta', _drop_cycles(metabases), d_meta)
+    cl_meta = type(CPPClassMeta)(cl_name+'_meta', _drop_cycles(metabases), 
d_meta)
 
     # create the python-side C++ class
-    pycls = metacpp(cl_name, _drop_cycles(bases), d_class)
+    pycls = cl_meta(cl_name, _drop_cycles(bases), d_class)
 
     # store the class on its outer scope
     setattr(scope, cl_name, pycls)
@@ -284,7 +335,7 @@
 def extract_namespace(name):
     # find the namespace the named class lives in, take care of templates
     tpl_open = 0
-    for pos in xrange(len(name)-1, 1, -1):
+    for pos in range(len(name)-1, 1, -1):
         c = name[pos]
 
         # count '<' and '>' to be able to skip template contents
@@ -425,11 +476,11 @@
     # at pypy-c startup, rather than on the "import _cppyy" statement
     import _cppyy
 
-    # root of all proxy classes: CPPInstance in pythonify exists to combine
-    # the CPPScope metaclass with the interp-level CPPInstanceBase
-    global CPPInstance
-    class CPPInstance(_cppyy.CPPInstanceBase):
-        __metaclass__ = CPPScope
+    # root of all proxy classes: CPPClass in pythonify exists to combine the
+    # CPPClassMeta metaclass (for Python-side class behavior) with the
+    # interp-level CPPInstance (for bound object behavior)
+    global CPPClass
+    class CPPClass(with_metaclass(CPPClassMeta, _cppyy.CPPInstance)):
         pass
 
     # class generator callback
diff --git a/pypy/module/_cppyy/test/datatypes.h 
b/pypy/module/_cppyy/test/datatypes.h
--- a/pypy/module/_cppyy/test/datatypes.h
+++ b/pypy/module/_cppyy/test/datatypes.h
@@ -44,16 +44,16 @@
         m_cc_called(true), m_x(s.m_x), m_y(s.m_y), m_z(s.m_z), m_t(s.m_t) {}
 
     double operator[](int i) {
-       if (i == 0) return m_x;
-       if (i == 1) return m_y;
-       if (i == 2) return m_z;
-       if (i == 3) return m_t;
-       return -1;
+        if (i == 0) return m_x;
+        if (i == 1) return m_y;
+        if (i == 2) return m_z;
+        if (i == 3) return m_t;
+        return -1;
     }
 
     bool operator==(const FourVector& o) {
-       return (m_x == o.m_x && m_y == o.m_y &&
-               m_z == o.m_z && m_t == o.m_t);
+        return (m_x == o.m_x && m_y == o.m_y &&
+                m_z == o.m_z && m_t == o.m_t);
     }
 
 public:
diff --git a/pypy/module/_cppyy/test/test_advancedcpp.py 
b/pypy/module/_cppyy/test/test_advancedcpp.py
--- a/pypy/module/_cppyy/test/test_advancedcpp.py
+++ b/pypy/module/_cppyy/test/test_advancedcpp.py
@@ -673,5 +673,5 @@
 
         try:
             t.throw_exception()
-        except Exception, e:
+        except Exception as e:
             "C++ function failed" in str(e)
diff --git a/pypy/module/_cppyy/test/test_cppyy.py 
b/pypy/module/_cppyy/test/test_cppyy.py
--- a/pypy/module/_cppyy/test/test_cppyy.py
+++ b/pypy/module/_cppyy/test/test_cppyy.py
@@ -50,9 +50,13 @@
         import sys, math
         t = self.example01
 
+        pylong = int
+        if sys.hexversion < 0x3000000:
+            pylong = long
+
         res = t.get_overload("staticAddOneToInt")(1)
         assert res == 2
-        res = t.get_overload("staticAddOneToInt")(1L)
+        res = t.get_overload("staticAddOneToInt")(pylong(1))
         assert res == 2
         res = t.get_overload("staticAddOneToInt")(1, 2)
         assert res == 4
diff --git a/pypy/module/_cppyy/test/test_crossing.py 
b/pypy/module/_cppyy/test/test_crossing.py
--- a/pypy/module/_cppyy/test/test_crossing.py
+++ b/pypy/module/_cppyy/test/test_crossing.py
@@ -93,7 +93,12 @@
             %(body)s
 
             PyMODINIT_FUNC
-            init%(name)s(void) {
+            #if PY_MAJOR_VERSION >= 3
+            PyInit_%(name)s(void)
+            #else
+            init%(name)s(void) 
+            #endif
+            {
             %(init)s
             }
             """ % dict(name=name, init=init, body=body)
@@ -116,8 +121,20 @@
         name = 'bar'
 
         init = """
-        if (Py_IsInitialized())
+        #if PY_MAJOR_VERSION >= 3
+            static struct PyModuleDef moduledef = {
+                PyModuleDef_HEAD_INIT,
+                "bar", "Module Doc", -1, methods, NULL, NULL, NULL, NULL,
+            };
+        #endif
+
+        if (Py_IsInitialized()) {
+        #if PY_MAJOR_VERSION >= 3
+            PyObject *module = PyModule_Create(&moduledef);
+        #else
             Py_InitModule("bar", methods);
+        #endif
+        }
         """
 
         # note: only the symbols are needed for C, none for python
diff --git a/pypy/module/_cppyy/test/test_zjit.py 
b/pypy/module/_cppyy/test/test_zjit.py
--- a/pypy/module/_cppyy/test/test_zjit.py
+++ b/pypy/module/_cppyy/test/test_zjit.py
@@ -71,7 +71,9 @@
         self.name = name
         self.__name__ = name
     def getname(self, space, name):
-        return self.name
+        if sys.hexversion < 0x3000000:
+            return self.name
+        return unicode(self.name)
 class FakeBuffer(FakeBase):
     typedname = "buffer"
     def __init__(self, val):
@@ -108,9 +110,11 @@
 class FakeSpace(object):
     fake = True
 
-    w_None = None
-    w_str = FakeType("str")
-    w_int = FakeType("int")
+    w_None  = None
+    w_str   = FakeType("str")
+    w_text  = FakeType("str")
+    w_bytes = FakeType("str")
+    w_int   = FakeType("int")
     w_float = FakeType("float")
 
     def __init__(self):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to