settings.py 19.1 KB
Newer Older
1 2 3 4 5 6 7
# -*- coding: utf-8 -*-
#
# This file is part of the bliss project
#
# Copyright (c) 2016 Beamline Control Unit, ESRF
# Distributed under the GNU LGPLv3. See LICENSE for more info.

8
from .conductor import client
9
from bliss.common.utils import Null
Matias Guijarro's avatar
Matias Guijarro committed
10 11 12 13
import weakref
import pickle

def get_cache():
14
    return client.get_cache(db=0)
Matias Guijarro's avatar
Matias Guijarro committed
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

def boolify(s,**keys):
    if s == 'True' or s == 'true':
            return True
    if s == 'False' or s == 'false':
            return False
    raise ValueError('Not Boolean Value!')

def auto_conversion(var):
    '''guesses the str representation of the variables type'''
    if var is None:
        return None
    for caster in (boolify,int, float):
        try:
            return caster(var)
        except ValueError:
            pass
    return var

34
def pickle_loads(var):
Matias Guijarro's avatar
Matias Guijarro committed
35 36 37 38 39 40 41 42 43 44 45 46
    if var is None:
        return None
    return pickle.loads(var)

def ttl_func(cnx,name,value = -1):
    if value is None:
        return cnx.persist(name)
    elif value is -1:
        return cnx.ttl(name)
    else:
        return cnx.expire(name,value)

47 48
def read_decorator(func):
    def _read(self,*args,**keys):
Matias Guijarro's avatar
Matias Guijarro committed
49 50
        value = func(self,*args,**keys)
        if self._read_type_conversion:
51
            if isinstance(value,list):
Matias Guijarro's avatar
Matias Guijarro committed
52
                value = [self._read_type_conversion(x) for x in value]
53
            elif isinstance(value,dict):
Matias Guijarro's avatar
Matias Guijarro committed
54 55
                for k,v in value.iteritems():
                    value[k] = self._read_type_conversion(v)
56 57 58 59
                if hasattr(self,'default_values') and isinstance(self.default_values,dict):
                    tmp = dict(self._default_values)
                    tmp.update(value)
                    value = tmp
Matias Guijarro's avatar
Matias Guijarro committed
60 61
            else:
                value = self._read_type_conversion(value)
62 63 64 65 66 67
        if value is None:
            if hasattr(self,'_default_value'):
                value = self._default_value
            elif(hasattr(self,'_default_values') and 
                 hasattr(self._default_values,'get')):
                value = self._default_values.get(args[0])
Matias Guijarro's avatar
Matias Guijarro committed
68 69 70
        return value
    return _read

71 72
def write_decorator_dict(func):
    def _write(self,values,**keys):
Matias Guijarro's avatar
Matias Guijarro committed
73 74 75 76 77 78 79 80 81 82
        if self._write_type_conversion:
            if not isinstance(values,dict) and values is not None:
                raise TypeError('can only be dict')

            if values is not None:
                for k,v in values.iteritems():
                    values[k] = self._write_type_conversion(v)
        return func(self,values,**keys)
    return _write

83
def write_decorator_multiple(func):
Matias Guijarro's avatar
Matias Guijarro committed
84 85 86 87 88 89 90 91 92
    def _write(self,values,**keys):
        if self._write_type_conversion:
            if not isinstance(values,(list,tuple)) and values is not None:
                raise TypeError('can only be tuple or list')
            if values is not None:
                values = [self._write_type_conversion(x) for x in values]
        return func(self,values,**keys)
    return _write

93
def write_decorator(func):
Matias Guijarro's avatar
Matias Guijarro committed
94 95 96 97 98 99
    def _write(self,value,**keys):
        if self._write_type_conversion and value is not None:
            value = self._write_type_conversion(value)
        return func(self,value,**keys)
    return _write

100
class SimpleSetting(object):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
101 102
    def __init__(self,name,connection = None,
                 read_type_conversion = auto_conversion,
103
                 write_type_conversion = None,
104
                 default_value = None):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
105 106 107 108 109 110
        if connection is None:
            connection = get_cache()
        self._cnx = weakref.ref(connection)
        self._name = name
        self._read_type_conversion = read_type_conversion
        self._write_type_conversion = write_type_conversion
111
        self._default_value = default_value
Matias Guijarro's avatar
Matias Guijarro committed
112

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
113
    @read_decorator
114
    def get(self):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
115 116 117 118 119
        cnx = self._cnx()
        value = cnx.get(self._name)
        return value

    @write_decorator
120
    def set(self,value):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
121 122 123 124 125 126
        cnx = self._cnx()
        cnx.set(self._name,value)

    def ttl(self,value = -1):
        return ttl_func(self._cnx(),self._name,value)

127
    def __add__(self,other):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
128
        value = self.get()
129
        if isinstance(other,SimpleSetting):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
130 131 132 133 134 135
            other = other.get()
        return value + other

    def __iadd__(self,other):
        cnx = self._cnx()
        if cnx is not None:
136
            if isinstance(other,int):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
137 138
                if other == 1:
                    cnx.incr(self._name)
Matias Guijarro's avatar
Matias Guijarro committed
139
                else:
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
140
                    cnx.incrby(self._name,other)
141
            elif isinstance(other,float):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
142 143 144 145
                cnx.incrbyfloat(self._name,other)
            else:
                cnx.append(self._name,other)
            return self
Matias Guijarro's avatar
Matias Guijarro committed
146

147
    def __isub__(self,other):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
148 149 150
        if isinstance(other,basestring):
            raise TypeError("unsupported operand type(s) for -=: %s" % type(other).__name__)
        return self.__iadd__(-other)
Matias Guijarro's avatar
Matias Guijarro committed
151

152
    def __getitem__(self,ran):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
        cnx = self._cnx()
        if cnx is not None:
            step = None
            if isinstance(ran,slice):
                i,j = ran.start,ran.stop
                step = ran.step
            elif isinstance(ran,int):
                i = j = ran
            else:
                raise TypeError('indices must be integers')

            value = cnx.getrange(self._name,i,j)
            if step is not None:
                value = value[0:-1:step]
            return value


    def __repr__(self):
        cnx = self._cnx()
        value = cnx.get(self._name)
173
        return '<SimpleSetting name=%s value=%s>' % (self._name,value)
Matias Guijarro's avatar
Matias Guijarro committed
174

175
class SimpleSettingProp(object):
Matias Guijarro's avatar
Matias Guijarro committed
176 177 178
    def __init__(self,name,connection = None,
                 read_type_conversion = auto_conversion,
                 write_type_conversion = None,
179
                 default_value = None,
180
                 use_object_name = True):
Matias Guijarro's avatar
Matias Guijarro committed
181 182 183 184
        self._name = name
        self._cnx = connection or get_cache()
        self._read_type_conversion = read_type_conversion
        self._write_type_conversion = write_type_conversion
185
        self._default_value = default_value
Matias Guijarro's avatar
Matias Guijarro committed
186 187
        self._use_object_name = use_object_name

188
    def __get__(self,obj,type = None):
Matias Guijarro's avatar
Matias Guijarro committed
189 190 191 192
        if self._use_object_name:
            name = obj.name + ':' + self._name
        else:
            name = self._name
193 194 195 196
        return SimpleSetting(name,self._cnx,
                             self._read_type_conversion,
                             self._write_type_conversion,
                             self._default_value)
Matias Guijarro's avatar
Matias Guijarro committed
197

198
    def __set__(self,obj,value):
199
        if isinstance(value,SimpleSetting): return
Matias Guijarro's avatar
Matias Guijarro committed
200 201 202 203 204 205 206 207 208 209 210 211 212 213

        if self._use_object_name:
            name = obj.name + ':' + self._name
        else:
            name = self._name

        if value is None:
            self._cnx.delete(name)
        else:
            if self._write_type_conversion:
                value = self._write_type_conversion(value)
            self._cnx.set(name,value)

class QueueSetting(object):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
214 215
    def __init__(self,name,connection = None,
                 read_type_conversion = auto_conversion,
216
                 write_type_conversion = None):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
217 218 219 220 221
        if connection is None: connection = get_cache()
        self._cnx = weakref.ref(connection)
        self._name = name
        self._read_type_conversion = read_type_conversion
        self._write_type_conversion = write_type_conversion
Matias Guijarro's avatar
Matias Guijarro committed
222

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
223
    @read_decorator
224
    def get(self,first=0,last=-1):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
225 226 227 228 229 230
        cnx = self._cnx()
        if first == last:
            l = cnx.lindex(self._name,first)
        else:
            l = cnx.lrange(self._name,first,last)
        return l
Matias Guijarro's avatar
Matias Guijarro committed
231

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
232
    @write_decorator
233
    def append(self,value):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
234
        cnx = self._cnx()
235
        return cnx.rpush(self._name,value)
Matias Guijarro's avatar
Matias Guijarro committed
236

237 238 239 240
    def clear(self):
        cnx = self._cnx()
        cnx.delete(self._name)

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
241
    @write_decorator
242
    def prepend(self,value):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
243
        cnx = self._cnx()
244
        return cnx.lpush(self._name,value)
Matias Guijarro's avatar
Matias Guijarro committed
245

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
246
    @write_decorator_multiple
247
    def extend(self,values):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
248
        cnx = self._cnx()
249
        return cnx.rpush(self._name,*values)
Matias Guijarro's avatar
Matias Guijarro committed
250

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
251
    @write_decorator
252
    def remove(self,value):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
253 254
        cnx = self._cnx()
        cnx.lrem(self._name,1,value)
Matias Guijarro's avatar
Matias Guijarro committed
255

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
256
    @write_decorator_multiple
257
    def set(self,values):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
258 259
        if not isinstance(values,(list,tuple)) and values is not None:
            raise TypeError('can only be tuple or list')
Matias Guijarro's avatar
Matias Guijarro committed
260

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
261 262 263 264
        cnx = self._cnx()
        cnx.delete(self._name)
        if values is not None:
            cnx.rpush(self._name,*values)
Matias Guijarro's avatar
Matias Guijarro committed
265

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
266
    @write_decorator
267
    def set_item(self,value,pos = 0):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
268 269
        cnx = self._cnx()
        cnx.lset(self._name,pos,value)
Matias Guijarro's avatar
Matias Guijarro committed
270

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
271
    @read_decorator
272
    def pop_front(self):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
273 274 275 276 277 278 279
        cnx = self._cnx()
        value = cnx.lpop(self._name)
        if self._read_type_conversion:
            value = self._read_type_conversion(value)
        return value

    @read_decorator
280
    def pop_back(self):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
281 282 283 284 285 286 287 288 289
        cnx = self._cnx()
        value = cnx.rpop(self._name)
        if self._read_type_conversion:
            value = self._read_type_conversion(value)
        return value

    def ttl(self,value = -1):
        return ttl_func(self._cnx(),self._name,value)

290
    def __len__(self):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
291 292 293
        cnx = self._cnx()
        return cnx.llen(self._name)

294
    def __repr__(self):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
295 296
        cnx = self._cnx()
        value = cnx.lrange(self._name,0,-1)
297
        return '<QueueSetting name=%s value=%s>' % (self._name,value)
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
298 299 300 301 302

    def __iadd__(self,other):
        self.extend(other)
        return self

303
    def __getitem__(self,ran):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
304
        if isinstance(ran,slice):
305 306
            i = ran.start is not None and ran.start or 0
            j = ran.stop is not None and ran.stop or -1
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
307 308 309 310
        elif isinstance(ran,int):
            i = j = ran
        else:
            raise TypeError('indices must be integers')
311 312 313 314 315
        value = self.get(first = i,last = j)
        if value is None:
            raise StopIteration
        else:
            return value
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
316

317
    def __iter__(self):
318 319
        cnx = self._cnx()
        lsize = cnx.llen(self._name)
320
        for first in xrange(0,lsize,1024):
321 322 323 324 325
            last = first + 1024
            if last >= lsize: last = -1
            for value in self.get(first,last):
                yield value
        
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
326
    def __setitem__(self,ran,value):
327 328
        if isinstance(ran,slice):
            for i,v in zip(range(ran.start,ran.stop),value):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
329 330 331 332 333 334 335 336
                self.set_item(v,pos=i)
        elif isinstance(ran,int):
            self.set_item(value,pos=ran)
        else:
            raise TypeError('indices must be integers')
        return self

class QueueSettingProp(object):
Matias Guijarro's avatar
Matias Guijarro committed
337 338 339
    def __init__(self,name,connection = None,
                 read_type_conversion = auto_conversion,
                 write_type_conversion = None,
340
                 use_object_name = True):
Matias Guijarro's avatar
Matias Guijarro committed
341 342 343 344 345 346
        self._name = name
        self._cnx = connection or get_cache()
        self._read_type_conversion = read_type_conversion
        self._write_type_conversion = write_type_conversion
        self._use_object_name = use_object_name

347
    def __get__(self,obj,type = None):
Matias Guijarro's avatar
Matias Guijarro committed
348 349 350 351 352
        if self._use_object_name:
            name = obj.name + ':' + self._name
        else:
            name = self._name

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
353 354 355
        return QueueSetting(name,self._cnx,
                            self._read_type_conversion,
                            self._write_type_conversion)
Matias Guijarro's avatar
Matias Guijarro committed
356

357
    def __set__(self,obj,values):
358
        if isinstance(values,QueueSetting): return
Matias Guijarro's avatar
Matias Guijarro committed
359 360 361 362 363 364

        if self._use_object_name:
            name = obj.name + ':' + self._name
        else:
            name = self._name

Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
365 366 367
        proxy = QueueSetting(name,self._cnx,
                             self._read_type_conversion,
                             self._write_type_conversion)
Matias Guijarro's avatar
Matias Guijarro committed
368 369 370 371 372
        proxy.set(values)

class HashSetting(object):
    def __init__(self,name,connection=None,
                 read_type_conversion=auto_conversion,
373 374
                 write_type_conversion=None,
                 default_values = {}):
Matias Guijarro's avatar
Matias Guijarro committed
375 376 377 378 379 380
        if connection is None:
            connection = get_cache()
        self._cnx = weakref.ref(connection)
        self._name = name
        self._read_type_conversion = read_type_conversion
        self._write_type_conversion = write_type_conversion
381
        self._default_values = default_values
Matias Guijarro's avatar
Matias Guijarro committed
382

383 384
    def __repr__(self):
        value = self.get_all()
Matias Guijarro's avatar
Matias Guijarro committed
385
        return '<HashSetting name=%s value=%s>' % (self._name,value)
386
    
387
    def __delitem__(self,key):
388 389
        cnx = self._cnx()
        cnx.hdel(self._name,key)
Matias Guijarro's avatar
Matias Guijarro committed
390

391
    def __len__(self):
Matias Guijarro's avatar
Matias Guijarro committed
392 393 394 395 396 397 398
        cnx = self._cnx()
        return cnx.hlen(self._name)

    def ttl(self,value = -1):
        return ttl_func(self._cnx(),self._name,value)

    @read_decorator
399
    def get(self,key,default = None):
Matias Guijarro's avatar
Matias Guijarro committed
400
        cnx = self._cnx()
401 402 403 404
        return_val = cnx.hget(self._name,key)
        if return_val is None:
            return_val = default
        return return_val
Matias Guijarro's avatar
Matias Guijarro committed
405 406

    @read_decorator
407 408 409 410 411 412 413 414 415 416
    def pop(self,key,default = Null()):
        cnx = self._cnx().pipeline()
        cnx.hget(self._name,key)
        cnx.hdel(self._name,key)
        (value,worked) = cnx.execute()
        if not worked:
            if isinstance(default,Null):
                raise KeyError(key)
            else:
                value = default
Matias Guijarro's avatar
Matias Guijarro committed
417 418
        return value
    
419
    def remove(self,key):
Matias Guijarro's avatar
Matias Guijarro committed
420 421 422 423 424 425 426 427
        cnx = self._cnx()
        cnx.hdel(self._name,key)

    @read_decorator
    def get_all(self):
        cnx = self._cnx()
        return cnx.hgetall(self._name)
    
428
    def keys(self):
429
        return list(self.iterkeys())
Matias Guijarro's avatar
Matias Guijarro committed
430

431
    def values(self):
432
        return list(self.itervalues())
Matias Guijarro's avatar
Matias Guijarro committed
433

434
    def clear(self):
Matias Guijarro's avatar
Matias Guijarro committed
435 436 437
        cnx = self._cnx()
        cnx.delete(self._name)

438
    def copy(self):
Matias Guijarro's avatar
Matias Guijarro committed
439 440 441
        return self.get()

    @write_decorator_dict
442
    def set(self,values):
Matias Guijarro's avatar
Matias Guijarro committed
443 444 445 446 447 448
        cnx = self._cnx()
        cnx.delete(self._name)
        if values is not None:
            cnx.hmset(self._name,values)

    @write_decorator_dict
449
    def update(self,values):
Matias Guijarro's avatar
Matias Guijarro committed
450 451 452
        cnx = self._cnx()
        cnx.hmset(self._name,values)

453
    def items(self):
Matias Guijarro's avatar
Matias Guijarro committed
454 455 456 457
        values = self.get_all()
        return [(k,v) for k,v in values.iteritems()]

    @read_decorator
458
    def fromkeys(self,keys):
Matias Guijarro's avatar
Matias Guijarro committed
459 460 461
        cnx = self._cnx()
        return cnx.hmget(self._name,keys)
    
462
    def has_key(self,key):
Matias Guijarro's avatar
Matias Guijarro committed
463
        cnx = self._cnx()
464
        return cnx.hexists(self._name,key) or self._default_values.has_key(key)
Matias Guijarro's avatar
Matias Guijarro committed
465 466
    
    def iterkeys(self):
467 468 469
        for k,v in self.iteritems():
            yield k

Matias Guijarro's avatar
Matias Guijarro committed
470
    def itervalues(self):
471 472
        for k,v in self.iteritems():
            yield v
Matias Guijarro's avatar
Matias Guijarro committed
473

474
    def iteritems(self):
Matias Guijarro's avatar
Matias Guijarro committed
475 476
        cnx = self._cnx()
        next_id = 0
477
        seen_keys = set()
Matias Guijarro's avatar
Matias Guijarro committed
478 479 480 481 482
        while True:
            next_id,pd = cnx.hscan(self._name,next_id)
            for k,v in pd.iteritems():
                if self._read_type_conversion:
                    v = self._read_type_conversion(v)
483
                seen_keys.add(k)
Matias Guijarro's avatar
Matias Guijarro committed
484
                yield k,v
485
            if not next_id or next_id is '0':
Matias Guijarro's avatar
Matias Guijarro committed
486 487
                break

488 489 490 491
        for k,v in self._default_values.iteritems():
            if k in seen_keys: continue
            yield k,v

Matias Guijarro's avatar
Matias Guijarro committed
492 493 494 495 496 497
    def __getitem__(self,key):
        value = self.get(key)
        if value is None:
            raise KeyError(key)
        return value

498
    def __setitem__(self,key,value):
Matias Guijarro's avatar
Matias Guijarro committed
499
        cnx = self._cnx()
500 501 502
        if value is None:
            cnx.hdel(self._name,key)
            return
Matias Guijarro's avatar
Matias Guijarro committed
503 504 505 506 507 508 509 510
        if self._write_type_conversion:
            value = self._write_type_conversion(value)
        cnx.hset(self._name,key,value)

class HashSettingProp(object):        
    def __init__(self,name,connection = None,
                 read_type_conversion = auto_conversion,
                 write_type_conversion = None,
511
                 default_values = {},
512
                 use_object_name = True):
Matias Guijarro's avatar
Matias Guijarro committed
513 514 515 516
        self._name = name
        self._cnx = connection or get_cache()
        self._read_type_conversion = read_type_conversion
        self._write_type_conversion = write_type_conversion
517
        self._default_values = default_values
Matias Guijarro's avatar
Matias Guijarro committed
518 519 520 521 522 523 524 525 526 527
        self._use_object_name = use_object_name

    def __get__(self,obj,type = None):
        if self._use_object_name:
            name = obj.name + ':' + self._name
        else:
            name = self._name
    
        return HashSetting(name,self._cnx,
                           self._read_type_conversion,
528 529
                           self._write_type_conversion,
                           self._default_values)
Matias Guijarro's avatar
Matias Guijarro committed
530

531
    def __set__(self,obj,values):
Matias Guijarro's avatar
Matias Guijarro committed
532 533 534 535 536
        if self._use_object_name:
            name = obj.name + ':' + self._name
        else:
            name = self._name

537
        if isinstance(values,HashSetting): return
Matias Guijarro's avatar
Matias Guijarro committed
538

539 540 541 542
        proxy = HashSetting(name,self._cnx,
                            self._read_type_conversion,
                            self._write_type_conversion,
                            self._default_values)
Matias Guijarro's avatar
Matias Guijarro committed
543 544
        proxy.set(values)
    
545
    def get_proxy(self):
Matias Guijarro's avatar
Matias Guijarro committed
546 547
        return HashSetting(self._name,self._cnx,
                           self._read_type_conversion,
548 549
                           self._write_type_conversion,
                           self._default_values)
Matias Guijarro's avatar
Matias Guijarro committed
550 551
#helper

552
def _change_to_obj_marshalling(keys):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
553 554 555 556 557
    read_type_conversion = keys.pop('read_type_conversion',pickle_loads)
    write_type_conversion = keys.pop('write_type_conversion',pickle.dumps)
    keys.update({'read_type_conversion':read_type_conversion,
                 'write_type_conversion':write_type_conversion})

558 559 560
class HashObjSetting(HashSetting):
    def __init__(self,name,**keys):
        _change_to_obj_marshalling(keys)
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
561 562
        HashSetting.__init__(self,name,**keys)

563
class HashObjSettingProp(HashSettingProp):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
564
    def __init__(self,name,**keys):
565
        _change_to_obj_marshalling(keys)
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
566 567
        HashSettingProp.__init__(self,name,**keys)

568 569 570
class QueueObjSetting(QueueSetting):
    def __init__(self,name,**keys):
        _change_to_obj_marshalling(keys)
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
571 572 573
        QueueSetting.__init__(self,name,**keys)

class QueueObjSettingProp(QueueSettingProp):
574 575
    def __init__(self,name,**keys):
        _change_to_obj_marshalling(keys)
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
576 577
        QueueSettingProp.__init__(self,name,**keys)

578 579 580
class SimpleObjSetting(SimpleSetting):
    def __init__(self,name,**keys):
        _change_to_obj_marshalling(keys)
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
581 582 583
        SimpleSetting.__init__(self,name,**keys)

class SimpleObjSettingProp(SimpleSettingProp):
584 585
    def __init__(self,name,**keys):
        _change_to_obj_marshalling(keys)
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
586
        SimpleSettingProp.__init__(self,name,**keys)
Matias Guijarro's avatar
Matias Guijarro committed
587 588

class Struct(object):
589
    def __init__(self,name,**keys):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
590
        self._proxy = HashSetting(name,**keys)
Matias Guijarro's avatar
Matias Guijarro committed
591

592
    def __dir__(self):
Matias Guijarro's avatar
Matias Guijarro committed
593 594
        return self._proxy.keys()

595
    def __repr__(self):
Matias Guijarro's avatar
Matias Guijarro committed
596 597 598 599 600 601 602 603
        return "<Struct with attributes: %s>" % self._proxy.keys()

    def __getattribute__(self, name):
        if name.startswith('_'):
            return object.__getattribute__(self,name)
        else:
            return self._proxy.get(name)
            
604
    def __setattr__(self,name,value):
Matias Guijarro's avatar
Matias Guijarro committed
605 606 607 608 609
        if name.startswith('_'):
            return object.__setattr__(self,name,value)
        else:
            self._proxy[name] = value
 
610
    def __delattr__(self,name):
Matias Guijarro's avatar
Matias Guijarro committed
611 612 613 614 615
        if name.startswith('_'):
            return object.__delattr__(self,name)
        else:
            self._proxy.remove(name)

616 617
if __name__ == "__main__":
    class A(object):
Sebastien Petitdemange's avatar
Sebastien Petitdemange committed
618 619 620 621 622 623
        x = SimpleSettingProp('counter')
        y = SimpleObjSettingProp('obj')
        q = QueueSettingProp('seb')
        ol = QueueObjSettingProp('seb-list')
        h = HashSettingProp('seb-hash')
        oh = HashObjSettingProp('seb-hash-object')
Matias Guijarro's avatar
Matias Guijarro committed
624 625 626 627 628
        def __init__(self,name):
            self.name = name

    a = A('m0')
    p = Struct('optics:zap:params')