Lele Gaifax <[email protected]> writes:
> Let me know how you prefer me going forward: I can easily try out your (now
> reverted) change, but it's up to you.
The following patch:
--
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.
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..fc94168 100644
--- a/lib/sqlalchemy/engine/result.py
+++ b/lib/sqlalchemy/engine/result.py
@@ -35,7 +35,10 @@ except ImportError:
try:
from sqlalchemy.cresultproxy import BaseRowProxy
+ _baserowproxy_usecext = True
except ImportError:
+ _baserowproxy_usecext = False
+
class BaseRowProxy(object):
__slots__ = ('_parent', '_row', '_processors', '_keymap')
@@ -210,11 +213,21 @@ class ResultMetaData(object):
context, cursor_description, result_columns,
num_ctx_cols, cols_are_ordered, textual_ordered)
- # keymap indexes by integer index...
- self._keymap = dict([
- (elem[0], (elem[3], elem[4], elem[0]))
- for elem in raw
- ])
+ if _baserowproxy_usecext:
+ self._keymap = {}
+ else:
+ # keymap indexes by integer index: we add also negative
+ # indexes to handle the row[-x] case in the pure Python
+ # BaseRowProxy.__getitem__ implementation, avoiding an
+ # expensive isinstance(key, util.int_types) in the most
+ # common case path
+ self._keymap = dict([
+ (elem[0], (elem[3], elem[4], elem[0]))
+ for elem in raw
+ ] + [
+ (elem[0] - num_ctx_cols, (elem[3], elem[4], elem[0]))
+ for elem in raw
+ ])
# processors in key order for certain per-row
# views like __iter__ and slices
diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py
index 5ea5d35..aadd170 100644
--- a/test/engine/test_execute.py
+++ b/test/engine/test_execute.py
@@ -951,6 +951,25 @@ class ResultProxyTest(fixtures.TestBase):
{'key': (None, None, 0), 0: (None, None, 0)})
assert isinstance(row, collections.Sequence)
+ def test_rowproxy_getitem(self):
+ metadata = MetaData()
+ metadata.bind = 'sqlite://'
+ values = Table('users', metadata,
+ Column('key', String(10), primary_key=True),
+ Column('value', String(10)))
+ values.create()
+
+ values.insert().execute(key='One', value='Uno')
+ row = values.select().execute().fetchone()
+
+ assert row['key'] == 'One'
+ assert row['value'] == 'Uno'
+ assert row[0] == 'One'
+ assert row[1] == 'Uno'
+ assert row[-2] == 'One'
+ assert row[-1] == 'Uno'
+ assert row[1:0:-1] == ('Uno',)
+
@testing.requires.cextensions
def test_row_c_sequence_check(self):
import csv
works for me:
# Python 3
$ py.test test/
platform linux -- Python 3.5.1+, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 --
/home/lele/wip/sqlalchemy/env/bin/python3
cachedir: .cache
rootdir: /home/lele/wip/sqlalchemy, inifile: setup.cfg
collected 7557 items
...
== 6799 passed, 758 skipped in 131.56 seconds ==
$ rm lib/sqlalchemy/*.so
$ py.test test/
platform linux -- Python 3.5.1+, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 --
/home/lele/wip/sqlalchemy/env/bin/python3
cachedir: .cache
rootdir: /home/lele/wip/sqlalchemy, inifile: setup.cfg
collected 7557 items
...
== 6776 passed, 781 skipped in 128.30 seconds ==
# Python 2
$ py.test test/
platform linux2 -- Python 2.7.11, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 --
/home/lele/wip/sqlalchemy/env2/bin/python
cachedir: .cache
rootdir: /home/lele/wip/sqlalchemy, inifile: setup.cfg
collected 7562 items
...
== 6800 passed, 762 skipped in 140.81 seconds ==
$ rm lib/sqlalchemy/*.so
$ py.test test/
platform linux2 -- Python 2.7.11, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 --
/home/lele/wip/sqlalchemy/env2/bin/python
cachedir: .cache
rootdir: /home/lele/wip/sqlalchemy, inifile: setup.cfg
collected 7562 items
== 6777 passed, 785 skipped in 135.83 seconds ==
So, what exactly failed for you?
ciao, lele.
PS: BTW, nice to see Py3.5 is faster than 2.7.11 ;-)
--
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
[email protected] | -- Fortunato Depero, 1929.
--
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.