summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-01-21 00:19:42 +0000
committerDamien George <damien.p.george@gmail.com>2015-01-21 00:19:42 +0000
commit962a5d50c94f01ca8dc7d46fe568535d713d59d0 (patch)
treee9e8460db62acf8c2695e9b00aead983f1c5e0d5
parentd7f199465f229e95b1ac1a1b6b74a3e0ce1f98c7 (diff)
downloadmicropython-962a5d50c94f01ca8dc7d46fe568535d713d59d0.tar.gz
micropython-962a5d50c94f01ca8dc7d46fe568535d713d59d0.zip
py: Implement __reversed__ slot.
Addresses issue #1073.
-rw-r--r--py/objreversed.c7
-rw-r--r--py/qstrdefs.h1
-rw-r--r--tests/basics/builtin_reversed.py6
3 files changed, 14 insertions, 0 deletions
diff --git a/py/objreversed.c b/py/objreversed.c
index 4ddb218074..0d5332d002 100644
--- a/py/objreversed.c
+++ b/py/objreversed.c
@@ -39,6 +39,13 @@ typedef struct _mp_obj_reversed_t {
STATIC mp_obj_t reversed_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 1, false);
+ // check if __reversed__ exists, and if so delegate to it
+ mp_obj_t dest[2];
+ mp_load_method_maybe(args[0], MP_QSTR___reversed__, dest);
+ if (dest[0] != MP_OBJ_NULL) {
+ return mp_call_method_n_kw(0, 0, dest);
+ }
+
mp_obj_reversed_t *o = m_new_obj(mp_obj_reversed_t);
o->base.type = type_in;
o->seq = args[0];
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index 71a523c2d6..23c25072d9 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -74,6 +74,7 @@ Q(__gt__)
Q(__eq__)
Q(__le__)
Q(__ge__)
+Q(__reversed__)
Q(micropython)
Q(bytecode)
diff --git a/tests/basics/builtin_reversed.py b/tests/basics/builtin_reversed.py
index 58631d5443..f129a4f5d5 100644
--- a/tests/basics/builtin_reversed.py
+++ b/tests/basics/builtin_reversed.py
@@ -31,3 +31,9 @@ class A:
return pos + 1
for a in reversed(A()):
print(a)
+
+# user object with __reversed__
+class B:
+ def __reversed__(self):
+ return [1, 2, 3]
+print(reversed(B()))