~doctormo/+junk/css-parser

« back to all changes in this revision

Viewing changes to csslavie/objects.py

  • Committer: Martin Owens
  • Date: 2014-07-13 21:48:23 UTC
  • Revision ID: doctormo@gmail.com-20140713214823-774n9vbbhw93zlbh
Move the files around and add some simple events

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright 2012-2014 Martin Owens <doctormo@gmail.com>
 
3
# Copyright      2014 Ian Denhardt <ian@zenhack.net>
 
4
#
 
5
# This program is free software: you can redistribute it and/or modify
 
6
#  it under the terms of the GNU General Public License as published by
 
7
#  the Free Software Foundation, either version 3 of the License, or
 
8
#  (at your option) any later version.
 
9
#
 
10
#  This program is distributed in the hope that it will be useful,
 
11
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
#  GNU General Public License for more details.
 
14
#
 
15
#  You should have received a copy of the GNU General Public License
 
16
#  along with this program.  If not, see <http://www.gnu.org/licenses/>
 
17
#
 
18
"""
 
19
The idea here is to provide a machanism for getting attributes at the right time.
 
20
 
 
21
Should provide stateful attribute access and some signal support for changes.
 
22
"""
 
23
 
 
24
from .base import DefaultOrderedDict, Event
 
25
from collections import defaultdict
 
26
 
 
27
class PropertyObject(object):
 
28
    """Property objects control system of layered property dictionaries,
 
29
       attributes returned are from the top most stack with that item key
 
30
 
 
31
    ! Keeping the user attributes ahead of the pack is trouble. Is this useful?
 
32
 
 
33
    """
 
34
    def __new__(cls, *p, **k):
 
35
        inst = object.__new__(cls)
 
36
        inst.__attrs__ = DefaultOrderedDict(dict)
 
37
        inst.__watch__ = defaultdict(Event)
 
38
        return inst
 
39
 
 
40
    def __init__(self, name=None, classes=None):
 
41
        self.name = name
 
42
        self.classes = classes
 
43
 
 
44
    def __setattr__(self, name, value):
 
45
        if name[0] != '_':
 
46
            self.__attrs__['user'][name] = value
 
47
        object.__setattr__(self, name, value)
 
48
 
 
49
    def __delattr__(self, name):
 
50
        if name[0] != '_' and name in self.__attrs__['user']:
 
51
            self.__attrs__['user'].pop(name)
 
52
        self.refresh([name])
 
53
 
 
54
    def add_to(self, d, name='base'):
 
55
        reorder = name not in self.__attrs__
 
56
 
 
57
        self.__attrs__[name].update(d)
 
58
        if reorder:
 
59
            self.__attrs__.sort_to_end('user')
 
60
 
 
61
        self.__dict__.update(d)
 
62
 
 
63
        if 'user' in self.__attrs__:
 
64
            self.__dict__.update(self.__attrs__['user'])
 
65
 
 
66
    def remove(self, name):
 
67
        old = self.__attrs__.pop(name)
 
68
        self.refresh(old.keys())
 
69
 
 
70
    def refresh(self, keys=None):
 
71
        keys = keys or self.__attrs__.super_keys()
 
72
        self.__dict__.update(self.__attrs__.super_gets(keys))
 
73
 
 
74
    def watch(self, callback, name, value=None, callback_off=None):
 
75
        """A single watcher for attribute changes... can also detect on/off switching"""
 
76
        self.__watch__[name] += callback
 
77
 
 
78
 
 
79