fixed issue 1393, cast_keys in dict for python 2.5 support, thanks Alan and Niphlod

This commit is contained in:
mdipierro
2013-03-17 12:11:10 -05:00
parent cd967d2551
commit c9a63a8524
4 changed files with 80 additions and 11 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.4.4-stable+timestamp.2013.03.16.20.52.38
Version 2.4.4-stable+timestamp.2013.03.17.12.10.29
+27 -7
View File
@@ -7054,15 +7054,13 @@ class DAL(object):
Example::
db = DAL('sqlite://test.db')
or
db = DAL({"uri": ..., "items": ...}) # experimental
db.define_table('tablename', Field('fieldname1'),
Field('fieldname2'))
(experimental)
you can pass a dict object as uri with the uri string
and table/field definitions. For an example of valid data check
the output of:
>>> db.as_dict(flat=True, sanitize=False)
"""
def __new__(cls, uri='sqlite://dummy.db', *args, **kwargs):
@@ -7183,6 +7181,28 @@ class DAL(object):
:uri: string that contains information for connecting to a database.
(default: 'sqlite://dummy.db')
experimental: you can specify a dictionary as uri
parameter i.e. with
db = DAL({"uri": "sqlite://storage.sqlite",
"items": {...}, ...})
for an example of dict input you can check the output
of the scaffolding db model with
db.as_dict()
Note that for compatibility with Python older than
version 2.6.5 you should cast your dict input keys
to str due to a syntax limitation on kwarg names.
for proper DAL dictionary input you can use one of:
obj = serializers.cast_keys(dict, [encoding="utf-8"])
or else (for parsing json input)
obj = serializers.loads_json(data, unicode_keys=False)
:pool_size: How many open connections to make to the database object.
:folder: where .table files will be created.
automatically set within web2py
+45 -2
View File
@@ -25,9 +25,52 @@ try:
except ImportError:
have_yaml = False
def loads_json(o):
def cast_keys(o, cast=str, encoding="utf-8"):
""" Builds a new object with <cast> type keys
Arguments:
o is the object input
cast (defaults to str) is an object type or function
which supports conversion such as:
>>> converted = cast(o)
encoding (defaults to utf-8) is the encoding for unicode
keys. This is not used for custom cast functions
Use this funcion if you are in Python < 2.6.5
This avoids syntax errors when unpacking dictionary arguments.
"""
if isinstance(o, (dict, Storage)):
if isinstance(o, dict):
newobj = dict()
else:
newobj = Storage()
for k, v in o.items():
if (cast == str) and isinstance(k, unicode):
key = k.encode(encoding)
else:
key = cast(k)
if isinstance(v, (dict, Storage)):
value = cast_keys(v, cast=cast, encoding=encoding)
else:
value = v
newobj[key] = value
else:
raise TypeError("Cannot cast keys: %s is not supported" % \
type(o))
return newobj
def loads_json(o, unicode_keys=True, **kwargs):
# deserialize a json string
return json_parser.loads(o)
result = json_parser.loads(o, **kwargs)
if not unicode_keys:
# filter non-str keys in dictionary objects
result = cast_keys(result,
encoding=kwargs.get("encoding", "utf-8"))
return result
def custom_json(o):
if hasattr(o, 'custom_json') and callable(o.custom_json):
+7 -1
View File
@@ -7,6 +7,7 @@
import sys
import os
import glob
if os.path.isdir('gluon'):
sys.path.append(os.path.realpath('gluon'))
else:
@@ -659,7 +660,12 @@ class TestDALDictImportExport(unittest.TestCase):
import serializers
dbjson = db.as_json(sanitize=False)
assert isinstance(dbjson, basestring) and len(dbjson) > 0
db3 = DAL(serializers.loads_json(dbjson))
unicode_keys = True
if sys.version < "2.6.5":
unicode_keys = False
db3 = DAL(serializers.loads_json(dbjson,
unicode_keys=unicode_keys))
assert hasattr(db3, "person") and hasattr(db3.person, "uuid") and\
db3.person.uuid.type == db.person.uuid.type
db3.person.drop()