From 794806acd5a694995ba35c11f623233b255b1296 Mon Sep 17 00:00:00 2001 From: Harold Cooper Date: Wed, 10 Feb 2016 23:19:54 -0500 Subject: [PATCH 1/9] more cleanups a la 0aa377c --- records.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/records.py b/records.py index 4b558b0..0b16f13 100644 --- a/records.py +++ b/records.py @@ -92,7 +92,7 @@ class ResultSet(object): # Other code may have iterated between yields, # so always check the cache. if i < len(self): - yield self._all_rows[i] + yield self[i] else: # Throws StopIteration when done. yield next(self) @@ -120,7 +120,7 @@ class ResultSet(object): is_int = True key = slice(key, key + 1, None) - while len(self._all_rows) < key.stop or key.stop is None: + while len(self) < key.stop or key.stop is None: try: next(self) except StopIteration: From 9034b51029965a6515ee159b9dc5c5fdc61618f3 Mon Sep 17 00:00:00 2001 From: Harold Cooper Date: Wed, 10 Feb 2016 23:28:13 -0500 Subject: [PATCH 2/9] typo --- records.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/records.py b/records.py index 0b16f13..cbbbe6f 100644 --- a/records.py +++ b/records.py @@ -34,7 +34,7 @@ class RecordsCursor(NamedTupleCursor): def _make_nt(self, namedtuple=namedtuple): RecordBase = namedtuple("Record", [d[0] for d in self.description or ()]) - # Extend the RecordsBase namedtupe, for enhanced API functionality. + # Extend the RecordsBase namedtuple, for enhanced API functionality. class Record(RecordBase): __slots__ = () def keys(self): From fa3600df20a79e7098c4dfad2beb161cc0f3b668 Mon Sep 17 00:00:00 2001 From: Harold Cooper Date: Thu, 11 Feb 2016 00:44:11 -0500 Subject: [PATCH 3/9] add regression tests for issues #13, #15, and the not-yet-fixed #34 --- tests/__init__.py | 0 tests/test_records.py | 47 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/test_records.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_records.py b/tests/test_records.py new file mode 100644 index 0000000..27ecf68 --- /dev/null +++ b/tests/test_records.py @@ -0,0 +1,47 @@ +from collections import namedtuple + +import records + + +IdRecord = namedtuple('IdRecord', 'id') + +def check_id(i, row): + assert row.id == i + +class TestResultSet: + def test_iter(self): + rows = records.ResultSet(IdRecord(i) for i in range(10)) + for i, row in enumerate(rows): + check_id(i, row) + + def test_next(self): + rows = records.ResultSet(IdRecord(i) for i in range(10)) + for i in range(10): + check_id(i, next(rows)) + + def test_iter_and_next(self): + rows = records.ResultSet(IdRecord(i) for i in range(10)) + i = enumerate(iter(rows)) + check_id(*next(i)) # Cache first row. + next(rows) # Cache second row. + check_id(*next(i)) # Read second row from cache. + + def test_multiple_iter(self): + rows = records.ResultSet(IdRecord(i) for i in range(10)) + i = enumerate(iter(rows)) + j = enumerate(iter(rows)) + + check_id(*next(i)) # Cache first row. + + check_id(*next(j)) # Read first row from cache. + check_id(*next(j)) # Cache second row. + + check_id(*next(i)) # Read second row from cache. + + def test_slice_iter(self): + rows = records.ResultSet(IdRecord(i) for i in range(10)) + for i, row in enumerate(rows[:5]): + check_id(i, row) + for i, row in enumerate(rows): + check_id(i, row) + assert len(rows) == 10 From 37f3032a4c47cc0630c1ccbe397b20ea546d2a1b Mon Sep 17 00:00:00 2001 From: Harold Cooper Date: Thu, 11 Feb 2016 00:48:30 -0500 Subject: [PATCH 4/9] Restrict ResultSet slices to just the sliced rows. Fixes #34. --- records.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/records.py b/records.py index cbbbe6f..7c481fa 100644 --- a/records.py +++ b/records.py @@ -113,12 +113,11 @@ class ResultSet(object): def __getitem__(self, key): - is_int = False + is_int = isinstance(key, int) # Convert ResultSet[1] into slice. - if isinstance(key, int): - is_int = True - key = slice(key, key + 1, None) + if is_int: + key = slice(key, key + 1) while len(self) < key.stop or key.stop is None: try: @@ -126,15 +125,11 @@ class ResultSet(object): except StopIteration: break - item = self._all_rows[key] - if not is_int: - r = ResultSet(self._rows) - r._all_rows = item - item = r + rows = self._all_rows[key] + if is_int: + return rows[0] else: - item = item[0] - - return item + return ResultSet(iter(rows)) def __len__(self): return len(self._all_rows) From 93620c3ac4ee992a86d2bd6a82c9bf94daa6ce4a Mon Sep 17 00:00:00 2001 From: mcdallas Date: Thu, 11 Feb 2016 17:56:55 +0000 Subject: [PATCH 5/9] Added __repr__ I used __class__.__name__ instead of Database for potential subclasses. --- records.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/records.py b/records.py index cbbbe6f..2e64893 100644 --- a/records.py +++ b/records.py @@ -196,6 +196,11 @@ class Database(object): def __exit__(self, exc, val, traceback): self.close() + def __repr__(self): + status = 'Open' if self.open else 'Closed' + r = '{}(url={}, status={})'.format(self.__class__.__name__, self.db_url, status) + return r + def _enable_hstore(self): """Enables HSTORE support, if available.""" try: From 893c46f630e6351ebb5114a0aa46fb48d56365b1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 11 Feb 2016 16:35:21 -0500 Subject: [PATCH 6/9] update requirements.txt --- requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2b88733..f46e9ee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ psycopg2==2.6.1 -tablib==0.10.0 +py==1.4.31 +pytest==2.8.7 +tablib==0.11.0 \ No newline at end of file From 3153bc213c206b6bc63256d775f7502b3700d3c4 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 11 Feb 2016 16:35:32 -0500 Subject: [PATCH 7/9] Makefile! --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6d7199b --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +tests: + py.test tests +init: + pip install -r requirements.txt +publish: + python setup.py register + python setup.py sdist upload + python setup.py bdist_wheel --universal upload + rm -fr build dist .egg records.egg-info \ No newline at end of file From 1cd006b57d6bd3e43237909b77f1c67ec727ce12 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 11 Feb 2016 16:36:00 -0500 Subject: [PATCH 8/9] Makefile: test: --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6d7199b..a43a28a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -tests: +test: py.test tests init: pip install -r requirements.txt From 4bbbdc965f4a9cb16f3222b6ae49da90f2b7bd22 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 11 Feb 2016 16:37:04 -0500 Subject: [PATCH 9/9] updated repr for database --- records.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/records.py b/records.py index e983c33..e089d0d 100644 --- a/records.py +++ b/records.py @@ -192,9 +192,7 @@ class Database(object): self.close() def __repr__(self): - status = 'Open' if self.open else 'Closed' - r = '{}(url={}, status={})'.format(self.__class__.__name__, self.db_url, status) - return r + return ''.format(self.open) def _enable_hstore(self): """Enables HSTORE support, if available."""