~variety/variety-slideshow/master

« back to all changes in this revision

Viewing changes to variety/AttrDict.py

  • Committer: Peter Levi
  • Date: 2016-01-19 10:23:10 UTC
  • Revision ID: git-v1:8904a675f26dbc14667560230ea823ada75049fa
Moved AttrDict into varietyslideshow package so it doesn't cause conflicts with Variety

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2
 
### BEGIN LICENSE
3
 
# Copyright (c) 2012, Peter Levi <peterlevi@peterlevi.com>
4
 
# This program is free software: you can redistribute it and/or modify it 
5
 
# under the terms of the GNU General Public License version 3, as published 
6
 
# by the Free Software Foundation.
7
 
8
 
# This program is distributed in the hope that it will be useful, but 
9
 
# WITHOUT ANY WARRANTY; without even the implied warranties of 
10
 
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
11
 
# PURPOSE.  See the GNU General Public License for more details.
12
 
13
 
# You should have received a copy of the GNU General Public License along 
14
 
# with this program.  If not, see <http://www.gnu.org/licenses/>.
15
 
### END LICENSE
16
 
 
17
 
from collections import defaultdict
18
 
import json
19
 
 
20
 
 
21
 
class AttrDict(defaultdict):
22
 
    @staticmethod
23
 
    def converted(v):
24
 
        if isinstance(v, AttrDict):
25
 
            return v
26
 
        elif isinstance(v, dict):
27
 
            return AttrDict(v)
28
 
        elif isinstance(v, (list, tuple)):
29
 
            r = map(AttrDict.converted, v)
30
 
            return tuple(r) if isinstance(v, tuple) else r
31
 
        else:
32
 
            return v
33
 
 
34
 
    def merge(self, arg):
35
 
        if hasattr(arg, 'iteritems'):
36
 
            self.merge(arg.iteritems())
37
 
        else:
38
 
            for k, v in arg:
39
 
                self[k] = AttrDict.converted(v)
40
 
 
41
 
    def asdict(self):
42
 
        return json.loads(json.dumps(self))
43
 
 
44
 
    def __init__(self, *args, **kwargs):
45
 
        super(AttrDict, self).__init__(AttrDict)
46
 
        if len(args) == 1:
47
 
            self.merge(args[0])
48
 
        elif len(args) > 1:
49
 
            raise TypeError("AttrDict expected at most 1 argument that is a map, got %i" % len(args))
50
 
        self.merge(kwargs)
51
 
 
52
 
    def __setitem__(self, k, v):
53
 
        return super(AttrDict, self).__setitem__(k, AttrDict.converted(v))
54
 
 
55
 
    __getattr__ = defaultdict.__getitem__
56
 
    __setattr__ = __setitem__
57
 
 
58
 
 
59
 
 
60
 
if __name__ == "__main__":
61
 
    a = AttrDict({'a': {'b':1}})
62
 
    assert not bool(a.deep.inside)
63
 
    assert bool(a.a)
64
 
    assert a.a.b == 1
65
 
    a.l.k = 3
66
 
    assert a.l.k == 3
67
 
    a.f.g.h = 2
68
 
    assert a.f.g.h == 2
69
 
    a["x"]["y"]["z"] = 1
70
 
    assert a["x"]["y"]["z"] == 1
71
 
 
72
 
    b = AttrDict(x=1, y=2)
73
 
    assert not bool(b.deep.inside)
74
 
    assert b.x == 1
75
 
    assert b.y == 2
76
 
 
77
 
    b.c = {'z': 3}
78
 
    assert b.c.z == 3
79
 
    assert not bool(b.c.dredrefre)