home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / checkbox / contrib / persist.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-10-12  |  19.1 KB  |  644 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import os
  5. import sys
  6. import copy
  7. import re
  8. import posixpath
  9. __all__ = [
  10.     'Persist',
  11.     'PickleBackend',
  12.     'BPickleBackend',
  13.     'path_string_to_tuple',
  14.     'path_tuple_to_string',
  15.     'RootedPersist',
  16.     'PersistError',
  17.     'PersistReadOnlyError']
  18. NOTHING = object()
  19.  
  20. class PersistError(Exception):
  21.     pass
  22.  
  23.  
  24. class PersistReadOnlyError(PersistError):
  25.     pass
  26.  
  27.  
  28. class Persist(object):
  29.     '''Persistence handler.
  30.  
  31.     There are three different kinds of opition maps, regarding the
  32.     persistence and priority that maps are queried.
  33.  
  34.     hard - Options are persistent.
  35.     soft - Options are not persistent, and have a higher priority
  36.            than persistent options.
  37.     weak - Options are not persistent, and have a lower priority
  38.            than persistent options.
  39.  
  40.     @ivar filename: The name of the file where persist data is saved
  41.         or None if not filename is available.
  42.     '''
  43.     
  44.     def __init__(self, filename = None, backend = None):
  45.         '''
  46.         @param backend: The backend to use. If none is specified,
  47.             L{BPickleBackend} will be used.
  48.         @param filename: The default filename to save to and load from. If
  49.             specified, and the file exists, it will be immediately
  50.             loaded. Specifying this will also allow L{save} to be called
  51.             without any arguments to save the persist.
  52.         '''
  53.         if backend is None:
  54.             backend = BPickleBackend()
  55.         
  56.         self._backend = backend
  57.         self._hardmap = backend.new()
  58.         self._softmap = { }
  59.         self._weakmap = { }
  60.         self._readonly = False
  61.         self._modified = False
  62.         self.filename = filename
  63.         if filename is not None and posixpath.exists(filename):
  64.             self.load(filename)
  65.         
  66.  
  67.     
  68.     def _get_readonly(self):
  69.         return self._readonly
  70.  
  71.     
  72.     def _set_readonly(self, flag):
  73.         self._readonly = bool(flag)
  74.  
  75.     
  76.     def _get_modified(self):
  77.         return self._modified
  78.  
  79.     readonly = property(_get_readonly, _set_readonly)
  80.     modified = property(_get_modified)
  81.     
  82.     def reset_modified(self):
  83.         self._modified = False
  84.  
  85.     
  86.     def assert_writable(self):
  87.         if self._readonly:
  88.             raise PersistReadOnlyError('Configuration is in readonly mode.')
  89.         self._readonly
  90.  
  91.     
  92.     def load(self, filepath):
  93.         filepath = posixpath.expanduser(filepath)
  94.         if not posixpath.isfile(filepath):
  95.             raise PersistError('File not found: %s' % filepath)
  96.         posixpath.isfile(filepath)
  97.         if posixpath.getsize(filepath) == 0:
  98.             return None
  99.         
  100.         try:
  101.             self._hardmap = self._backend.load(filepath)
  102.         except:
  103.             posixpath.getsize(filepath) == 0
  104.             filepathold = filepath + '.old'
  105.             if posixpath.isfile(filepathold) and posixpath.getsize(filepathold) > 0:
  106.                 
  107.                 try:
  108.                     self._hardmap = self._backend.load(filepathold)
  109.                 raise PersistError('Broken configuration file at %s' % filepathold)
  110.  
  111.             else:
  112.                 raise PersistError('Broken configuration file at %s' % filepath)
  113.  
  114.  
  115.     
  116.     def save(self, filepath = None):
  117.         '''Save the persist to the given C{filepath}.
  118.  
  119.         If None is specified, then the filename passed during construction will
  120.         be used.
  121.         '''
  122.         if filepath is None:
  123.             if self.filename is None:
  124.                 raise PersistError('Need a filename!')
  125.             self.filename is None
  126.             filepath = self.filename
  127.         
  128.         filepath = posixpath.expanduser(filepath)
  129.         if posixpath.isfile(filepath):
  130.             os.rename(filepath, filepath + '.old')
  131.         
  132.         dirname = posixpath.dirname(filepath)
  133.         if dirname and not posixpath.isdir(dirname):
  134.             os.makedirs(dirname)
  135.         
  136.         self._backend.save(filepath, self._hardmap)
  137.  
  138.     
  139.     def _traverse(self, obj, path, default = NOTHING, setvalue = NOTHING):
  140.         if setvalue is not NOTHING:
  141.             setvalue = self._backend.copy(setvalue)
  142.         
  143.         queue = list(path)
  144.         marker = NOTHING
  145.         newobj = obj
  146.         while queue:
  147.             obj = newobj
  148.             elem = queue.pop(0)
  149.             newobj = self._backend.get(obj, elem)
  150.             if newobj is NotImplemented:
  151.                 if queue:
  152.                     path = path[:-len(queue)]
  153.                 
  154.                 raise PersistError("Can't traverse %r (%r): %r" % (type(obj), path_tuple_to_string(path), str(obj)))
  155.             newobj is NotImplemented
  156.             if newobj is marker:
  157.                 break
  158.                 continue
  159.         if newobj is not marker:
  160.             if setvalue is not marker:
  161.                 newobj = self._backend.set(obj, elem, setvalue)
  162.             
  163.         elif setvalue is marker:
  164.             newobj = default
  165.         else:
  166.             while True:
  167.                 if len(queue) > 0:
  168.                     if type(queue[0]) is int:
  169.                         newvalue = []
  170.                     else:
  171.                         newvalue = { }
  172.                 else:
  173.                     newvalue = setvalue
  174.                 newobj = self._backend.set(obj, elem, newvalue)
  175.                 if newobj is NotImplemented:
  176.                     raise PersistError("Can't traverse %r with %r" % (type(obj), type(elem)))
  177.                 newobj is NotImplemented
  178.                 if not queue:
  179.                     break
  180.                 
  181.                 obj = newobj
  182.                 elem = queue.pop(0)
  183.         return newobj
  184.  
  185.     
  186.     def _getvalue(self, path, soft = False, hard = False, weak = False):
  187.         if type(path) is str:
  188.             path = path_string_to_tuple(path)
  189.         
  190.         marker = NOTHING
  191.         if soft:
  192.             value = self._traverse(self._softmap, path, marker)
  193.         elif hard:
  194.             value = self._traverse(self._hardmap, path, marker)
  195.         elif weak:
  196.             value = self._traverse(self._weakmap, path, marker)
  197.         else:
  198.             value = self._traverse(self._softmap, path, marker)
  199.             if value is marker:
  200.                 value = self._traverse(self._hardmap, path, marker)
  201.                 if value is marker:
  202.                     value = self._traverse(self._weakmap, path, marker)
  203.                 
  204.             
  205.         return value
  206.  
  207.     
  208.     def has(self, path, value = NOTHING, soft = False, hard = False, weak = False):
  209.         obj = self._getvalue(path, soft, hard, weak)
  210.         marker = NOTHING
  211.         if obj is marker:
  212.             return False
  213.         if value is marker:
  214.             return True
  215.         result = self._backend.has(obj, value)
  216.         if result is NotImplemented:
  217.             raise PersistError("Can't check %r for containment" % type(obj))
  218.         result is NotImplemented
  219.         return result
  220.  
  221.     
  222.     def keys(self, path, soft = False, hard = False, weak = False):
  223.         obj = self._getvalue(path, soft, hard, weak)
  224.         if obj is NOTHING:
  225.             return []
  226.         result = self._backend.keys(obj)
  227.         if result is NotImplemented:
  228.             raise PersistError("Can't return keys for %s" % type(obj))
  229.         result is NotImplemented
  230.         return result
  231.  
  232.     
  233.     def get(self, path, default = None, soft = False, hard = False, weak = False):
  234.         value = self._getvalue(path, soft, hard, weak)
  235.         if value is NOTHING:
  236.             return default
  237.         return self._backend.copy(value)
  238.  
  239.     
  240.     def set(self, path, value, soft = False, weak = False):
  241.         if not path:
  242.             raise AssertionError
  243.         if type(path) is str:
  244.             path = path_string_to_tuple(path)
  245.         
  246.         if soft:
  247.             map = self._softmap
  248.         elif weak:
  249.             map = self._weakmap
  250.         else:
  251.             self.assert_writable()
  252.             self._modified = True
  253.             map = self._hardmap
  254.         self._traverse(map, path, setvalue = value)
  255.  
  256.     
  257.     def add(self, path, value, unique = False, soft = False, weak = False):
  258.         if not path:
  259.             raise AssertionError
  260.         if type(path) is str:
  261.             path = path_string_to_tuple(path)
  262.         
  263.         if soft:
  264.             map = self._softmap
  265.         elif weak:
  266.             map = self._weakmap
  267.         else:
  268.             self.assert_writable()
  269.             self._modified = True
  270.             map = self._hardmap
  271.         if unique:
  272.             current = self._traverse(map, path)
  273.             if type(current) is list and value in current:
  274.                 return None
  275.         
  276.         path = path + (sys.maxint,)
  277.         self._traverse(map, path, setvalue = value)
  278.  
  279.     
  280.     def remove(self, path, value = NOTHING, soft = False, weak = False):
  281.         if not path:
  282.             raise AssertionError
  283.         if type(path) is str:
  284.             path = path_string_to_tuple(path)
  285.         
  286.         if soft:
  287.             map = self._softmap
  288.         elif weak:
  289.             map = self._weakmap
  290.         else:
  291.             self.assert_writable()
  292.             self._modified = True
  293.             map = self._hardmap
  294.         marker = NOTHING
  295.         while path:
  296.             if value is marker:
  297.                 obj = self._traverse(map, path[:-1])
  298.                 elem = path[-1]
  299.                 isvalue = False
  300.             else:
  301.                 obj = self._traverse(map, path)
  302.                 elem = value
  303.                 isvalue = True
  304.             result = False
  305.             if obj is not marker:
  306.                 result = self._backend.remove(obj, elem, isvalue)
  307.                 if result is NotImplemented:
  308.                     raise PersistError("Can't remove %r from %r" % (elem, type(obj)))
  309.                 result is NotImplemented
  310.             
  311.             if self._backend.empty(obj):
  312.                 if value is not marker:
  313.                     value = marker
  314.                 else:
  315.                     path = path[:-1]
  316.             value is not marker
  317.             break
  318.         return result
  319.  
  320.     
  321.     def move(self, oldpath, newpath, soft = False, weak = False):
  322.         if not soft or weak:
  323.             self.assert_writable()
  324.         
  325.         if type(oldpath) is str:
  326.             oldpath = path_string_to_tuple(oldpath)
  327.         
  328.         if type(newpath) is str:
  329.             newpath = path_string_to_tuple(newpath)
  330.         
  331.         result = False
  332.         marker = NOTHING
  333.         if not soft:
  334.             pass
  335.         value = self._getvalue(oldpath, soft, not weak, weak)
  336.         if value is not marker:
  337.             self.remove(oldpath, soft = soft, weak = weak)
  338.             self.set(newpath, value, weak, soft)
  339.             result = True
  340.         
  341.         return result
  342.  
  343.     
  344.     def root_at(self, path):
  345.         return RootedPersist(self, path)
  346.  
  347.  
  348.  
  349. class RootedPersist(object):
  350.     
  351.     def __init__(self, parent, root):
  352.         self.parent = parent
  353.         if type(root) is str:
  354.             self.root = path_string_to_tuple(root)
  355.         else:
  356.             self.root = root
  357.  
  358.     readonly = property((lambda self: self.parent.readonly))
  359.     modified = property((lambda self: self.parent.modified))
  360.     
  361.     def assert_writable(self):
  362.         self.parent.assert_writable()
  363.  
  364.     
  365.     def save(self):
  366.         self.parent.save()
  367.  
  368.     
  369.     def has(self, path, value = NOTHING, soft = False, hard = False, weak = False):
  370.         if type(path) is str:
  371.             path = path_string_to_tuple(path)
  372.         
  373.         return self.parent.has(self.root + path, value, soft, hard, weak)
  374.  
  375.     
  376.     def keys(self, path, soft = False, hard = False, weak = False):
  377.         if type(path) is str:
  378.             path = path_string_to_tuple(path)
  379.         
  380.         return self.parent.keys(self.root + path, soft, hard, weak)
  381.  
  382.     
  383.     def get(self, path, default = None, soft = False, hard = False, weak = False):
  384.         if type(path) is str:
  385.             path = path_string_to_tuple(path)
  386.         
  387.         return self.parent.get(self.root + path, default, soft, hard, weak)
  388.  
  389.     
  390.     def set(self, path, value, soft = False, weak = False):
  391.         if type(path) is str:
  392.             path = path_string_to_tuple(path)
  393.         
  394.         return self.parent.set(self.root + path, value, soft, weak)
  395.  
  396.     
  397.     def add(self, path, value, unique = False, soft = False, weak = False):
  398.         if type(path) is str:
  399.             path = path_string_to_tuple(path)
  400.         
  401.         return self.parent.add(self.root + path, value, unique, soft, weak)
  402.  
  403.     
  404.     def remove(self, path, value = NOTHING, soft = False, weak = False):
  405.         if type(path) is str:
  406.             path = path_string_to_tuple(path)
  407.         
  408.         return self.parent.remove(self.root + path, value, soft, weak)
  409.  
  410.     
  411.     def move(self, oldpath, newpath, soft = False, weak = False):
  412.         if type(oldpath) is str:
  413.             oldpath = path_string_to_tuple(oldpath)
  414.         
  415.         if type(newpath) is str:
  416.             newpath = path_string_to_tuple(newpath)
  417.         
  418.         return self.parent.move(self.root + oldpath, self.root + newpath, soft, weak)
  419.  
  420.     
  421.     def root_at(self, path):
  422.         if type(path) is str:
  423.             path = path_string_to_tuple(path)
  424.         
  425.         return self.parent.root_at(self.root + path)
  426.  
  427.  
  428. _splitpath = re.compile('(\\[-?\\d+\\])|(?<!\\\\)\\.').split
  429.  
  430. def path_string_to_tuple(path):
  431.     if '.' not in path and '[' not in path:
  432.         return (path,)
  433.     result = []
  434.     tokens = _splitpath(path)
  435.     for token in tokens:
  436.         if token:
  437.             if token[0] == '[' and token[-1] == ']':
  438.                 
  439.                 try:
  440.                     result.append(int(token[1:-1]))
  441.                 except ValueError:
  442.                     '[' not in path
  443.                     '[' not in path
  444.                     raise PersistError('Invalid path index: %r' % token)
  445.                 except:
  446.                     '[' not in path<EXCEPTION MATCH>ValueError
  447.                 
  448.  
  449.             '[' not in path<EXCEPTION MATCH>ValueError
  450.             result.append(token.replace('\\.', '.'))
  451.             continue
  452.         '[' not in path
  453.     
  454.     return tuple(result)
  455.  
  456.  
  457. def path_tuple_to_string(path):
  458.     result = []
  459.     for elem in path:
  460.         if type(elem) is int:
  461.             result[-1] += '[%d]' % elem
  462.             continue
  463.         result.append(str(elem).replace('.', '\\.'))
  464.     
  465.     return '.'.join(result)
  466.  
  467.  
  468. class Backend(object):
  469.     
  470.     def new(self):
  471.         raise NotImplementedError
  472.  
  473.     
  474.     def load(self, filepath):
  475.         raise NotImplementedError
  476.  
  477.     
  478.     def save(self, filepath, map):
  479.         raise NotImplementedError
  480.  
  481.     
  482.     def get(self, obj, elem, _marker = NOTHING):
  483.         if type(obj) is dict:
  484.             newobj = obj.get(elem, _marker)
  485.         elif type(obj) in (tuple, list):
  486.             if type(elem) is int:
  487.                 
  488.                 try:
  489.                     newobj = obj[elem]
  490.                 except IndexError:
  491.                     newobj = _marker
  492.                 except:
  493.                     None<EXCEPTION MATCH>IndexError
  494.                 
  495.  
  496.             None<EXCEPTION MATCH>IndexError
  497.             if elem in obj:
  498.                 newobj = elem
  499.             else:
  500.                 newobj = _marker
  501.         else:
  502.             newobj = NotImplemented
  503.         return newobj
  504.  
  505.     
  506.     def set(self, obj, elem, value):
  507.         if type(obj) is dict:
  508.             newobj = obj[elem] = value
  509.         elif type(obj) is list and type(elem) is int:
  510.             lenobj = len(obj)
  511.             if lenobj <= elem:
  512.                 obj.append(None)
  513.                 elem = lenobj
  514.             elif elem < 0 and abs(elem) > lenobj:
  515.                 obj.insert(0, None)
  516.                 elem = 0
  517.             
  518.             newobj = obj[elem] = value
  519.         else:
  520.             newobj = NotImplemented
  521.         return newobj
  522.  
  523.     
  524.     def remove(self, obj, elem, isvalue):
  525.         result = False
  526.         if type(obj) is dict:
  527.             if elem in obj:
  528.                 del obj[elem]
  529.                 result = True
  530.             
  531.         elif type(obj) is list:
  532.             if not isvalue and type(elem) is int:
  533.                 
  534.                 try:
  535.                     del obj[elem]
  536.                     result = True
  537.                 except IndexError:
  538.                     pass
  539.                 except:
  540.                     None<EXCEPTION MATCH>IndexError
  541.                 
  542.  
  543.             None<EXCEPTION MATCH>IndexError
  544.             if elem in obj:
  545.                 obj[:] = _[1]
  546.                 result = True
  547.             
  548.         else:
  549.             result = NotImplemented
  550.         return result
  551.  
  552.     
  553.     def copy(self, value):
  554.         if type(value) in (dict, list):
  555.             return copy.deepcopy(value)
  556.         return value
  557.  
  558.     
  559.     def empty(self, obj):
  560.         return not obj
  561.  
  562.     
  563.     def has(self, obj, elem):
  564.         contains = getattr(obj, '__contains__', None)
  565.         if contains:
  566.             return contains(elem)
  567.         return NotImplemented
  568.  
  569.     
  570.     def keys(self, obj):
  571.         keys = getattr(obj, 'keys', None)
  572.         if keys:
  573.             return keys()
  574.         if type(obj) is list:
  575.             return range(len(obj))
  576.         return NotImplemented
  577.  
  578.  
  579.  
  580. class PickleBackend(Backend):
  581.     
  582.     def __init__(self):
  583.         import cPickle
  584.         self._pickle = cPickle
  585.  
  586.     
  587.     def new(self):
  588.         return { }
  589.  
  590.     
  591.     def load(self, filepath):
  592.         file = open(filepath)
  593.         
  594.         try:
  595.             return self._pickle.load(file)
  596.         finally:
  597.             file.close()
  598.  
  599.  
  600.     
  601.     def save(self, filepath, map):
  602.         file = open(filepath, 'w')
  603.         
  604.         try:
  605.             self._pickle.dump(map, file, 2)
  606.         finally:
  607.             file.close()
  608.  
  609.  
  610.  
  611.  
  612. class BPickleBackend(Backend):
  613.     
  614.     def __init__(self):
  615.         bpickle = bpickle
  616.         import checkbox.contrib
  617.         self._bpickle = bpickle
  618.  
  619.     
  620.     def new(self):
  621.         return { }
  622.  
  623.     
  624.     def load(self, filepath):
  625.         file = open(filepath)
  626.         
  627.         try:
  628.             return self._bpickle.loads(file.read())
  629.         finally:
  630.             file.close()
  631.  
  632.  
  633.     
  634.     def save(self, filepath, map):
  635.         file = open(filepath, 'w')
  636.         
  637.         try:
  638.             file.write(self._bpickle.dumps(map))
  639.         finally:
  640.             file.close()
  641.  
  642.  
  643.  
  644.