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