this is great. but you know throwing an isinstance() right into the
otherwise no-latency __getitem__ (the pure python version) there is
making me think this may be better as a key fallback, so the expense is
limited just to the negative integer case (or another idea, the negative
int keys could be pre-populated the same way the positive ones are).
what do you think?
On 01/25/2016 07:26 AM, Lele Gaifax wrote:
> Here is a rectified diff, handling fixing the Py2 case:
>
> diff --git a/lib/sqlalchemy/cextension/resultproxy.c
> b/lib/sqlalchemy/cextension/resultproxy.c
> index 9c4d0c7..331fae2 100644
> --- a/lib/sqlalchemy/cextension/resultproxy.c
> +++ b/lib/sqlalchemy/cextension/resultproxy.c
> @@ -263,7 +263,9 @@ BaseRowProxy_subscript(BaseRowProxy *self, PyObject
> *key)
> #if PY_MAJOR_VERSION < 3
> if (PyInt_CheckExact(key)) {
> index = PyInt_AS_LONG(key);
> - }
> + if (index < 0)
> + index += BaseRowProxy_length(self);
> + } else
> #endif
>
> if (PyLong_CheckExact(key)) {
> @@ -271,6 +273,8 @@ BaseRowProxy_subscript(BaseRowProxy *self, PyObject
> *key)
> if ((index == -1) && PyErr_Occurred())
> /* -1 can be either the actual value, or an error flag. */
> return NULL;
> + if (index < 0)
> + index += BaseRowProxy_length(self);
> } else if (PySlice_Check(key)) {
> values = PyObject_GetItem(self->row, key);
> if (values == NULL)
> diff --git a/lib/sqlalchemy/engine/result.py
> b/lib/sqlalchemy/engine/result.py
> index cc4ac74..47f87f3 100644
> --- a/lib/sqlalchemy/engine/result.py
> +++ b/lib/sqlalchemy/engine/result.py
> @@ -67,6 +67,8 @@ except ImportError:
>
> def __getitem__(self, key):
> try:
> + if isinstance(key, util.int_types) and key < 0:
> + key += len(self)
> processor, obj, index = self._keymap[key]
> except KeyError:
> processor, obj, index = self._parent._key_fallback(key)
> diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py
> index 5ea5d35..06f7863 100644
> --- a/test/engine/test_execute.py
> +++ b/test/engine/test_execute.py
> @@ -951,6 +951,20 @@ class ResultProxyTest(fixtures.TestBase):
> {'key': (None, None, 0), 0: (None, None, 0)})
> assert isinstance(row, collections.Sequence)
>
> + def test_rowproxy_getitem(self):
> + from sqlalchemy.engine import RowProxy
> +
> + row = RowProxy(
> + object(), ['value1', 'value2'], [None, None],
> + {'key1': (None, None, 0),
> + 'key2': (None, None, 1),
> + 0: (None, None, 0),
> + 1: (None, None, 1)})
> + assert row['key1'] == 'value1'
> + assert row[0] == 'value1'
> + assert row[-1] == 'value2'
> + assert row[1:0:-1] == ('value2',)
> +
> @testing.requires.cextensions
> def test_row_c_sequence_check(self):
> import csv
>
> BTW, the first Py2-only check seems redundant in the current master: it
> extract `index` from a PyInt, but then in the ``else`` part of the cascading
> if the `index` is recomputed... Am I missing something there?
>
> ciao, lele.
>
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.