From 46a7e5d443757dedaaff4f6b1b8ae5e020210e0e Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 8 Nov 2016 00:22:02 +0100 Subject: [PATCH 1/3] Added license file --- LICENSE | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8552857 --- /dev/null +++ b/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2016 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From fc91dff1618427c573329d0d432ba470df84053d Mon Sep 17 00:00:00 2001 From: MWK Date: Sun, 2 Apr 2017 17:57:31 +0200 Subject: [PATCH 2/3] Implemented a function to make a full datastructure recursively more Pythonic --- phpserialize.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/phpserialize.py b/phpserialize.py index 036cfb4..208156e 100644 --- a/phpserialize.py +++ b/phpserialize.py @@ -283,7 +283,7 @@ class WP_User extends WP_UserBase { xrange = range __author__ = 'Armin Ronacher ' -__version__ = '1.3' +__version__ = '1.4' __all__ = ('phpobject', 'convert_member_dict', 'dict_to_list', 'dict_to_tuple', 'load', 'loads', 'dump', 'dumps', 'serialize', 'unserialize') @@ -549,6 +549,35 @@ def dict_to_list(d): except KeyError: raise ValueError('dict is not a sequence') +def full_dict_to_list(d, array_hook=dict): + """Converts a full dict into a more Pythonic structure. In particular ensure that all list-like structures are handled as Python lists + Examples: + + d1 = {'a': 'b', 'c': {0: '1', 1: '2', 2: {'e': 7}, 3: {2: 8}}} + full_dict_to_list(d1) returns + {'a': 'b', 'c': ['1', '2', {'e': 7}, {2: 8}]} + + d2 = OrderedDict({'a': 'b', 'c': OrderedDict({0: '1', 1: '2', 2: OrderedDict({'e': 7}), 3: OrderedDict({2: 8})})}) + full_dict_to_list(d2, OrderedDict) returns + OrderedDict([('a', 'b'), ('c', ['1', '2', OrderedDict([('e', 7)]), OrderedDict([(2, 8)])])]) + """ + if type(d) is array_hook: + keys = list(d.keys()) + + if keys == list(range(0, len(keys))): #Any array with keys 0..N is considered to be a list + return [full_dict_to_list(val) for val in d.values()] + elif len(keys) == 1: + key = keys[0] + return {key : full_dict_to_list(d[key], array_hook)} + else: + tmp_dict = array_hook() + for key in keys: + tmp_dict.update( {key : full_dict_to_list(d[key], array_hook)} ) + return tmp_dict + else: + return d + + def dict_to_tuple(d): """Converts an ordered dict into a tuple.""" From 770e17a132a2d1d6c37296122283d2374622b7c8 Mon Sep 17 00:00:00 2001 From: MWK Date: Sun, 2 Apr 2017 21:07:35 +0200 Subject: [PATCH 3/3] Added tests for full_dict_to_list --- tests.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests.py b/tests.py index f6d7066..0deec9c 100644 --- a/tests.py +++ b/tests.py @@ -99,6 +99,18 @@ def test_basic_object_hook(self): self.assertEqual(user.username, 'admin') self.assertEqual(user.__name__, 'WP_User') + def test_full_dict_to_list(self): + #with normal dict + d1 = {'a': 'b', 'c': {0: '1', 1: '2', 2: {'e': 7}, 3: {2: 8}}} + d1_cleaned = {'a': 'b', 'c': ['1', '2', {'e': 7}, {2: 8}]} + self.assertEqual(phpserialize.full_dict_to_list(d1), d1_cleaned) + + #with OrderedDict as array_hook + from collections import OrderedDict + d2 = OrderedDict({'a': 'b', 'c': OrderedDict({0: '1', 1: '2', 2: OrderedDict({'e': 7}), 3: OrderedDict({2: 8})})}) + d2_cleaned = OrderedDict([('a', 'b'), ('c', ['1', '2', OrderedDict([('e', 7)]), OrderedDict([(2, 8)])])]) + self.assertEqual(phpserialize.full_dict_to_list(d2, OrderedDict), d2_cleaned) + if __name__ == '__main__': unittest.main()