Current File : //opt/cloudlinux/venv/lib/python3.11/site-packages/guppy/heapy/RefPat.py
def str_as_atr(s):
if s == '_':
return []
atr = []
i = 0
while i < len(s):
v = s[i]
if i + 1 < len(s) and s[i+1].isdigit():
n = 0
i = i + 1
while i < len(s) and s[i].isdigit():
n = n * 10 + int(s[i])
i += 1
else:
i += 1
n = 1
for j in range(n):
atr.append(v)
return atr
def atr_as_str(atr):
if not atr:
return '_'
prefl = []
prestr = ''.join([str(x) for x in atr])
i = 0
while i < len(prestr):
c = prestr[i]
j = i+1
while j < len(prestr) and prestr[j] == c:
j += 1
if j - i > 2:
prefl.append(c)
prefl.append(str(j-i))
else:
while i < j:
prefl.append(c)
i += 1
i = j
return ''.join(prefl)
def str_as_ixl(s):
return [ord(ch)-ord('a') for ch in str_as_atr(s)]
def ixl_as_str(ixl):
return atr_as_str([chr(ix + ord('a')) for ix in ixl])
class Paths:
def __init__(self, mod, rp, key, extended=True, andsets=(), variant=2):
self.mod = mod
self._hiding_tag_ = mod._hiding_tag_
self.key = key
self.rp = rp
self.extended = extended
self.srcrow = rp.get_row(self.key)
self.variant = variant
self.andsetbyname = {}
row = self.srcrow
while row is not None:
self.andsetbyname[row.ixlstr] = mod.Use.Anything
row = row.parent
if isinstance(andsets, dict):
self.andsetbyname.update(andsets)
elif isinstance(andsets, (tuple, list)):
row = self.srcrow
for i, s in enumerate(andsets):
if row is None:
raise ValueError('andsets argument is too long')
if s is not None:
self.andsetbyname[row.ixlstr] = s
row = row.parent
else:
raise TypeError('andsets argument must be dict, tuple, or list')
mod.OutputHandling.setup_printing(
self,
stop_only_when_told=variant >= 2)
def get_str_of_path_component_singleton(self, set):
return set.brief.lstrip('<1 ').rstrip('>')
def source_to_target_info(self):
src = 'Source'
tgt = 'Target'
via = 'Via'
row = self.srcrow
indent = 0
while row is not None:
if row.parent is None:
a = tgt
elif row is srcrow:
a = src
else:
a = via
a = ' '*indent + a
name = row.ixlstr
a = a + ' ' + ' '*(8+srcrow.depth*indinc -
len(name)-len(a)) + name + ': '
yield a+row.getsummary(mod.line_length-len(a))
row = row.parent
indent += indinc
def _oh_get_label(self):
return 'Paths from source %r to target %r.' % (self.srcrow.ixlstr, '_')
def _oh_get_line_iter(self):
return getattr(self, 'get_line_iter_%s' % (self.variant,))()
def _oh_get_more_state_msg(self, startindex, lastindex):
return ''
def get_line_iter_1(self):
# Original variant indenting from left to right
mod = self.mod
srcrow = self.srcrow
srcset = srcrow.set
indinc = 2
if srcrow.depth >= 10:
indinc = 1
def genlines(row, ks, indent=0):
par = row.parent
for key, i, set in ks:
sidx = '%s[%d]' % (row.ixlstr, i)
if self.extended:
strsing = self.get_str_of_path_component_singleton(set)
else:
strsing = ''
vline = '%s %s %s %s' % (
key,
' '*(40-len(key) - len(sidx)),
sidx,
strsing
)
yield vline
if par is None:
continue
def get_nks(key, set):
parset = set.referents & par.set
for i, p in enumerate(parset.byid.parts):
rels = mod.Path.relations(set.theone, p.theone)
for rel in rels:
if rel is mod.Path.identity:
continue
if rel is mod.Path.norelation:
k = '??'
else:
k = str(rel) % ''
k = ' '*(indent+indinc)+k
yield k, i, p
for line in genlines(par, get_nks(key, set), indent+indinc):
yield line
def get_ks():
for i, s in enumerate(srcset.byid.parts):
k = '[%d] ' % i
k = k + (' -'*20)[:36-len(k)-srcrow.depth]
yield k, i, s
for line in genlines(srcrow, get_ks()):
yield line
return
def get_line_iter_2(self):
# Newer variant
mod = self.mod
srcrow = self.srcrow
indinc = 1
if srcrow.depth >= 10:
indinc = 1
lno = [0]
seen = {}
indir = 1
if indir == 1:
max_ixlstr_len = 0
max_str_len_set = 0
row = srcrow
while row:
if len(row.ixlstr) > max_ixlstr_len:
max_ixlstr_len = len(row.ixlstr)
if len(str(len(row.set.nodes))) > max_str_len_set:
max_str_len_set = len(str(len(row.set.nodes)))
row = row.parent
def genlines(row, part, idx):
seen[part.nodes, row.depth] = lno[0]
sidx = row.ixlstr
idxs = '[%d]' % idx
if indir < 0:
indent = (row.depth)*indinc
sidx = '%s%s%s' % (
sidx, ' '*(6+indent-len(sidx)-len(idxs)), idxs)
if row.parent is None:
sidx += ' == %s' % part.brief
else:
#idxs = ('[%.'+str(max_str_len_set)+'d]')%idx
sidx = '%s%s%s' % (sidx,
' '*(3+max_str_len_set +
max_ixlstr_len-len(sidx)-len(idxs)),
idxs)
sidx += ' ' * (srcrow.depth + 1 - row.depth)
if row.parent is not None:
sidx += '@'
else:
sidx += '= %s' % part.brief
if row.parent is None:
#vline += ' == %s'%self.get_str_of_path_component_singleton(part)
vline = '%2s: %s' % (lno[0], sidx)
lno[0] += 1
yield ('STOP_AFTER', vline)
return
referents = part.referents & row.parent.set & self.andsetbyname[row.parent.ixlstr]
relations = mod.Path.relations
iso = mod.Use.iso
s = part.theone
t = [(relations(s, p.theone), p.by(referents.er), i)
for (i, p) in enumerate(referents.byid.parts)]
for (rels, p, i) in t:
relstrings = []
for rel in rels:
if rel is mod.Path.identity:
continue
if rel is mod.Path.norelation:
k = '??'
else:
k = str(rel) % ''
relstrings.append(k)
relsstr = ' / '.join(relstrings)
seenlno = seen.get((p.nodes, row.parent.depth))
vline = '%2s: %s' % (lno[0], sidx)
lno[0] += 1
if seenlno is not None:
relsstr += ' -> #%d' % seenlno
yield ('STOP_AFTER', vline + ' ' + relsstr)
else:
yield vline + ' ' + relsstr
for line in genlines(row.parent, p, i):
yield line
for i, p in enumerate((srcrow.set & self.andsetbyname[srcrow.ixlstr]).byid.parts):
for line in genlines(srcrow, p, i):
yield line
class RefPatIter:
def __init__(self, rp, start=0):
self.rp = rp
self._hiding_tag_ = rp._hiding_tag_
self.ix = start
def __iter__(self):
return self
def __next__(self):
try:
x = self.rp[self.ix]
except IndexError:
raise StopIteration
self.ix += 1
return x
class RefPatRow:
def __init__(self, rp, kindset, seenline, ixl, parent):
self.rp = rp
self._hiding_tag_ = rp._hiding_tag_
self.kindset = kindset
self.kind, self.set = kindset
assert self.set <= self.kind
self.seenline = seenline
self.ixl = ixl[:]
self.parent = parent
if parent is not None:
self.depth = parent.depth + 1
else:
self.depth = 0
self.index = 0
self.maxdepth = rp.depth
self.max_str_len = rp.mod.line_length
self.ixlstr = ixl_as_str(ixl)
self.isready = 0
self.children = []
def __str__(self):
prestr = '%2d: %s ' % (self.index, self.ixlstr)
if self.index & 1:
fillpat = ' ' * 100
else:
fillpat = '-'*100
lps = len(prestr)
fill = fillpat[lps:9+self.depth]
if self.seenline:
ref = '[^ %s]' % self.seenline.index
elif self.isroot:
ref = '[R]'
elif self.depth > 0 and self.set <= self.rp.stopkind:
ref = '[S]'
elif self.depth < self.maxdepth:
ref = '[-]'
else:
ref = '[+]'
prefix = '%s%s %s ' % (prestr, fill, ref)
return '%s%s' % (prefix, self.getsummary(self.max_str_len-len(prefix)))
def getchild(self, ix):
while ix >= len(self.children) and not self.isready:
self.rp.generate(len(self.rp.lines))
return self.children[ix]
def getsummary(self, max_len):
kind, set = self.kind, self.set
summary = set.fam.get_str_refpat(set, kind, max_len)
return summary
class ReferencePattern:
__doc__ = '<Help Text'
help = """\
Methods
"""
def __init__(self, mod, set, depth, er, relimg, bf, stopkind, nocyc):
self.mod = mod
self._hiding_tag_ = mod._hiding_tag_
self.View = mod.View
self.set = set
self.depth = depth
self.er = er
self.bf = bf
self.stopkind = stopkind
self.nocyc = nocyc
self.is_initialized = 0
self.totcount = set.count
self.totsize = set.indisize
self.kind = set.kind
self.kindset = (self.kind, self.set)
self.relimg = relimg
self.top = self
mod.OutputHandling.setup_printing(self)
self.View.referrers_add_target(self)
self.reset_nogc()
self.is_initialized = 1
def __getattr__(self, s):
if not self.is_initialized:
raise AttributeError(s)
try:
return getattr(self.__class__, s)
except AttributeError:
pass
try:
row = self.get_row_named(s)
except ValueError:
raise AttributeError(s)
return row.set
def __getitem__(self, ix):
return self.get_row_indexed(ix).set
def __iter__(self, start=0):
return RefPatIter(self, start)
def __len__(self):
self.generate()
return len(self.lines)
def _oh_get_label(self):
return 'Reference Pattern by <' + self.er.classifier.get_byname() + '>.'
def _oh_get_more_state_msg(self, startindex, lastindex):
if self.isfullygenerated:
msg = '%d more lines. ' % (len(self.lines) - 1-lastindex,)
else:
msg = ''
return msg
def _oh_get_line_iter(self):
it = self.iterlines(0)
for el in it:
yield str(el)
def generate(self, ix=None):
while ix is None or ix < 0 or ix >= len(self.lines):
try:
self.lines.append(next(self.lg))
except StopIteration:
self.isfullygenerated = 1
return
self.lines[-1].index = len(self.lines) - 1
def get_row(self, key):
try:
[][key]
except TypeError:
return self.get_row_named(key)
except IndexError:
return self.get_row_indexed(key)
def get_row_indexed(self, ix):
self.generate(ix)
return self.lines[ix]
def get_row_named(self, name):
row = self.get_row_indexed(0)
for ix in str_as_ixl(name):
try:
row = row.getchild(ix)
except IndexError:
raise ValueError(
'Reference pattern has no row named %r' % name)
return row
def iterlines(self, start=None):
if start is None:
start = 0
while 1:
try:
yield self.get_row_indexed(start)
except IndexError:
return
start += 1
def linegenerator(self, xxx_todo_changeme, ixl, parent=None):
(kind, set) = xxx_todo_changeme
seenline = self.seensets.get(set.nodes)
ixl = list(ixl)
line = RefPatRow(self, (kind, set), seenline=seenline,
ixl=ixl, parent=parent)
children = self.get_children(line)
line.isroot = not children
if seenline is None:
self.seensets[set.nodes] = line
if parent is not None:
parent.children.append(line)
yield line
depth = line.depth
if (not seenline and depth < self.depth and
(depth == 0 or not (set <= self.stopkind))):
for i, cs in enumerate(children):
ixl.append(i)
for rl in self.linegenerator(cs, ixl, line):
yield rl
ixl.pop()
line.isready = 1
def get_children(self, line):
(kind, set) = line.kindset
chset = self.relimg(set)
if self.nocyc:
while line is not None:
chset -= line.set
line = line.parent
return [(row.kind, row.set)
for row in self.get_partition(chset, self.er).get_rows()]
def get_partition(self, set, er):
p = self.mod.Part.partition(set, er)
return p
def paths(self, key, **kwds):
return Paths(self.mod, self, key, **kwds)
def reset(self):
self.reset_nogc()
self.printer.reset()
self.mod._root.gc.collect()
def reset_nogc(self):
self.isfullygenerated = 0
self.seensets = {}
self.lines = []
self.lg = self.linegenerator(self.kindset, [])
self.lastindex = None
class _GLUECLAMP_:
_preload_ = ('_hiding_tag_',)
depth = 7
line_length = 80
_uniset_exports = ('rp',)
_chgable_ = ('er',
'depth',
'line_length',
)
# 'module imports'
_imports_ = (
'_parent:OutputHandling',
'_parent:Part',
'_parent:Path',
'_parent:UniSet',
'_parent:Use',
'_parent:View',
'_parent.View:_hiding_tag_',
)
#
def _get_er(self): return self.Use.Clodo
def _get_stopkind(self):
hp = self.Use
return (
hp.Type.Module |
hp.Type.Type |
hp.Type.Module.dictof |
hp.Type.Type.dictof |
hp.Type.Code |
hp.Type.Frame
)
def rp(self, X, depth=None, er=None, imdom=0, bf=0, src=None, stopkind=None,
nocyc=False, ref=None):
"""rp(X, depth=None, er=None, imdom=0, bf=0, src=None, stopkind=None, nocyc=False, ref=None)
Reference pattern forming.
Arguments
X Set of objects for which a reference pattern is sought.
depth The depth to which the pattern will be generated. The
default is taken from depth of this module.
er The equivalence relation to partition the referrers. The default
is Clodo.
imdom If true, the immediate dominators will be used instead
of the referrers. This will take longer time to calculate,
but may be useful to reduce the complexity of the reference
pattern.
bf If true, the pattern will be printed in breadth-first
order instead of depth-first. (Experimental.)
src If specified, an alternative reference source instead
of the default root.
stopkind
nocyc
ref
Description
Return a reference pattern object based on the objects in the set X.
The reference pattern object is of class ReferencePattern. It is
described in XXX.
"""
if depth is None:
depth = self.depth
X = self.UniSet.idset_adapt(X)
if src is not None:
# Creates an entire new guppy tree
# Mostly for testing purposes -
# can likely cause type problems generally
src = self.UniSet.idset_adapt(src)
self = self._root.guppy.Root().guppy.heapy.RefPat
self.View.root = tuple(src.nodes)
X = self.Use.idset(X.nodes)
if er is None:
er = self.er # NEEDS to be loaded after new Classifier created
if imdom:
def relimg(X): return X.imdom
elif ref is not None:
if ref == 'gc':
def relimg(X): return X.referrers_gc
elif ref == 'gcx':
relimg = (lambda x: x.referrers_gc
- self._root.guppy.sets.ImmNodeSet
- self._parent.heapyc.NodeGraph
- self.View.ObservationList)
elif ref == 'imdom':
def relimg(X): return X.imdom
elif callable(ref):
relimg = ref
else:
raise ValueError(
"ref should be 'gc', 'gcx', 'imdom', or a callable")
else:
def relimg(X): return X.referrers
if stopkind is None:
stopkind = self.stopkind
rp = ReferencePattern(self, X, depth, er, relimg, bf, stopkind, nocyc)
return rp