~ubuntu-branches/ubuntu/raring/wxwidgets2.8/raring

« back to all changes in this revision

Viewing changes to wxPython/wx/lib/agw/persist/persistencemanager.py

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2012-01-07 13:59:25 UTC
  • mfrom: (1.1.9) (5.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120107135925-2601miy9ullcon9j
Tags: 2.8.12.1-6ubuntu1
* Resync from Debian, changes that were kept:
  - debian/rules: re-enable mediactrl. This allows libwx_gtk2u_media-2.8 to be
    built, as this is required by some applications (LP: #632984)
  - debian/control: Build-dep on libxt-dev for mediactrl.
  - Patches
    + fix-bashism-in-example
* Add conflict on python-wxgtk2.8 (<< 2.8.12.1-6ubuntu1~) to python-wxversion
  to guarantee upgrade ordering when moving from pycentral to dh_python2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# --------------------------------------------------------------------------- #
 
2
# PersistentControls Library wxPython IMPLEMENTATION
 
3
#
 
4
# Inspired by the wxWidgets implementation by Vadim Zeitlin.
 
5
#
 
6
# License: wxWidgets license
 
7
#
 
8
# Python Code By:
 
9
#
 
10
# Andrea Gavana, @ 16 Nov 2009
 
11
# Latest Revision: 28 Jan 2011, 15.00 GMT
 
12
#
 
13
# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
 
14
# Write To Me At:
 
15
#
 
16
# andrea.gavana@gmail.com
 
17
# gavana@kpo.kz
 
18
#
 
19
# Or, Obviously, To The wxPython Mailing List!!!
 
20
#
 
21
# End Of Comments
 
22
# --------------------------------------------------------------------------- #
 
23
 
 
24
"""
 
25
This module contains the definitions of `PersistentObject` and `PersistenceManager` objects.
 
26
"""
 
27
 
 
28
import wx
 
29
import os
 
30
import warnings
 
31
import datetime
 
32
 
 
33
import wx.gizmos
 
34
 
 
35
from persist_handlers import FindHandler
 
36
 
 
37
from persist_constants import BAD_DEFAULT_NAMES, CONFIG_PATH_SEPARATOR
 
38
from persist_constants import PM_DEFAULT_STYLE
 
39
 
 
40
# ----------------------------------------------------------------------------------- #
 
41
 
 
42
class PersistentObject(object):
 
43
    """
 
44
    PersistentObject: ABC for anything persistent.
 
45
 
 
46
    This is the base class for persistent object adapters.
 
47
    wxPython persistence framework is non-intrusive, i.e. can work with the
 
48
    classes which have no relationship to nor knowledge of it. To allow this,
 
49
    an intermediate persistence adapter is used: this is just a simple object
 
50
    which provides the methods used by L{PersistenceManager} to save and restore
 
51
    the object properties and implements them using the concrete class methods.
 
52
 
 
53
    You may derive your own classes from L{PersistentObject} to implement persistence
 
54
    support for your common classes, see :ref:`persistent-windows` in the
 
55
    `__init__.py` file.
 
56
    """
 
57
    
 
58
    def __init__(self, window, persistenceHandler=None):
 
59
        """
 
60
        Default class constructor.
 
61
 
 
62
        :param `window`: an instance of `wx.Window`;
 
63
        :param `persistenceHandler`: if not ``None``, this should a custom handler derived
 
64
         from L{persist_handlers.AbstractHandler}.
 
65
        """
 
66
 
 
67
        self._name = window.GetName()
 
68
 
 
69
        if not self._name.strip():
 
70
            raise Exception("Persistent windows should be named! (class=%s)"%window.__class__)
 
71
 
 
72
        klass = window.__class__
 
73
        if issubclass(klass, wx.GenericDirCtrl):
 
74
            self._window = window.GetTreeCtrl()
 
75
        elif issubclass(klass, wx.gizmos.EditableListBox):
 
76
            self._window = window.GetListCtrl()
 
77
        else:
 
78
            self._window = window
 
79
 
 
80
        if persistenceHandler is not None:
 
81
            self._persistentHandler = persistenceHandler(self)
 
82
        else:
 
83
            self._persistentHandler = FindHandler(self)
 
84
        
 
85
        if self._name in BAD_DEFAULT_NAMES:
 
86
            warnings.warn("Window names should not be defaulted! (class=%s, name=%s)"%(window.__class__, window.GetName()))
 
87
 
 
88
 
 
89
    def GetName(self):
 
90
        """
 
91
        Returns the string uniquely identifying the window we're associated with
 
92
        among all the other objects of the same type.
 
93
        
 
94
        :note: This method is used together with L{GetKind} to construct the unique
 
95
         full name of the object in e.g. a configuration file.
 
96
        """
 
97
 
 
98
        return self._name
 
99
 
 
100
 
 
101
    def GetWindow(self):
 
102
        """ Returns the actual associated window. """
 
103
 
 
104
        return self._window
 
105
 
 
106
 
 
107
    def GetKind(self):
 
108
        """
 
109
        Returns the string uniquely identifying the objects supported by this adapter.
 
110
 
 
111
        :note: This method is called from L{SaveValue} and L{RestoreValue} and normally
 
112
         returns some short (but not too cryptic) strings, e.g. "Checkbox".
 
113
        """
 
114
 
 
115
        return self._persistentHandler.GetKind()
 
116
    
 
117
 
 
118
    def Save(self):
 
119
        """
 
120
        Saves the corresponding window settings. 
 
121
 
 
122
        :note: This method shouldn't be used directly as it doesn't respect the
 
123
         global L{PersistenceManager.DisableSaving} settings, use L{PersistenceManager}
 
124
         methods with the same name instead.
 
125
        """
 
126
 
 
127
        self._persistentHandler.Save()
 
128
    
 
129
 
 
130
    def Restore(self):
 
131
        """
 
132
        Restores the corresponding window settings. 
 
133
 
 
134
        :note: This method shouldn't be used directly as it doesn't respect the
 
135
         global L{PersistenceManager.DisableRestoring} settings, use L{PersistenceManager}
 
136
         methods with the same name instead.
 
137
        """
 
138
 
 
139
        self._persistentHandler.Restore()
 
140
 
 
141
 
 
142
    def SaveValue(self, name, value):
 
143
        """
 
144
        Save the specified value using the given name.
 
145
        
 
146
        :param `name`: the name of the value in the configuration file.
 
147
        :param `value`: the value to save.
 
148
 
 
149
        :returns: ``True`` if the value was saved or ``False`` if an error occurred.
 
150
        """
 
151
    
 
152
        return PersistenceManager.Get().SaveValue(self, name, value)
 
153
 
 
154
 
 
155
    def RestoreValue(self, name):
 
156
        """
 
157
        Restore the value saved by L{Save}.
 
158
        
 
159
        :param `name`: the same name as was used by L{Save}.
 
160
 
 
161
        :returns: ``True`` if the value was successfully read or ``False`` if it was not
 
162
         found or an error occurred.
 
163
        """
 
164
 
 
165
        return PersistenceManager.Get().RestoreValue(self, name)
 
166
 
 
167
# ----------------------------------------------------------------------------------- #
 
168
 
 
169
class PersistenceManager(object):
 
170
    """
 
171
    PersistenceManager: global aspects of persistent windows.
 
172
 
 
173
    Provides support for automatically saving and restoring object properties
 
174
    to persistent storage.
 
175
 
 
176
    This class is the central element of wxPython persistence framework, see
 
177
    the :ref:`persistent-overview` in the `__init__.py` file for its overview.
 
178
 
 
179
    This is a singleton class and its unique instance can be retrieved using L{PersistenceManager.Get}
 
180
    method.
 
181
    """
 
182
    
 
183
    def __init__(self):
 
184
        """
 
185
        Default class constructor.
 
186
 
 
187
        This method should **not** be called directly: you should use the object
 
188
        obtained by L{PersistenceManager.Get} and assign manager styles, custom
 
189
        configuration files and custom configuration handlers using the appropriate
 
190
        methods in this class.
 
191
 
 
192
        Interesting attributes you can set for this class are:
 
193
        
 
194
        - `configFile`: the persistent configuration file for L{PersistenceManager},
 
195
          a custom file name to which `wx.FileConfig` will access to store and
 
196
          retrieve UI settings;
 
197
        - `configKey`: the persistent key name inside the configuration file for
 
198
          L{PersistenceManager};
 
199
        - `customConfigHandler`: the persistent configuration handler for L{PersistenceManager};
 
200
          this attribute is object capable of saving/restoring UI settings. This
 
201
          can be a cPickle object or a ConfigObj one, for example.
 
202
        - `style`: a combination of the following values:
 
203
 
 
204
          ======================================== ==================================
 
205
          Flag name                                Description
 
206
          ======================================== ==================================
 
207
          ``PM_SAVE_RESTORE_AUI_PERSPECTIVES``     If a toplevel window has an AUI manager associated, the manager will save and restore its AUI perspective
 
208
          ``PM_SAVE_RESTORE_TREE_LIST_SELECTIONS`` If set, the manager will save items selections in list and tree controls
 
209
          ``PM_DEFAULT_STYLE``                     Same as ``PM_SAVE_RESTORE_AUI_PERSPECTIVES``
 
210
          ======================================== ==================================
 
211
        
 
212
        :note: UI settings are stored as dictionaries key <=> tuple: the tuple value
 
213
         contains two items. The first is the value *type* (i.e., float, int, bool etc...)
 
214
         while the second is the actual key value.
 
215
        
 
216
        """
 
217
 
 
218
        object.__init__(self)
 
219
 
 
220
        # Specifies custom wx.Config object to use (i.e., custom file names)
 
221
        self._configFile = None
 
222
 
 
223
        # Specifies custom key in the wx.Config object to use
 
224
        self._configKey = None
 
225
        
 
226
        # Specifies whether a custom config handler exists, so that we will not use
 
227
        # wx.FileConfig (i.e., ConfigObj, ConfigParser etc...)
 
228
        self._customConfigHandler = None
 
229
        
 
230
        # Specifies the PersistenceManager style
 
231
        self._style = PM_DEFAULT_STYLE
 
232
        
 
233
        # Set these values to True if we should restore/save the settings (it doesn't
 
234
        # make much sense to use this class when both of them are False but setting
 
235
        # one of them to False may make sense in some situations)
 
236
        self._doSave = True
 
237
        self._doRestore = True
 
238
 
 
239
        # map with the registered objects as keys and associated
 
240
        # PersistentObjects as values        
 
241
        self._persistentObjects = {}
 
242
        
 
243
 
 
244
    def Get(self):
 
245
        """ Accessor to the unique persistence manager object. """
 
246
 
 
247
        if not hasattr(self, "_instance"):        
 
248
            self._instance = PersistenceManager()
 
249
 
 
250
        return self._instance
 
251
 
 
252
    Get = classmethod(Get)
 
253
 
 
254
    
 
255
    def Free(self):
 
256
        """ Destructor for the unique persistence manager object. """
 
257
 
 
258
        if hasattr(self, "_instance"):        
 
259
            del self._instance
 
260
 
 
261
    Free = classmethod(Free)
 
262
 
 
263
 
 
264
    def GetManagerStyle(self):
 
265
        """
 
266
        Returns the L{PersistenceManager} style.
 
267
 
 
268
        :see: L{SetManagerStyle} for a list of possible styles.
 
269
        """
 
270
        
 
271
        return self._style        
 
272
 
 
273
 
 
274
    def SetManagerStyle(self, style):
 
275
        """
 
276
        Sets the L{PersistenceManager} style.
 
277
 
 
278
        :param `style`: a combination of the following values:
 
279
 
 
280
        ======================================== ==================================
 
281
        Flag name                                Description
 
282
        ======================================== ==================================
 
283
        ``PM_SAVE_RESTORE_AUI_PERSPECTIVES``     If a toplevel window has an AUI manager associated, the manager will save and restore its AUI perspective
 
284
        ``PM_SAVE_RESTORE_TREE_LIST_SELECTIONS`` If set, the manager will save items selections in list and tree controls
 
285
        ``PM_DEFAULT_STYLE``                     Same as ``PM_SAVE_RESTORE_AUI_PERSPECTIVES``.        
 
286
        ======================================== ==================================
 
287
        """
 
288
 
 
289
        self._style = style
 
290
        
 
291
        
 
292
    def SetPersistenceKey(self, key):
 
293
        """
 
294
        Sets the persistent key name inside the configuration file for L{PersistenceManager}.
 
295
 
 
296
        :param `key`: a short meaningful name for your unique preferences key.
 
297
 
 
298
        :note: Calling this method has no influence if you are using your own
 
299
         custom configuration handler (i.e., by using ConfigObj/ConfigParser/cPickle etc...).        
 
300
        """
 
301
 
 
302
        self._configKey = key
 
303
        
 
304
 
 
305
    def GetPersistenceKey(self):
 
306
        """
 
307
        Returns the persistent key name inside the configuration file for L{PersistenceManager}.
 
308
 
 
309
        :note: The return value of this method is not used if you are using your own
 
310
         custom configuration handler (i.e., by using ConfigObj/ConfigParser/cPickle etc...).
 
311
        """
 
312
 
 
313
        return self._configKey
 
314
 
 
315
 
 
316
    def SetPersistenceFile(self, fileName):
 
317
        """
 
318
        Sets the persistent configuration file for L{PersistenceManager}.
 
319
 
 
320
        :param `fileName`: the file name where to store the persistent options.
 
321
 
 
322
        :note: Calling this method has no influence if you are using your own
 
323
         custom configuration handler (i.e., by using ConfigObj/ConfigParser/cPickle etc...).
 
324
        """
 
325
 
 
326
        self._configFile = fileName
 
327
        
 
328
 
 
329
    def GetPersistenceFile(self):
 
330
        """
 
331
        Returns the persistent configuration file for L{PersistenceManager}.
 
332
 
 
333
        :note: The return value of this method is not used if you are using your own
 
334
         custom configuration handler (i.e., by using ConfigObj/ConfigParser/cPickle etc...).
 
335
        """
 
336
 
 
337
        if self._configFile is not None:
 
338
            persistenceDir, fileName = os.path.split(self._configFile)
 
339
            fileName = self._configFile
 
340
        else:
 
341
            persistenceDir = self.GetPersistenceDirectory()
 
342
            fileName = "Persistence_Options"
 
343
            
 
344
        fileName = os.path.join(persistenceDir, fileName)
 
345
 
 
346
        if not os.path.exists(persistenceDir):
 
347
            # Create the data folder, it still doesn't exist
 
348
            os.makedirs(persistenceDir)
 
349
 
 
350
        config = wx.FileConfig(localFilename=fileName)
 
351
        return config
 
352
 
 
353
 
 
354
    def SetConfigurationHandler(self, handler):
 
355
        """
 
356
        Sets the persistent configuration handler for L{PersistenceManager}.
 
357
 
 
358
        :param `handler`: an object capable of saving/restoring UI settings. This
 
359
         can be a cPickle object or a ConfigObj one, for example.
 
360
 
 
361
        :note: UI settings are stored as dictionaries key <=> tuple: the tuple value
 
362
         contains two items. The first is the value *type* (i.e., float, int, bool etc...)
 
363
         while the second is the actual key value.
 
364
        """
 
365
 
 
366
        self._customConfigHandler = handler
 
367
        
 
368
 
 
369
    def GetConfigurationHandler(self):
 
370
        """
 
371
        Returns the persistent configuration handler for L{PersistenceManager}.
 
372
        """
 
373
 
 
374
        return self._customConfigHandler        
 
375
 
 
376
        
 
377
    def GetPersistenceDirectory(self):
 
378
        """
 
379
        Returns a default persistent option directory for L{PersistenceManager}.
 
380
 
 
381
        :note: The return value of this method is not used if you are using your own
 
382
         custom configuration handler (i.e., by using ConfigObj/ConfigParser/cPickle etc...)
 
383
         or if you have specified a custom configuration file to use with `wx.FileConfig`.
 
384
        """
 
385
        
 
386
        sp = wx.StandardPaths.Get()
 
387
        return sp.GetUserDataDir()
 
388
 
 
389
 
 
390
    def Find(self, window):
 
391
        """
 
392
        Checks if the object is registered and return the associated L{PersistentObject}
 
393
        if it is or ``None`` otherwise.
 
394
 
 
395
        :param `window`: an instance of `wx.Window`.
 
396
        """
 
397
    
 
398
        if window.GetName() in self._persistentObjects:
 
399
            return window
 
400
    
 
401
 
 
402
    def Register(self, window, persistenceHandler=None):
 
403
        """
 
404
        Register an object with the manager.
 
405
 
 
406
        :param `window`: an instance of `wx.Window`;
 
407
        :param `persistenceHandler`: if not ``None``, this should a custom handler derived
 
408
         from L{persist_handlers.AbstractHandler}.
 
409
 
 
410
        :note: Note that registering the object doesn't do anything except allowing to call
 
411
         L{Restore} for it later. If you want to register the object and restore its
 
412
         properties, use L{RegisterAndRestore}.
 
413
 
 
414
        :note: The manager takes ownership of the L{PersistentObject} and will delete it when
 
415
         it is unregistered.         
 
416
        """
 
417
    
 
418
        if self.Find(window):
 
419
            raise Exception("Object (class=%s, name=%s) is already registered"%(window.__class__, window.GetName()))
 
420
 
 
421
        name = window.GetName()
 
422
        self._persistentObjects[name] = PersistentObject(window, persistenceHandler)
 
423
 
 
424
        return True
 
425
    
 
426
 
 
427
    def Unregister(self, window):
 
428
        """
 
429
        Unregister the object, this is called by L{PersistentObject} itself so there is
 
430
        usually no need to do it explicitly.
 
431
 
 
432
        :param `window`: an instance of `wx.Window`, which must have been previously
 
433
         registered with L{Register}.
 
434
 
 
435
        :note: For the persistent windows this is done automatically (via L{SaveAndUnregister})
 
436
         when the window is destroyed so you only need to call this function explicitly if you
 
437
         are using custom persistent objects or if you want to prevent the object properties
 
438
         from being saved.
 
439
         
 
440
        :note: This deletes the associated L{PersistentObject}.
 
441
        """
 
442
    
 
443
        if not self.Find(window):
 
444
            return False
 
445
 
 
446
        name = window.GetName()
 
447
        self._persistentObjects.pop(name)
 
448
 
 
449
        return True
 
450
    
 
451
 
 
452
    def Save(self, window):
 
453
        """
 
454
        Saves the state of an object.
 
455
 
 
456
        :param `window`: an instance of `wx.Window`.
 
457
        
 
458
        :note: This methods does nothing if L{DisableSaving} was called.
 
459
        """
 
460
    
 
461
        if not self._doSave:
 
462
            return False
 
463
 
 
464
        if not self.Find(window):
 
465
            return False
 
466
 
 
467
        name = window.GetName()
 
468
        self._persistentObjects[name].Save()
 
469
        
 
470
        return True
 
471
    
 
472
    
 
473
    def Restore(self, window):
 
474
        """
 
475
        Restores the state of an object.
 
476
 
 
477
        :param `window`: an instance of `wx.Window`.
 
478
 
 
479
        :returns: ``True`` if the object properties were restored or ``False`` if nothing
 
480
         was found to restore or the saved settings were invalid.
 
481
 
 
482
        :note: This methods does nothing if L{DisableRestoring} was called.
 
483
        """
 
484
 
 
485
        if not self._doRestore:
 
486
            return False
 
487
 
 
488
        if not self.Find(window):
 
489
            return False
 
490
 
 
491
        name = window.GetName()
 
492
        self._persistentObjects[name].Restore()
 
493
 
 
494
        return True
 
495
    
 
496
 
 
497
    def DisableSaving(self):
 
498
        """
 
499
        Globally disables saving the persistent properties (enabled by default).
 
500
 
 
501
        :note: By default, saving properties in L{Save} is enabled but the program
 
502
         may wish to disable if, for example, it detects that it is running on a
 
503
         system which shouldn't be modified in any way and so configuration file
 
504
         (or Windows registry) shouldn't be written to.
 
505
        """
 
506
        
 
507
        self._doSave = False
 
508
 
 
509
 
 
510
    def DisableRestoring(self):
 
511
        """
 
512
        Globally disables restoring the persistent properties (enabled by default).
 
513
 
 
514
        :note: By default, restoring properties in L{Restore} is enabled but this
 
515
         function allows to disable it. This is mostly useful for testing.
 
516
        """
 
517
        
 
518
        self._doRestore = False
 
519
 
 
520
 
 
521
    def EnableSaving(self):
 
522
        """
 
523
        Globally enables saving the persistent properties (enabled by default).
 
524
 
 
525
        :note: By default, saving properties in L{Save} is enabled but the program
 
526
         may wish to disable if, for example, it detects that it is running on a
 
527
         system which shouldn't be modified in any way and so configuration file
 
528
         (or Windows registry) shouldn't be written to.        
 
529
        """
 
530
        
 
531
        self._doSave = True
 
532
 
 
533
 
 
534
    def EnableRestoring(self):
 
535
        """
 
536
        Globally enables restoring the persistent properties (enabled by default).
 
537
 
 
538
        :note: By default, restoring properties in L{Restore} is enabled but this
 
539
         function allows to disable it. This is mostly useful for testing.
 
540
        """
 
541
        
 
542
        self._doRestore = True
 
543
 
 
544
 
 
545
    def SaveAndUnregister(self, window=None):
 
546
        """
 
547
        Combines both L{Save} and L{Unregister} calls.
 
548
 
 
549
        :param `window`: an instance of `wx.Window`. If it is ``None``, all the
 
550
         windows previously registered are saved and then unregistered.
 
551
        """
 
552
 
 
553
        if window is None:
 
554
            for name, obj in self._persistentObjects.items():
 
555
                self.SaveAndUnregister(obj.GetWindow())
 
556
 
 
557
            return
 
558
 
 
559
        self.Save(window)
 
560
        self.Unregister(window)
 
561
 
 
562
 
 
563
    def RegisterAndRestore(self, window):
 
564
        """
 
565
        Combines both L{Register} and L{Restore} calls.
 
566
 
 
567
        :param `window`: an instance of `wx.Window`.
 
568
        """
 
569
        
 
570
        return self.Register(window) and self.Restore(window)
 
571
 
 
572
 
 
573
    def GetKey(self, obj, keyName):
 
574
        """
 
575
        Returns a correctly formatted key name for the object `obj` and `keyName` parameters.
 
576
 
 
577
        :param `obj`: an instance of L{PersistentObject};
 
578
        :param `keyName`: a string specifying the key name.
 
579
 
 
580
        """
 
581
 
 
582
        key = (self._configKey is None and ["Persistence_Options"] or [self._configKey])[0]       
 
583
        
 
584
        key += CONFIG_PATH_SEPARATOR + obj.GetKind()
 
585
        key += CONFIG_PATH_SEPARATOR + obj.GetName()
 
586
        key += CONFIG_PATH_SEPARATOR + keyName
 
587
        
 
588
        return key
 
589
 
 
590
    
 
591
    def SaveValue(self, obj, keyName, value):
 
592
        """
 
593
        Method used by the persistent objects to save the data.
 
594
 
 
595
        By default this method simply use `wx.FileConfig` but this behaviour may be
 
596
        overridden by passing a custom configuration handler in the L{PersistenceManager}
 
597
        constructor.
 
598
 
 
599
        :param `obj`: an instance of L{PersistentObject};
 
600
        :param `keyName`: a string specifying the key name;
 
601
        :param `value`: the value to store in the configuration file.
 
602
        
 
603
        """
 
604
 
 
605
        kind = repr(value.__class__).split("'")[1]
 
606
    
 
607
        if self._customConfigHandler is not None:
 
608
            result = self._customConfigHandler.SaveValue(self.GetKey(obj, keyName), repr((kind, str(value))))
 
609
        else:
 
610
            config = self.GetPersistenceFile()
 
611
            result = config.Write(self.GetKey(obj, keyName), repr((kind, str(value))))
 
612
            config.Flush()
 
613
 
 
614
        return result        
 
615
    
 
616
 
 
617
    def RestoreValue(self, obj, keyName):
 
618
        """
 
619
        Method used by the persistent objects to restore the data.
 
620
        
 
621
        By default this method simply use `wx.FileConfig` but this behaviour may be
 
622
        overridden by passing a custom config handler in the PersistenceManager
 
623
        constructor.
 
624
 
 
625
        :param `obj`: an instance of L{PersistentObject};
 
626
        :param `keyName`: a string specifying the key name.
 
627
        """
 
628
 
 
629
        if self._customConfigHandler is not None:
 
630
            result = self._customConfigHandler.RestoreValue(self.GetKey(obj, keyName))
 
631
        else:
 
632
            config = self.GetPersistenceFile()
 
633
            result = config.Read(self.GetKey(obj, keyName))
 
634
 
 
635
        if result:
 
636
            kind, result = eval(result)
 
637
            if kind in ("unicode", "str"):
 
638
                return result
 
639
            elif kind == "datetime.date":
 
640
                y, m, d = result.split("-")
 
641
                result = datetime.date(int(y), int(m), int(d))
 
642
                return result
 
643
            
 
644
            return eval(result)
 
645
 
 
646