~ubuntu-branches/debian/experimental/spyder/experimental

« back to all changes in this revision

Viewing changes to spyderlib/utils/external/pickleshare.py

  • Committer: Package Import Robot
  • Author(s): Picca Frédéric-Emmanuel
  • Date: 2014-05-29 09:06:26 UTC
  • mfrom: (1.1.21) (18.1.6 sid)
  • Revision ID: package-import@ubuntu.com-20140529090626-f58t82g0n5iewaxu
Tags: 2.3.0~rc+dfsg-1~experimental2
* Add spyder-common binary package for all the python2,3 common files
* debian/path
  - 0001-fix-documentation-installation.patch (deleted)
  + 0001-fix-spyderlib-path.patch (new)

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 
34
34
"""
35
35
 
 
36
from __future__ import print_function
 
37
 
36
38
from spyderlib.utils.external.path import path as Path
37
 
import os,stat,time
38
 
import cPickle as pickle
39
 
import UserDict
40
 
import warnings
 
39
from spyderlib.py3compat import pickle, MutableMapping
 
40
 
 
41
import os
 
42
import stat
 
43
import time
41
44
import glob
 
45
import errno
42
46
 
43
47
def gethashfile(key):
44
48
    return ("%02x" % abs(hash(key) % 256))[-2:]
45
49
 
46
50
_sentinel = object()
47
51
 
48
 
class PickleShareDB(UserDict.DictMixin):
 
52
class PickleShareDB(MutableMapping):
49
53
    """ The main 'connection' object for PickleShare database """
50
 
    def __init__(self,root):
 
54
    def __init__(self, root):
51
55
        """ Return a db object that will manage the specied directory"""
52
56
        self.root = Path(root).expanduser().abspath()
53
57
        if not self.root.isdir():
54
58
            self.root.makedirs()
55
59
        # cache has { 'key' : (obj, orig_mod_time) }
56
60
        self.cache = {}
57
 
        
 
61
    
 
62
    #==========================================================================
 
63
    # Only affects Python 3
 
64
    def __iter__(self):
 
65
        return iter(self.cache)
 
66
    def __len__(self):
 
67
        return len(self.cache)
 
68
    #==========================================================================
58
69
 
59
 
    def __getitem__(self,key):
 
70
    def __getitem__(self, key):
60
71
        """ db['key'] reading """
61
72
        fil = self.root / key
62
73
        try:
68
79
            return self.cache[fil][0]
69
80
        try:
70
81
            # The cached item has expired, need to read
71
 
            obj = pickle.load(fil.open())
 
82
            obj = pickle.load(fil.open('rb'))
72
83
        except:
73
84
            raise KeyError(key)
74
85
            
75
 
        self.cache[fil] = (obj,mtime)
 
86
        self.cache[fil] = (obj, mtime)
76
87
        return obj
77
88
    
78
 
    def __setitem__(self,key,value):
 
89
    def __setitem__(self, key, value):
79
90
        """ db['key'] = 5 """
80
91
        fil = self.root / key
81
92
        parent = fil.parent
82
93
        if parent and not parent.isdir():
83
94
            parent.makedirs()
84
 
        pickled = pickle.dump(value,fil.open('w'))
 
95
        # We specify protocol 2, so that we can mostly go between Python 2
 
96
        # and Python 3. We can upgrade to protocol 3 when Python 2 is obsolete.
 
97
        pickled = pickle.dump(value, fil.open('wb'), protocol=2)
85
98
        try:
86
 
            self.cache[fil] = (value,fil.mtime)
87
 
        except OSError,e:
88
 
            if e.errno != 2:
 
99
            self.cache[fil] = (value, fil.mtime)
 
100
        except OSError as e:
 
101
            if e.errno != errno.ENOENT:
89
102
                raise
90
103
    
91
104
    def hset(self, hashroot, key, value):
135
148
            try:
136
149
                all.update(self[f])
137
150
            except KeyError:
138
 
                print "Corrupt",f,"deleted - hset is not threadsafe!"
 
151
                print("Corrupt", f, "deleted - hset is not threadsafe!")
139
152
                del self[f]
140
153
                
141
154
            self.uncache(f)
165
178
            
166
179
            
167
180
        
168
 
    def __delitem__(self,key):
 
181
    def __delitem__(self, key):
169
182
        """ del db["key"] """
170
183
        fil = self.root / key
171
 
        self.cache.pop(fil,None)
 
184
        self.cache.pop(fil, None)
172
185
        try:
173
186
            fil.remove()
174
187
        except OSError:
178
191
        
179
192
    def _normalized(self, p):
180
193
        """ Make a key suitable for user's eyes """
181
 
        return str(self.root.relpathto(p)).replace('\\','/')
 
194
        return str(self.root.relpathto(p)).replace('\\', '/')
182
195
    
183
196
    def keys(self, globpat = None):
184
197
        """ All keys in DB, or all keys matching a glob"""
200
213
        if not items:
201
214
            self.cache = {}
202
215
        for it in items:
203
 
            self.cache.pop(it,None)
 
216
            self.cache.pop(it, None)
204
217
            
205
218
    def waitget(self,key, maxwaittime = 60 ):
206
219
        """ Wait (poll) for a key to get a value
234
247
            if tries < len(wtimes) -1:
235
248
                tries+=1
236
249
    
237
 
    def getlink(self,folder):
 
250
    def getlink(self, folder):
238
251
        """ Get a convenient link for accessing items  """
239
252
        return PickleShareLink(self, folder)
240
253
    
256
269
    def __init__(self, db, keydir ):    
257
270
        self.__dict__.update(locals())
258
271
        
259
 
    def __getattr__(self,key):
 
272
    def __getattr__(self, key):
260
273
        return self.__dict__['db'][self.__dict__['keydir']+'/' + key]
261
 
    def __setattr__(self,key,val):
 
274
    def __setattr__(self, key, val):
262
275
        self.db[self.keydir+'/' + key] = val
263
276
    def __repr__(self):
264
277
        db = self.__dict__['db']
271
284
def test():
272
285
    db = PickleShareDB('~/testpickleshare')
273
286
    db.clear()
274
 
    print "Should be empty:",db.items()
 
287
    print("Should be empty:", list(db.items()))
275
288
    db['hello'] = 15
276
 
    db['aku ankka'] = [1,2,313]
277
 
    db['paths/nest/ok/keyname'] = [1,(5,46)]
 
289
    db['aku ankka'] = [1, 2, 313]
 
290
    db['paths/nest/ok/keyname'] = [1, (5, 46)]
278
291
    db.hset('hash', 'aku', 12)
279
292
    db.hset('hash', 'ankka', 313)
280
 
    print "12 =",db.hget('hash','aku')
281
 
    print "313 =",db.hget('hash','ankka')
282
 
    print "all hashed",db.hdict('hash')
283
 
    print db.keys()
284
 
    print db.keys('paths/nest/ok/k*')
285
 
    print dict(db) # snapsot of whole db
 
293
    print("12 =", db.hget('hash', 'aku'))
 
294
    print("313 =", db.hget('hash', 'ankka'))
 
295
    print("all hashed", db.hdict('hash'))
 
296
    print(list(db.keys()))
 
297
    print(db.keys('paths/nest/ok/k*'))
 
298
    print(dict(db)) # snapsot of whole db
286
299
    db.uncache() # frees memory, causes re-reads later
287
300
 
288
301
    # shorthand for accessing deeply nested files
289
302
    lnk = db.getlink('myobjects/test')
290
303
    lnk.foo = 2
291
304
    lnk.bar = lnk.foo + 5
292
 
    print lnk.bar # 7
 
305
    print(lnk.bar) # 7
293
306
 
294
307
def stress():
295
308
    db = PickleShareDB('~/fsdbtest')
296
 
    import time,sys
 
309
    import time, sys
297
310
    for i in range(1000):
298
311
        for j in range(1000):
299
312
            if i % 15 == 0 and i < 200:
304
317
            if j%33 == 0:
305
318
                time.sleep(0.02)
306
319
            
307
 
            db[str(j)] = db.get(str(j), []) + [(i,j,"proc %d" % os.getpid())]
308
 
            db.hset('hash',j, db.hget('hash',j,15) + 1 )
 
320
            db[str(j)] = db.get(str(j), []) + [(i, j, "proc %d" % os.getpid())]
 
321
            db.hset('hash', j, db.hget('hash', j, 15) + 1 )
309
322
            
310
 
        print i,
 
323
        print(i, end=' ')
311
324
        sys.stdout.flush()
312
325
        if i % 10 == 0:
313
326
            db.uncache()
326
339
    DB = PickleShareDB
327
340
    import sys
328
341
    if len(sys.argv) < 2:
329
 
        print usage
 
342
        print(usage)
330
343
        return
331
344
        
332
345
    cmd = sys.argv[1]
335
348
        if not args: args= ['.']
336
349
        db = DB(args[0])
337
350
        import pprint
338
 
        pprint.pprint(db.items())
 
351
        pprint.pprint(list(db.items()))
339
352
    elif cmd == 'load':
340
353
        cont = sys.stdin.read()
341
354
        db = DB(args[0])
342
355
        data = eval(cont)
343
356
        db.clear()
344
 
        for k,v in db.items():
 
357
        for k, v in list(db.items()):
345
358
            db[k] = v
346
359
    elif cmd == 'testwait':
347
360
        db = DB(args[0])
348
361
        db.clear()
349
 
        print db.waitget('250')
 
362
        print(db.waitget('250'))
350
363
    elif cmd == 'test':
351
364
        test()
352
365
        stress()