Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r62433:3c6f61f3f1ef
Date: 2013-03-18 17:34 -0700
http://bitbucket.org/pypy/pypy/changeset/3c6f61f3f1ef/

Log:    fix sliced indexing to allow for STL-like classes

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
@@ -270,11 +270,16 @@
 # pythonization by decoration (move to their own file?)
 def python_style_getitem(self, idx):
     # python-style indexing: check for size and allow indexing from the back
-    sz = len(self)
-    if idx < 0: idx = sz + idx
-    if idx < sz:
-        return self._getitem__unchecked(idx)
-    raise IndexError('index out of range: %d requested for %s of size %d' % 
(idx, str(self), sz))
+    try:
+        sz = len(self)
+        if idx < 0: idx = sz + idx
+        if idx < sz:
+            return self._getitem__unchecked(idx)
+        raise IndexError(
+            'index out of range: %d requested for %s of size %d' % (idx, 
str(self), sz))
+    except TypeError:
+        pass
+    return self._getitem__unchecked(idx)
 
 def python_style_sliceable_getitem(self, slice_or_idx):
     if type(slice_or_idx) == types.SliceType:
@@ -324,8 +329,7 @@
         pyclass.__iter__ = __iter__
 
     # combine __getitem__ and __len__ to make a pythonized __getitem__
-    if not 'std::map' in pyclass.__name__ and\
-            '__getitem__' in pyclass.__dict__ and '__len__' in 
pyclass.__dict__:
+    if '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__:
         pyclass._getitem__unchecked = pyclass.__getitem__
         if '__setitem__' in pyclass.__dict__ and '__iadd__' in 
pyclass.__dict__:
             pyclass.__getitem__ = python_style_sliceable_getitem
diff --git a/pypy/module/cppyy/test/stltypes.h 
b/pypy/module/cppyy/test/stltypes.h
--- a/pypy/module/cppyy/test/stltypes.h
+++ b/pypy/module/cppyy/test/stltypes.h
@@ -10,6 +10,35 @@
     int m_i;
 };
 
+//- class with lots of std::string handling
+class stringy_class {
+public:
+   stringy_class(const char* s);
+
+   std::string get_string1();
+   void get_string2(std::string& s);
+
+   void set_string1(const std::string& s);
+   void set_string2(std::string s);
+
+   std::string m_string;
+};
+
+//- class that has an STL-like interface
+class no_dict_available;
+    
+template<class T>
+class stl_like_class {
+public: 
+   no_dict_available* begin() { return 0; }
+   no_dict_available* end() { return 0; }
+   int size() { return 4; }
+   int operator[](int i) { return i; }
+   std::string operator[](double) { return "double"; }
+   std::string operator[](const std::string&) { return "string"; }
+};      
+
+
 #define STLTYPE_INSTANTIATION(STLTYPE, TTYPE, N)                             \
    std::STLTYPE<TTYPE > STLTYPE##_##N;                                       \
    std::STLTYPE<TTYPE >::iterator STLTYPE##_##N##_i;                         \
@@ -52,6 +81,8 @@
 
     };
 
+    stl_like_class<int> stlc_1;
+
 } // unnamed namespace
 
 #define STLTYPES_EXPLICIT_INSTANTIATION_DECL_COMPS(STLTYPE, TTYPE)           \
@@ -65,18 +96,3 @@
 // comps for int only to allow testing: normal use of vector is looping over a
 // range-checked version of __getitem__
 STLTYPES_EXPLICIT_INSTANTIATION_DECL_COMPS(vector, int)
-
-
-//- class with lots of std::string handling
-class stringy_class {
-public:
-   stringy_class(const char* s);
-
-   std::string get_string1();
-   void get_string2(std::string& s);
-
-   void set_string1(const std::string& s);
-   void set_string2(std::string s);
-
-   std::string m_string;
-};
diff --git a/pypy/module/cppyy/test/stltypes.xml 
b/pypy/module/cppyy/test/stltypes.xml
--- a/pypy/module/cppyy/test/stltypes.xml
+++ b/pypy/module/cppyy/test/stltypes.xml
@@ -26,5 +26,6 @@
 
   <class name="std::string" />
   <class name="stringy_class" />
+  <class pattern="stl_like_class<*>" />
 
 </lcgdict>
diff --git a/pypy/module/cppyy/test/test_stltypes.py 
b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -421,3 +421,12 @@
 
         raises(ValueError, mul.__setitem__, 'minus two', -2)
 
+    def test05_STL_like_class_indexing_overloads(self):
+        """Test overloading of operator[] in STL like class"""
+
+        import cppyy
+        stl_like_class = cppyy.gbl.stl_like_class
+
+        a = stl_like_class(int)()
+        assert a["some string" ] == 'string'
+        assert a[3.1415] == 'double'
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to