Skip to content

Commit 8573841

Browse files
author
Alexander Kazeka
committed
Merge pull request #3 from kazeka/2to3
Major version bump: ran 2to3, changed buffer to memoryview, updated setup and tox config
2 parents 4dc1de4 + b720de2 commit 8573841

7 files changed

+52
-27
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: python
22
python:
3+
- "3.4"
34
- "2.7"
4-
- "2.6"
55

66
install: pip install -r test-requirements.txt --use-mirrors
77
script: sh run-tests

README.rst

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
.. image:: https://travis-ci.org/litl/park.svg?branch=master :alt: Build Status
2+
.. image:: https://coveralls.io/repos/litl/park/badge.svg?branch=master :alt: Coverage Status
3+
14
Park is a persistent key-value API for Python with ordered traversal
25
of keys. Both keys and values are binary safe. It's similar in use to
36
LevelDB, but has no dependencies outside the Python standard library.

park.py

+38-16
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
11
# coding: utf-8
2-
# Copyright 2012 litl, LLC. All Rights Reserved.
3-
4-
__version__ = "1.0.0"
2+
# Copyright 2012-2015 litl, LLC. All Rights Reserved.
53

64
import abc
75
import itertools
86
import logging
97
import os
108
import sqlite3
119

10+
__version__ = "1.1.0"
11+
1212
logger = logging.getLogger(__name__)
1313

1414
__all__ = ["SQLiteStore", "KVStore"]
1515

16+
import sys
17+
if sys.version_info < (3,):
18+
def b(x):
19+
return x
20+
21+
def un_b(x):
22+
return x
23+
else:
24+
import codecs
25+
26+
def b(x):
27+
return codecs.latin_1_encode(x)[0]
28+
29+
def un_b(x):
30+
return codecs.latin_1_decode(x)[0]
31+
1632

1733
class KVStore(object):
1834
"""An abstract key-value interface with support for range iteration."""
@@ -244,7 +260,7 @@ def __init__(self, path):
244260
self.conn = sqlite3.connect(path)
245261

246262
# Don't create unicode objects for retrieved values
247-
self.conn.text_factory = buffer
263+
self.conn.text_factory = memoryview
248264

249265
# Disable the SQLite cache. Its pages tend to get swapped
250266
# out, even if the database file is in buffer cache.
@@ -284,15 +300,16 @@ def get(self, key, default=None):
284300
q = "SELECT value FROM kv WHERE key = ?"
285301
c = self.conn.cursor()
286302

287-
row = c.execute(q, (sqlite3.Binary(key),)).fetchone()
303+
row = c.execute(q, (sqlite3.Binary(b(key)),)).fetchone()
288304
if not row:
289305
return default
290306

291-
return bytes(row[0])
307+
return un_b(bytes(row[0]))
292308

293309
def put(self, key, value):
294310
q = "INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)"
295-
self.conn.execute(q, (sqlite3.Binary(key), sqlite3.Binary(value)))
311+
self.conn.execute(q,
312+
(sqlite3.Binary(b(key)), sqlite3.Binary(b(value))))
296313
self.conn.commit()
297314

298315
def put_many(self, items):
@@ -301,14 +318,15 @@ def put_many(self, items):
301318

302319
blob = sqlite3.Binary
303320
for batch in ibatch(items, 30000):
304-
items = ((blob(key), blob(value)) for key, value in batch)
321+
items = ((blob(b(key)), blob(b(value)))
322+
for key, value in batch)
305323

306324
c.executemany(q, items)
307325
self.conn.commit()
308326

309327
def delete(self, key):
310328
q = "DELETE FROM kv WHERE key = ?"
311-
self.conn.execute(q, (sqlite3.Binary(key),))
329+
self.conn.execute(q, (sqlite3.Binary(b(key)),))
312330
self.conn.commit()
313331

314332
def delete_many(self, keys):
@@ -317,19 +335,23 @@ def delete_many(self, keys):
317335

318336
blob = sqlite3.Binary
319337
for batch in ibatch(keys, 30000):
320-
items = ((blob(key),) for key in batch)
338+
items = ((blob(b(key)),) for key in batch)
321339

322340
c.executemany(q, items)
323341
self.conn.commit()
324342

325343
def _range_where(self, key_from=None, key_to=None):
326344
if key_from is not None and key_to is None:
345+
key_from = b(key_from)
327346
return "WHERE key >= :key_from"
328347

329348
if key_from is None and key_to is not None:
349+
key_to = b(key_to)
330350
return "WHERE key <= :key_to"
331351

332352
if key_from is not None and key_to is not None:
353+
key_from = b(key_from)
354+
key_to = b(key_to)
333355
return "WHERE key BETWEEN :key_from AND :key_to"
334356

335357
return ""
@@ -339,25 +361,25 @@ def items(self, key_from=None, key_to=None):
339361
% self._range_where(key_from, key_to)
340362

341363
if key_from is not None:
342-
key_from = sqlite3.Binary(key_from)
364+
key_from = sqlite3.Binary(b(key_from))
343365

344366
if key_to is not None:
345-
key_to = sqlite3.Binary(key_to)
367+
key_to = sqlite3.Binary(b(key_to))
346368

347369
c = self.conn.cursor()
348370
for key, value in c.execute(q, dict(key_from=key_from, key_to=key_to)):
349-
yield bytes(key), bytes(value)
371+
yield un_b(bytes(key)), un_b(bytes(value))
350372

351373
def keys(self, key_from=None, key_to=None):
352374
q = "SELECT key FROM kv %s ORDER BY key " \
353375
% self._range_where(key_from, key_to)
354376

355377
if key_from is not None:
356-
key_from = sqlite3.Binary(key_from)
378+
key_from = sqlite3.Binary(b(key_from))
357379

358380
if key_to is not None:
359-
key_to = sqlite3.Binary(key_to)
381+
key_to = sqlite3.Binary(b(key_to))
360382

361383
c = self.conn.cursor()
362384
for key, in c.execute(q, dict(key_from=key_from, key_to=key_to)):
363-
yield bytes(key)
385+
yield un_b(bytes(key))

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# Load the test requirements. These are in a separate file so they can
1212
# be accessed from Travis CI and tox.
1313
with open("test-requirements.txt") as fd:
14-
tests_require = list(fd.xreadlines())
14+
tests_require = list(fd)
1515

1616

1717
setup(
@@ -25,7 +25,7 @@
2525
py_modules=["park"],
2626

2727
setup_requires=[
28-
"unittest2==0.5.1"
28+
"unittest2==1.1.0"
2929
],
3030

3131
test_suite="unittest2.collector",

test-requirements.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
coverage==3.5.2
2-
pep8==1.3.3
3-
pyflakes==0.5.0
1+
coverage==4.0
2+
pep8==1.6.2
3+
pyflakes==1.0.0

test_park.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# coding: utf-8
2-
# Copyright 2012 litl, LLC. All Rights Reserved.
2+
# Copyright 2012-2015 litl, LLC. All Rights Reserved.
33

44
import operator
55
import os
@@ -189,12 +189,12 @@ def test_items(self):
189189
("nine", "value9")
190190
])
191191

192-
for key, value in put_items.items():
192+
for key, value in list(put_items.items()):
193193
self.store.put(key, value)
194194

195195
# Sorted order is: eight five four nine one seven six three two
196196
keys = list(self.store.items())
197-
expected = sorted(put_items.items(), key=operator.itemgetter(0))
197+
expected = sorted(list(put_items.items()), key=operator.itemgetter(0))
198198
self.assertEqual(expected, keys)
199199

200200
# Test key_from on keys that are present and missing in the db
@@ -260,7 +260,7 @@ def test_context_manager(self):
260260

261261
class TestIbatch(unittest.TestCase):
262262
def test_ibatch(self):
263-
items = range(10)
263+
items = list(range(10))
264264

265265
batches = park.ibatch(items, 3)
266266

tox.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = py26, py27
2+
envlist = py27, py34
33

44
[testenv]
55
deps=

0 commit comments

Comments
 (0)