def safeval(self, v): ''' v: object -> r: None|tuple|search.SIMPLE|search.ARRAY convert v to a "safe" type, which is either a simple type, a hashable sequence, or an ndarray instance. In the latter case, the array will be set read-only. A TypeError is thrown if the input is not one of these types and also can't be converted to one (for example, lists can usually be cast to tuples,but functions, classes, etc will usually not convert) ''' vt = search.classify(v) if vt in search.simpletypes: return v elif vt == '#': v.setflags(write=False) return v elif vt == '[': if ishashable(v): return v return astuple(v) elif vt == "{": return Doc(v, 2) else: raise TypeError('type of %s (%s) is not safe (and can not be made so)' % (str(v), str(type(v)),))
def t2a(doc): for k in doc.keys(-1, None, True, False): v = doc[k] if classify(v) == "[": try: a = asarray(v) except: continue doc[k] = a
def astuple(self): t = [] for k in self.keys(-1, None, True, False): v = self[k] if v == None: continue if search.classify(v) in "[#": v = astuple(v) t.append((k, v)) return tuple(t)
def setslice(self, k, sl, v): if not type(sl[0]) in [tuple, list]: sl = apply(slice, sl) else: sl = tuple([apply(slice, t) for t in sl]) ov = self[k] ovt = search.classify(ov) if ovt == '#': ov[sl] = v elif ovt == '[': nv = list(ov) nv[sl] = v self[k] = tuple(nv) else: raise ValueError('Attempt to assign slice to non-sequence at %s' % (k,))
def tshape(t): if not type(t) == tuple: return None if len(t) == 0: return ((0,), ()) if all([type(a) == tuple for a in t]): td = tshape(t[0]) if td == None: return None td, ty = td if len(ty) > 1: return None tdlr = (td[-1], td[-1]) for tt in t[1:]: ttd = tshape(tt) if ttd == None: return None ttd, tty = ttd if tty != ty: if ty == (): ty = tty elif tty == (): pass else: return None if len(ttd) != len(td): return None if any([td[i] != ttd[i] for i in range(len(td) - 1)]): return None if type(td[-1]) == tuple: ttdlr = ttd[-1] else: ttdlr = (ttd[-1], ttd[-1]) tdlr = (min(tdlr[0], ttdlr[0]), max(tdlr[1], ttdlr[1])) if tdlr[0] != tdlr[1]: td = td[:-1] + (tdlr,) return ((len(t),) + td, ty) elif any([not classify(a) in simpletypes for a in t]): return None else: z = [type(a) for a in t] if len(set(z)) == 1: z = (z[0],) return ((len(t),), tuple(z))
def summary(self, k): v = self[k] vt = search.classify(v) if vt in search.simpletypes: return str(v) elif vt == '#': if v.size < 10: return str(v) else: return "%s-array:%s" % (str(v.shape), v.dtype.str) elif vt == '[': if len(str(v)) < 60: return str(v) else: return search.seqtype(v) elif vt == '{': n = len(v.keys()) sn = len(v.keys(depth=-1)) - n return "%i-doc (%i subkeys)" % (n, sn) else: return str(v)
def resolvelink(self, d, k='', value=True): ''' return the value of a link or slice dictionary d, located at key k (if k is None, relative links are not allowed) ''' k = k.split('.') t = d['_link'] if t.startswith('.'): nt = t.rstrip('.') nl = len(t) - len(nt) if nl > len(k): report('WARNING: relative link %s encountered at %s. Not enough nesting levels to specify it.' % ( t, '.'.join(k))) return None else: t = '.'.join(k[:-nl]) + "." + nt if not value: return t if not t.strip(): return self nv = self.get(t) if nv == None: report('WARNING: link at %s to %s is broken' % ('.'.join(k), t)) return None if d['_slice'] != None: nvt = search.classify(nv) sl = d['_slice'] if nvt == '#': if not type(sl[0]) == tuple: sl = (sl,) nv = nv[[apply(slice, t) for t in sl]] elif nvt == '[': if type(sl[0]) == tuple: sl = sl[0] nv = nv[apply(slice, sl)] else: report('WARNING: slice at %s of %s tries to slice a non-sequence' % ('.'.join(k), t)) nv = None return nv
def a2t(doc): for k in doc.keys(-1, None, True, False): v = doc[k] if classify(v) == "#": doc[k] = astuple(v)