X7ROOT File Manager
Current Path:
/opt/cloudlinux/venv/lib/python3.11/site-packages/guppy/gsl
opt
/
cloudlinux
/
venv
/
lib
/
python3.11
/
site-packages
/
guppy
/
gsl
/
??
..
??
Document.py
(57.55 KB)
??
DottedTree.py
(8.58 KB)
??
Exceptions.py
(402 B)
??
FileIO.py
(2.6 KB)
??
Filer.py
(3.83 KB)
??
Gsml.py
(2.69 KB)
??
Help.py
(1018 B)
??
Html.py
(17.46 KB)
??
Latex.py
(25.16 KB)
??
Main.py
(66.91 KB)
??
SpecNodes.py
(18.48 KB)
??
Tester.py
(23.99 KB)
??
Text.py
(31.13 KB)
??
XHTML.py
(18.38 KB)
??
__init__.py
(53 B)
??
__pycache__
Editing: Main.py
from guppy.etc.Descriptor import property_nondata from guppy.gsl.Exceptions import * class SpecEnv: def __init__(self, mod): self.mod = mod self.imported_packages = {} self.importing_packages = {} self.error_reports = [] self.num_errors = 0 self.num_warnings = 0 def errmsg_context(self, context): linetext = '' filename = '<unknown file>' if context is not None: node = context # Assume it's a node - that's all we use for now lineno = node.index + 1 src = node.src if src is not None: filename = src.filename linetext = src.get_line(index=context.index) print('%s:%s:' % (filename, lineno)) if linetext: print(' %r' % linetext) def error(self, message, context=None, exception=ReportedError, more=(), harmless=0): self.error_reports.append( (message, context, exception, more, harmless)) if harmless: self.num_warnings += 1 else: self.num_errors += 1 self.errmsg_context(context) if harmless: print('* %s' % message) else: print('*** %s' % message) print() for msg, ctx in more: self.errmsg_context(ctx) print(' %s' % msg) print() if self.debug: import pdb pdb.set_trace() else: if self.num_errors >= self.max_errors: raise TooManyErrors('Too many errors, giving up') if exception is not None: raise exception def get_filers(self, documents): filers = [] for d in documents: filers.extend(d.get_filers(self.output_dir)) return filers def import_package(self, name, context): pac = self.imported_packages.get(name) if pac is None: if name in self.importing_packages: self.error('Invalid mutual import involving packages %r' % ( list(self.importing_packages.keys()),), context) self.importing_packages[name] = 1 filename = name.replace('.', self.mod.IO.path.sep)+'.gsl' ip = self.package_of_filename(filename, name) pac = self.mkPackage(ip) self.imported_packages[name] = pac del self.importing_packages[name] return pac def link_documents(self, documents): defines = {} links = {} def walk(node): t = node.tag if t == 'link_to': name = node.arg.strip() links.setdefault(name, []).append((d, node)) elif t == 'define': name = node.arg.strip() defines.setdefault(name, []).append((d, node)) elif t == 'to_tester_only': return for ch in node.children: walk(ch) for d in documents: node = d.get_result() walk(node) for name, ds in list(defines.items()): if len(ds) > 1: print('Duplicate definition of name %r, defined in:' % name) for (d, node) in ds: print(' %s line %s' % (d.get_doc_name(), node.index+1)) print('Will use the first one.') nodefs = [] for name, ds in list(links.items()): if name not in defines: used = {} for (d, node) in ds: used[d.get_doc_name()] = 1 node.tag = 'link_to_unresolved' used = list(used.keys()) used.sort() used = ', '.join(used) nodefs.append('%s used in %s' % (name, used)) else: defd, defnode = defines[name][0] for (d, node) in ds: if d is defd: node.tag = 'link_to_local' else: node.tag = 'link_to_extern' node.children = (defd.doc_name_node,)+node.children if nodefs: nodefs.sort() print('Unresolved links:') for nd in nodefs: print(' ', nd) def mkPackage(self, sub): pac = PackageDescription(self, sub, sub) pac.output_dir = self.output_dir pac.resolve_all() return pac def package_of_filename(self, filename, packname=None, nostrip=1, input_string=None): mod = self.mod if packname is None: if filename.endswith('.gsl'): packname = filename[:-4] else: packname = filename packname = packname.replace(mod.IO.path.sep, '.') if self.input_dir: filename = mod.IO.path.join(self.input_dir, filename) else: filename = mod.IO.path.abspath(filename) if input_string is not None: data = input_string else: data = mod.IO.read_file(filename) md5 = mod.md5() md5.update(b'.filename: %s\n' % filename.encode('utf-8')) md5.update(b'.packname: : %s\n' % packname.encode('utf-8')) md5.update(data.encode('utf-8')) digest = md5.digest() if digest in mod.package_cache: return mod.package_cache[digest] node = mod.SpecNodes.node_of_string(data, filename, nostrip=nostrip) numerr = self.num_errors print('Making package subject %r' % packname) package = PackageSubject(mod, self, node, packname, filename) if numerr == self.num_errors: mod.package_cache[digest] = package return package def process_main(self, filename, input_dir=None, output_dir=None, debug=False, max_errors=None, process_despite_errors=False, raise_at_errors=False, input_string=None ): if input_dir is None: input_dir = self.mod.input_dir self.input_dir = input_dir if output_dir is None: output_dir = '/tmp' self.output_dir = output_dir self.debug = debug if max_errors is None: max_errors = self.mod.max_errors self.max_errors = max_errors try: pac = self.mkPackage(self.package_of_filename( filename, input_string=input_string)) documents = pac.get_documents() if not documents: self.error('No documents specified.', exception=None, harmless=1) if not self.num_errors or process_despite_errors: print('Linking') self.link_documents(documents) if not self.num_errors or process_despite_errors: filers = self.get_filers(documents) except TooManyErrors: giving_up = ' giving up --' else: giving_up = '' if not self.num_errors: for filer in filers: f = self.mod.Filer.filer(filer) print('Writing: ', ', '.join(list(f.writefile_names))) f.write() if self.num_warnings: print('* %d warning%s reported.' % ( self.num_warnings, 's'[:self.num_warnings > 1])) if self.num_errors: print('*** %d error%s reported --%s no files written.' % ( self.num_errors, 's'[:self.num_errors > 1], giving_up)) if raise_at_errors: raise HadReportedError('Some error has been reported.') class UntypedDescription: def __init__(self, env, tgt, src): self.env = env self.pac = env.pac self.mod = env.mod self.tgt = tgt self.src = src def combine_with_subject(self, subject): self.combined_subjects.append(subject) def resolve_all(self): self.resolve_primary() self.resolve_lookuped() def resolve_primary(self): self.resolve_type() self.resolve_tgt() def resolve_type(self): dc = self.tgt.description_class if not hasattr(dc, 'd_tag'): self.d_tag = self.tgt.tag self.tgtfullname = self.mod.tgt_prefix+self.tgt.fullname self.tgtnode = self.tgt.node self.tgtlastname = self.tgt.lastname self.srcnode = self.tgt.node self.srcfullname = self.src.fullname self.srclastname = self.tgt.lastname self.__class__ = dc class Description: d_max_occur = None # Max occurence as an aspect if a number d_sub = () # Tags of allowed sub-aspects d_type = 'other' d_is_def = 0 is_lookuped = False is_synthetic = False # Set if it was made not to correspond with a user node the_less_specific_descr = None args = () def aspects_extend(self, as_): for asp in as_: try: k = asp.src.definame # k = asp.tgt.definame # Humm if k: w = self.localview.get(k) if w: if w is asp: # May happen eg as in test16, for a product # But it is somewhat mystical. continue self.error('Duplicate aspect %r (may be correct in future).' % (k,), w.src.node, DuplicateError) self.localview[k] = asp bn = self.aspects_by_tag.setdefault(asp.d_tag, []) oc = asp.d_max_occur if oc is not None: if len(bn) + 1 > oc: self.error('More than %d %r aspects.' % ( oc, asp.d_tag), asp.src.node) bn.append(asp) self.aspects.append(asp) except ReportedError: pass def aspects_extend_by_subjects(self, subjects): for v in subjects: try: asp = UntypedDescription(self, v, v) asp.resolve_primary() self.aspects_extend((asp,)) except ReportedError: pass def deftgt(self, forme=None): if forme is None: forme = self try: tgtview = self.tgtview except AttributeError: self.env.deftgt(forme) else: if forme.tgtfullname in tgtview: self.error('Duplicate definition of %r' % forme.tgtfullname, forme.src.node) tgtview[forme.tgtfullname] = forme def error(self, msg, node=None, exception=ReportedError, **kwds): return self.pac.env.error(msg, node, exception, **kwds) def resolve_lookuped(self): if not self.is_lookuped: self.is_lookuped = 1 self.resolve_aspects() def resolve_tgt(self): self.deftgt() def find_aspects(self, tag='*', *tags): al = [] tag = tag.replace(' ', '_') if tag in ('*', 'arg'): for a in self.args: a.resolve_lookuped() al.append(a) if tag == '*': for a in self.aspects: a.resolve_lookuped() al.append(a) return al tags = (tag,) + tags for a in self.aspects: if a.d_tag in tags: a.resolve_lookuped() al.append(a) return al def find_arg_aspects(self): al = [] for a in self.args: a.resolve_lookuped() al.append(a) for a in self.aspects: if a.d_tag in ('arg', 'seq', 'repeat', 'alt', 'args', 'optionals', 'key_arg', 'draw', 'no_arg'): a.resolve_lookuped() al.append(a) return al def find_kind_aspects(self): kas = [] for asp in self.find_aspects('*'): if asp.d_tag in ('attribute', 'mapping', 'kind', 'either', 'kind_of', 'superkind', 'superkind_of'): kas.append(asp) else: pass return kas def merge_policy(self, descrs): return descrs def get_descr_for_aspect(self, aspect): if not self.aspects and self.the_less_specific_descr is not None: return self.the_less_specific_descr.get_descr_for_aspect(aspect) return self def get_atom_beams(self): aspects = self.find_aspects('*') aks = [] for asp in aspects: if asp.d_tag in ('attribute', 'mapping', 'either', 'operator', 'inplace_operator', 'reverse_operator', 'function_operator', 'delitem', 'getitem', 'setitem', ): aks.append(beam(self, asp)) elif asp.d_tag in ('kind', 'kind_of', 'subkind_of') and asp is not self: a = beam(self, asp) for b in asp.get_atom_beams(): aks.append(a + b) return aks def get_aspects_kind(self, aspects=None): if aspects is None: aspects = self.find_aspects('*') aks = [] for asp in aspects: if asp.d_tag in ('attribute', 'mapping', 'either', 'operator', 'inplace_operator', 'reverse_operator', 'function_operator', 'delitem', 'getitem', 'setitem', ): aks.append(asp) elif asp.d_tag in ('kind', 'kind_of', 'subkind_of') and asp is not self: aks.extend(asp.get_atom_kinds()) return aks def get_atom_kinds(self): return self.get_aspects_kind([self] + self.find_aspects('*')) def get_examples(self, get_all=False): examples = [] exs = self.find_aspects('example') for ex in exs: examples.extend(ex.get_examples()) return examples def get_re(self, opt): if opt.get('get_examples'): exres = [self.mod.RE.Single(x) for x in self.get_examples()] if not exres: self.error('Test coverage error: no examples specified.', self.tgt.node, CoverageError) return self.mod.RE.Union(*exres) else: return self.mod.RE.Single(self) def get_most_specific_descrs(self, descrs): nds = [] for d in descrs: nds = [x for x in nds if not d.is_more_specific_than(x)] for x in nds: if x is d: break if x.is_more_specific_than(d): break else: nds.append(d) return nds def get_package(self): return self.pac def is_more_specific_than(self, d): r = self.the_less_specific_descr return r is d or (r is not None and r.is_more_specific_than(d)) def get_self_name(self): def find(e): sa = e.find_aspects('self') if sa: # length = 1, has been checked assert len(sa) == 1 return sa[0].src.node.arg.strip() if e.d_tag != 'package': return find(e.env) return None return find(self) def gen_description_doc(self, out): ds = self.find_aspects('description') if not ds: out.gen_text('<NO DESCRIPTION OF %r>' % self.tgtfullname) else: for d in ds: d.gen_doc(out) def get_id_name(self): return self.tgtfullname def get_link_name(self): return self.tgtfullname def get_local_name(self): return self.srclastname def get_test_name(self): return self.tgtfullname def get_name(self): return self.tgtfullname def get_Name(self): # To be used in Name of doc. n = self.find_aspects('name') if not n: name = self.tgtlastname else: name = n.tgt.node.arg.strip() return name def get_descr_by_subject(self, subject): return self.pac.get_descr_by_subject(subject) def init_localview(self, only_vars=0): self.localview = {} self.aspects = [] self.aspects_by_tag = {} if not only_vars: self.aspects_extend_by_subjects(self.tgt.aspects) def resolve_aspects(self): self.init_localview() if self.src.args: self.args = [self.env.get_descr_by_subject( arg) for arg in self.src.args] self.resolve_special() def resolve_special(self): # To be overridden with special checks etc. pass def get_the_one_argument(self): arg = self.src.node.arg.strip() if self.aspects: 'No children expected for %r' % self.node.tag return arg def make_and_test_kind(self, kinds): ks = [] def flatten(k): if k.d_tag == 'kind': for k1 in k.find_kind_aspects(): flatten(k1) else: ks.append(k) if (len(kinds) == 1 and kinds[0].d_tag == 'kind'): return kinds[0] for k in kinds: flatten(k) kinds = ks k = Kind() k.d_tag = 'kind' k.aspects = kinds k.tgtfullname = '(%s)' % ('&'.join([x.tgtfullname for x in kinds])) k.is_lookuped = 1 return k def make_and_kind(self, kinds): if (len(kinds) == 1 and kinds[0].d_tag in('kind', 'kind_of')): return kinds[0] k = Kind() k.d_tag = 'kind' k.aspects = kinds k.tgtfullname = '(%s)' % ('&'.join([x.tgtfullname for x in kinds])) k.is_lookuped = True k.is_synthetic = True return k def make_or_kind(self, kinds): if len(kinds) == 1: return kinds[0] else: k = Superkind() k.d_tag = 'kind' k.aspects = kinds k.tgtfullname = '(%s)' % ('|'.join([x.tgtfullname for x in kinds])) k.is_lookuped = True k.is_synthetic = True return k class Definition(Description): d_is_def = 1 d_type = 'definition' def export_aspects(self, src): src.__class__ = self.__class__ if src.d_tag == 'import': src.d_tag = self.d_tag else: if src.d_tag != self.d_tag: # Can't think of how this would happen - # so not yet converted to .error() raise ImportError('Different description tag') src.aspects_extend(self.aspects) class DescriptionDescription(Description): d_sub = ('text', ) d_tag = 'description' def gen_doc(self, out): self.srcnode.arg_accept(out) class Default(DescriptionDescription): def gen_doc(self, out): arglines = self.srcnode.arg.strip().split('\n') default = arglines[0] rest = '\n'.join(arglines[1:]) out.open('dl') out.open('dt') out.open('strong') out.gen_text('Default: ') out.close() out.gen_text(default) out.close() out.open('dd') out.gen_text(rest) self.srcnode.children_accept(out) out.close() out.close('dl') class DescriptionWithHeader(DescriptionDescription): def gen_doc(self, out): arglines = self.srcnode.arg.strip().split('\n') header = arglines[0] rest = '\n'.join(arglines[1:]) out.open('dl') out.gen_outer_dt(header) out.open('dd') out.gen_text(rest) self.srcnode.children_accept(out) out.close() out.close() class Comment(DescriptionDescription): d_tag = 'comment' pass class Either(Description): d_type = 'with_args' def get_atom_beams(self): return [beam(self)] def get_atom_kinds(self): return [self] def get_alt_kinds(self): return self.find_kind_aspects() class Import(Definition): d_sub = ('from', 'resolve_by', 'using', 'attribute', 'condition', 'description', 'comment', 'constructor', 'mapping', 'method', 'operator', 'inplace_operator', 'reverse_operator', 'function_operator', 'delitem', 'getitem', 'setitem', 'self', 'subkind_of', ) def resolve_tgt(self): self.is_lookuped = 1 using_name, using_node = self.src.imp_using_map.get( self.src.definame, (self.src.definame, self.src.node)) import_node = self.src.node ds = [self.pac.import_package(from_name, from_node). get_descr_by_name(using_name, using_node) for (from_name, from_node) in self.src.imp_froms] if len(ds) == 1: d = ds[0] else: d = Product(self, ds, ProductSubject([x.src for x in ds]), self.src.imp_resolve_mode) self.tgt = d.tgt self.tgtfullname = self.mod.tgt_prefix+self.tgt.fullname self.the_less_specific_descr = d self.init_localview(only_vars=1) d.export_aspects(self) self.aspects_extend_by_subjects(self.src.aspects) self.deftgt() def resolve_aspects(self): pass class Product(Description): def __init__(self, env, ds, src, mode): self.env = env self.mod = env.mod self.src = src self.mode = mode self.pac = env.pac tgt = ds[0].tgt for d in ds[1:]: if d.tgt is not tgt: self.error('Import error when importing from multiple packages:\n' + ' Can not make a product of %r (tgt = %r) with %r (tgt = %r)\n' % ( d.src.fullname, d.tgt.fullname, ds[0].src.fullname, ds[0].tgt.fullname) + ' because of different targets.', d.src.node) self.tgt = tgt self.ds = ds def export_aspects(self, src): for d in self.ds: d.export_aspects(src) def is_more_specific_than(self, d): for x in self.ds: if x is d or x.is_more_specific_than(d): return True return False class PackageDescription(UntypedDescription): def __init__(self, env, tgt, src): self.env = env self.pac = self self.mod = env.mod self.tgt = tgt self.src = src class ErrorDescription: d_tag = 'error' def __init__(self, env): self.env = env def get_id_name(self): return '<error>.<error>' class Package(Description): d_sub = ('and', 'comment', 'condition', 'document', 'import', 'kind', 'macro', 'superkind', ) def get_tgtdicts(self): seen = {id(self.tgtview): 1} tgtdicts = [self.tgtview] for p in list(self.imported_packages.values()): sds = p.get_tgtdicts() for sd in sds: if id(sd) not in seen: seen[id(sd)] = 1 tgtdicts.append(sd) return tgtdicts def get_descr_by_name(self, name, context=None): if name.startswith(self.mod.tgt_prefix): return self.get_descr_by_tgt_name(name, context) e = self parts = name.split('.') for part in parts: try: e = e.localview[part] except KeyError: assert context self.env.error( 'Undefined: %r in %r.' % (part, e.get_id_name()), context, exception=UndefinedError) e.resolve_lookuped() return e def get_descr_by_subject(self, subject): name = subject.fullname if name.startswith(self.srcfullname+'.'): name = name[len(self.srcfullname)+1:].strip() else: self.error('Undefined: %r' % name, subject.node) return self.get_descr_by_name(name, subject.node) def get_descr_by_tgt_name(self, name, context=None): tgtdicts = self.get_tgtdicts() descrs = [] for tgtdict in tgtdicts: if name in tgtdict: d = tgtdict[name] d.resolve_lookuped() d = d.get_descr_for_aspect('*') descrs.append(d) if not descrs: self.error('No definition of tgt %r' % name, context, UndefinedError) descrs = self.get_most_specific_descrs(descrs) if len(descrs) > 1: descrs = self.merge_policy(descrs) if len(descrs) > 1: self.error('Conflicting descriptions of %r:%r' % ( name, [d.src.fullname for d in descrs]), context, DuplicateError) return descrs[0] def get_filename(self): return self.src.filename def get_package(self): return self def resolve_tgt(self): self.tgtview = {} def resolve_aspects(self): self.imported_packages = {} self.init_localview() def import_package(self, name, context): pac = self.imported_packages.get(name) if pac is None: pac = self.env.import_package(name, context) self.imported_packages[name] = pac return pac def get_documents(self): documents = [] for doc in self.src.documents: node = doc.node doc = self.mod.Document.document(node, self) documents.append(doc) return documents class Attribute(Definition): d_sub = ('attribute', 'comment', 'description', 'description_with_header', 'either', 'kind_of', 'mapping', 'method', 'self') def export_aspects(self, src): src.__class__ = self.__class__ src.aspects_extend(self.aspects) def get_attr_name(self): return self.tgtlastname def get_name(self): return self.tgtlastname def get_kind(self): kas = self.find_kind_aspects() return self.make_and_kind(kas) def get_kind_name(self): k = self.get_kind() if k.d_tag == 'kind_of': kas = k.find_kind_aspects() if len(kas) == 1: k = kas[0] else: raise ValueError("Don't know how to name this kind, %r" % self) return k.tgtfullname def get_link_name(self): # xxx needs smoother logic s = '%s.%s' % (self.get_descr_by_subject( self.tgt.parent).get_link_name(), self.tgt.lastname) return s def get_test_kind(self): kas = self.find_kind_aspects() return self.make_and_test_kind(kas) def is_method(self): return (self.find_aspects('mapping') and not self.find_aspects('kind_of')) def get_op_name(self): return self.get_attr_name() class KindOf(Description): d_type = 'with_args' d_sub = () class SubkindOf(Description): d_type = 'with_args' d_sub = ('description',) class Kind(Definition): d_sub = ('attribute', 'condition', 'description', 'comment', 'constructor', 'example', 'mapping', 'method', 'operator', 'inplace_operator', 'reverse_operator', 'function_operator', 'self', 'subkind_of', 'delitem', 'getitem', 'setitem', ) def get_attributes(self): return self.find_aspects('attribute') def get_mappings(self): return self.find_aspects('mapping') class Superkind(Definition): d_sub = ('comment', 'description', 'example', 'superkind_of') def get_local_name(self): return self.srclastname class SuperkindOf(Description): d_type = 'with_args' def get_examples(self, enough=1): examples = Description.get_examples(self, enough) if len(examples) < enough: for ka in self.find_kind_aspects(): if ka is self: continue examples.extend(ka.get_examples(enough-len(examples))) if len(examples) >= enough: break return examples class Example(Description): d_sub = ('comment', 'description', 'in_context') partab = {"'''": "'''", '"""': '"""', '(': ')', '[': ']', '{': '}' } def get_ex_text(self): return self.src.ex_text def get_examples(self, get_all=False): return [self] def get_ctx_text(self): asp = self.find_aspects('in_context') if not asp: return '' # It is of length 1, has been checked. return asp[0].tgt.node.arg.strip() def get_use_text(self, x): return x class InContext(Description): d_max_occur = 1 class Defines(Description): d_type = 'with_args' def get_defined_tgt_names(self): return [x.tgtfullname for x in self.find_aspects('arg')] class Macro(Definition): def export_aspects(self, src): src.__class__ = self.__class__ src.tgtnode = self.tgtnode def use(self, options): return self.mod.SpecNodes.node_of_taci( 'block', '', self.tgtnode.children, self.tgtnode.index) class Self(Description): d_max_occur = 1 class Mapping(Description): d_type = 'other' d_sub = ('alt', 'arg', 'args', 'comment', 'description', 'description_with_header', 'equation', 'draw', 'key_arg', 'optionals', 'precondition', 'postcondition', 'repeat', 'returns', 'self', 'seq', ) def chk_num_args(self, min, max): re = self.get_args_re({}) xs = re.sequni() for x in xs: try: if min is not None and min == max and len(x) != min: self.error( '%s requires %d argument%s specified, got %d.' % ( self.d_tag, min, 's'[min == 1:], len(x)), self.src.node) elif min is not None and len(x) < min: self.error( '%s requires at least %d argument%s specified, got %d.' % ( self.d_tag, min, 's'[min == 1:], len(x)), self.src.node) elif max is not None and len(x) > min: self.error( '%s can take at most %d argument%s specified, got %d.' % ( self.d_tag, max, 's'[max == 1:], len(x)), self.src.node) except ReportedError: pass def get_arg_kinds(self): ak = [] for a in self.find_aspects('args'): ak.extend(list(a.args)) return ak def get_args_examples(self, mapname, top_kind): # Get arguments example, esp. for test purposes try: opt = {'get_examples': True} re = self.get_args_re(opt) coverage = 1 try: xs = re.sequni() except self.mod.RE.InfiniteError: print('Infinitely long args example for %s' % self.srcfullname) print( 'Limiting by expanding each Cleene closure 0 up to %d times.' % coverage) re = re.limited(coverage) xs = re.sequni() examples = [ArgsExample(self, tuple( x), mapname, top_kind) for x in xs] except CoverageError: return [] else: return examples def get_args_for_args(self, args, match): arglist = [] for a in self.find_arg_aspects(): t = a.d_tag if t == 'arg': name = a.get_name() if name in match: v = args.get_arg_value(match[name]) else: ex = a.get_examples() if not ex: # I have been able to cause this to happen in test67. self.error( 'Test coverage error: Can not create precondition for %r\n -- no examples specified for the argument above.' % args.mapping.tgtfullname, a.src.node ) v = ex[0] arglist.append(v) else: assert 0 # raise ConditionError, 'Can not match this precondition' return ArgsExample(self, tuple(arglist), args.mapname, args.top_kind) def get_args_re(self, opt): re = self.mod.RE.Epsilon for a in self.find_arg_aspects(): re += a.get_re(opt) return re def get_arguments(self): # Get the arguments subjects, for doc description purposes return self.find_arg_aspects() def get_return_kind(self): return self.make_and_kind([x.get_kind() for x in self.find_aspects('returns')]) def get_return_test_kind(self): return self.make_and_test_kind([x.get_test_kind() for x in self.find_aspects('returns')]) class ArgsExample: def __init__(self, mapping, egs, mapname, top_kind): self.mapping = mapping self.egs = egs self.mapname = mapname self.top_kind = top_kind self.negs = [mapname(x) for x in egs] def __str__(self): return ', '.join(self.negs) def get_arg_value(self, name): i = 0 for a in self.mapping.find_arg_aspects(): t = a.d_tag if t == 'arg': if a.get_name() == name: return self.egs[i] else: raise ConditionError('No argument matches: %r' % name) i += 1 def get_preconditions(self): return self.mapping.find_aspects('precondition') def get_postconditions(self): return self.mapping.find_aspects('postcondition') def get_setups_for_preconditions(self): pres = self.get_preconditions() if not pres: return [] kind = self.top_kind map = self.mapping pres = map.find_aspects('precondition') if pres: for a in kind.find_aspects('attribute'): for m in a.find_aspects('mapping'): mpre = m.find_aspects('precondition') if mpre: continue match = self.match_to(m.find_aspects('postcondition')) if match is not None: # found one args = m.get_args_for_args(self, match) return [SetUp(a.get_attr_name(), args)] break else: continue break else: # Caller will do error reporting return None return [] def match_to_kind(self, kind): pass def match_to(self, posts): match = {} for pre in self.get_preconditions(): for pos in posts: if pos.cond_id == pre.cond_id: if len(pos.arg_names) != len(pre.arg_names): continue upd = {} for a, b in zip(pos.arg_names, pre.arg_names): if a in match: break upd[a] = b else: match.update(upd) break else: return None assert ',' not in match return match class SetUp: def __init__(self, name, args): self.name = name self.args = args def get_name(self): return self.name def get_args(self): return self.args class Operator(Mapping): d_is_def = 1 d_type = 'operator' d_sub = ('arg', 'comment', 'description', 'description_with_header', 'equation', 'postcondition', 'precondition', 'self', 'returns', ) def get_op_name(self): return self.src.node.arg.strip() def resolve_special(self): self.chk_num_args(1, 1) class ReverseOperator(Operator): pass class FunctionOperator(Operator): def resolve_special(self): self.chk_num_args(0, 0) class InplaceOperator(Operator): pass class SetItem(Mapping): d_type = 'other' d_sub = ('arg', 'comment', 'description', 'description_with_header', 'equation', 'postcondition', 'precondition', 'self') def get_op_name(self): return '[]' def resolve_special(self): self.chk_num_args(2, None) class DelItem(SetItem): def resolve_special(self): self.chk_num_args(1, None) class GetItem(SetItem): d_sub = SetItem.d_sub + ('returns', ) def resolve_special(self): self.chk_num_args(1, None) class Condition(Description): d_is_def = 1 d_sub = ('self', 'arg', 'comment', 'description', 'python_code') def get_arg_names(self): an = [] for a in self.find_aspects('*'): if a.d_tag in ('self', 'arg'): an.append(a.src.node.arg.strip()) return an def get_def_name(self): dn = self.src.lastname return dn def_name = property(get_def_name) class PythonCode(Description): d_sub = ('comment', 'description', 'in_context') class ConditionRef(Description): d_sub = ('comment', 'description',) def __repr__(self): try: return self.cond_expr except AttributeError: return Description.__repr__(self) def get_cond_id(self): cond_id = self.cond_definition.tgtfullname if self.is_not: cond_id = 'not ' + cond_id self.cond_id = cond_id return cond_id cond_id = property_nondata(get_cond_id) def get_definition(self): return self.cond_definition def resolve_special(self): cond_def = self.src.cond_definition self.cond_definition = self.env.get_descr_by_subject(cond_def) self.cond_doc_name = cond_def.parent.lastname + '.' + cond_def.lastname self.cond_expr = self.src.node.arg.strip() # Mostly for information self.arg_names = self.src.arg_names self.is_not = self.src.is_not class Precondition(ConditionRef): #doc_name = 'Before' doc_name = 'Precondition' class Postcondition(ConditionRef): #doc_name = 'After' doc_name = 'Postcondition' class PostcondCase: # Postcondition with specific variables def __init__(postcond, variables): self.postcond = postcond self.variables = variables class Constructor(Description): d_type = 'with_args' d_sub = ('comment', 'description',) class Equation(Description): d_sub = ('comment', 'description', 'precondition', 'postcondition') class Args(Description): d_type = 'with_args' d_sub = ('comment', 'description', 'optionals', ) def get_re(self, opt): re = self.mod.RE.Epsilon for a in self.find_arg_aspects(): re += a.get_re(opt) return re class NoArg(Description): def get_re(self, opt): return self.mod.RE.Epsilon class Arg(Description): d_sub = ('comment', 'default', 'description', 'superkind_of', 'name', ) def get_kind(self): return self.make_or_kind(self.find_kind_aspects()) def get_name(self): try: return self.get_arg_name() except AttributeError: return '?' def get_arg_name(self): return self.src.specified_name def get_examples(self, get_all=False): examples = [] exs = self.find_aspects('example') for ex in exs: examples.extend(ex.get_examples()) if not exs or get_all: k = self.get_kind() examples.extend(k.get_examples()) return examples class KeyArgEG: def __init__(self, name, eg): self.name = name self.eg = eg def get_ex_text(self): return self.eg.get_ex_text() def get_ctx_text(self): return self.eg.get_ctx_text() def get_use_text(self, x): return '%s=%s' % (self.name, x) class KeyArg(Arg): # Spec with keyarg means it is: # NOT to be used as positional argument # ONLY as keyword argument def get_examples(self, get_all=False): name = self.get_arg_name() return [KeyArgEG(name, eg) for eg in Arg.get_examples(self, get_all)] class Draw(Description): d_sub = ('comment', 'description', 'key_arg', 'seq', ) def get_re(self, opt): re = self.mod.RE.Epsilon for a in self.find_arg_aspects(): re += a.get_re(opt)('?') return re class Optionals(Description): d_sub = ('arg', 'args', 'key_arg', 'comment', 'seq', ) d_type = 'with_args' def get_re(self, opt): def opt_ra(aspects): if not aspects: return self.mod.RE.Epsilon return (aspects[0].get_re(opt) + opt_ra(aspects[1:]))('?') return opt_ra(self.find_arg_aspects()) class Repeat(Description): d_sub = ('alt', 'arg', 'args', 'comment', 'description') def get_arg(self): return self.src.node.arg.strip() def get_re(self, opt): asp = self.find_arg_aspects() if not asp: self.error('No argument aspects.', self.src.node) re = asp[0].get_re(opt) for a in asp[1:]: re += a.get_re(opt) arg = self.get_arg() sep = '..' if sep in arg: args = arg.split(sep) if len(args) != 2: self.error('More than one %r in argument.' % sep, self.src.node) lo, hi = [x.strip() for x in args] try: lo = int(lo) except ValueError: self.error('Expected int in lower bound.', self.src.node) if hi != '*': try: hi = int(hi) except ValueError: self.error('Expected int or * in upper bound.', self.src.node) else: try: lo = int(arg) except ValueError: self.error( 'Expected int, int..int or int..* in argument.', self.src.node) hi = lo if lo < 0 or (hi != '*' and hi < 0): self.error('Expected non-negative repetition count.', self.src.node) if hi == '*': res = re('*') for i in range(lo): res = re + res else: if hi < lo: self.error('Expected upper bound >= lower bound.', self.src.node) a = self.mod.RE.Epsilon for i in range(lo): a += re b = self.mod.RE.Epsilon for i in range(lo, hi): b = (re + b)('?') res = a + b return res class Seq(Description): d_sub = ('arg', 'comment', 'description', 'optionals',) d_sub += ('key_arg', ) # May perhaps be optionally disabled d_type = 'with_args' def get_re(self, opt): re = self.mod.RE.Epsilon for a in self.find_arg_aspects(): re += a.get_re(opt) return re class Alt(Description): d_sub = ('arg', 'comment', 'descripton', 'key_arg', 'no_arg', 'seq', ) d_type = 'with_args' def get_re(self, opt): asp = self.find_arg_aspects() if not asp: self.error('No alternatives.', self.src.node) re = asp[0].get_re(opt) for a in asp[1:]: re |= a.get_re(opt) return re class Returns(Description): d_sub = ('attribute', 'comment', 'description', 'description_with_header', 'either', 'mapping', 'method') d_type = 'with_opt_args' def get_kind(self): return self.make_and_kind(self.find_kind_aspects()) def get_test_kind(self): return self.make_and_test_kind(self.find_kind_aspects()) # help functions def find_aspects_inseq(seq, tag): as_ = [] for o in seq: as_.extend(o.find_aspects(tag)) return as_ # Beam base class class Beam: def __init__(self, k_tag, *objects): self.src = objects[0] self.tgt = objects[-1] self.k_tag = k_tag self.objects = objects def __add__(self, other): return compose(self, other) class KindBeam(Beam): pass class AtomKindBeam(Beam): pass class KindMappingBeam(Beam): pass class KindOpBeam(Beam): op_index = 1 op_name_index = 1 def find_equations(self): return find_aspects_inseq(self.get_op_seq(), 'equation') def find_postconditions(self): return find_aspects_inseq(self.get_op_seq(), 'postcondition') def find_preconditions(self): return find_aspects_inseq(self.get_op_seq(), 'precondition') def get_args_examples(self, mapname): top_kind = self.objects[0] return self.get_the_op().get_args_examples(mapname, top_kind) def get_op_id_name(self): return self.objects[self.op_name_index].get_id_name() def get_op_name(self): return self.objects[self.op_name_index].get_op_name() def get_op_seq(self): return self.objects[self.op_index:] def get_self_name(self): return self.get_the_op().get_self_name() def get_the_op(self): return self.objects[self.op_index] def get_return_test_kind(self): return self.get_the_op().get_return_test_kind() class KindAttributeBeam(KindOpBeam): def get_the_op(self): assert 0 class KindAttributeMappingBeam(KindOpBeam): op_index = 2 class KindMappingBeam(KindOpBeam): def get_op_name(self): return '()' class KOKOpBeam(KindOpBeam): op_index = 2 op_name_index = 2 def subkind_of_kind(*objects): return beam(*objects[2:]) def compose(a, b): if a.tgt is not b.src: raise "Composition error, tgt %r is not src %r" % (a.tgt, b.src) objects = a.objects + b.objects[1:] return beam(*objects) def remove_1_2(k_tag, *objects): return beam(objects[0], *objects[3:]) def remove_0(k_tag, *objects): return beam(*objects[1:]) beam_table = { ('attribute', 'attribute'): Beam, ('attribute', 'either'): Beam, ('attribute', 'kind_of'): Beam, ('attribute', 'kind_of', 'kind', 'attribute'): Beam, ('attribute', 'kind_of', 'kind', 'function_operator'): Beam, ('attribute', 'kind_of', 'kind', 'inplace_operator'): Beam, ('attribute', 'kind_of', 'kind', 'mapping'): Beam, ('attribute', 'kind_of', 'kind', 'operator'): Beam, ('attribute', 'kind_of', 'kind', 'reverse_operator'): Beam, ('attribute', 'kind_of', 'kind', 'delitem'): Beam, ('attribute', 'kind_of', 'kind', 'getitem'): Beam, ('attribute', 'kind_of', 'kind', 'setitem'): Beam, ('attribute', 'mapping'): Beam, ('either', ): Beam, ('either', 'kind'): Beam, ('either', 'kind', 'attribute'): Beam, ('kind', 'attribute'): Beam, ('kind', 'attribute', 'kind_of', 'kind', 'mapping'): KindAttributeBeam, ('kind', 'attribute', 'mapping'): KindAttributeMappingBeam, ('kind', 'either'): Beam, ('kind', 'function_operator'): KindOpBeam, ('kind', 'delitem'): KindOpBeam, ('kind', 'getitem'): KindOpBeam, ('kind', 'inplace_operator'): KindOpBeam, ('kind', 'kind_of'): Beam, ('kind', 'kind_of', 'kind', 'attribute'): Beam, ('kind', 'mapping'): KindMappingBeam, ('kind', 'operator'): KindOpBeam, ('kind', 'reverse_operator'): KindOpBeam, ('kind', 'setitem'): KindOpBeam, ('kind', 'subkind_of'): Beam, ('kind', 'subkind_of', 'kind', 'attribute'): remove_1_2, ('kind', 'subkind_of', 'kind', 'function_operator'): remove_1_2, ('kind', 'subkind_of', 'kind', 'delitem'): remove_1_2, ('kind', 'subkind_of', 'kind', 'getitem'): remove_1_2, ('kind', 'subkind_of', 'kind', 'inplace_operator'): remove_1_2, ('kind', 'subkind_of', 'kind', 'mapping'): remove_1_2, ('kind', 'subkind_of', 'kind', 'operator'): remove_1_2, ('kind', 'subkind_of', 'kind', 'reverse_operator'): remove_1_2, ('kind', 'subkind_of', 'kind', 'setitem'): remove_1_2, ('kind_of', 'kind'): Beam, ('kind_of', 'kind', 'attribute'): Beam, ('kind_of', 'kind', 'function_operator'): KOKOpBeam, ('kind_of', 'kind', 'delitem'): KOKOpBeam, ('kind_of', 'kind', 'getitem'): KOKOpBeam, ('kind_of', 'kind', 'inplace_operator'): KOKOpBeam, ('kind_of', 'kind', 'operator'): KOKOpBeam, ('kind_of', 'kind', 'reverse_operator'): KOKOpBeam, ('kind_of', 'kind', 'setitem'): KOKOpBeam, ('kind_of', 'kind', 'mapping'): Beam, ('subkind_of', 'kind'): Beam, ('subkind_of', 'kind', 'attribute'): Beam, ('subkind_of', 'kind', 'function_operator'): Beam, ('subkind_of', 'kind', 'delitem'): Beam, ('subkind_of', 'kind', 'getitem'): Beam, ('subkind_of', 'kind', 'inplace_operator'): Beam, ('subkind_of', 'kind', 'mapping'): Beam, ('subkind_of', 'kind', 'operator'): Beam, ('subkind_of', 'kind', 'reverse_operator'): Beam, ('subkind_of', 'kind', 'setitem'): Beam, } def beam(*objects): k_tag = tuple([x.d_tag for x in objects]) C = beam_table[k_tag] return C(k_tag, *objects) class ProductSubject: def __init__(self, subjects): self.subjects = subjects self.fullname = '(%s)' % '*'.join([x.fullname for x in subjects]) class Subject: args = () specified_name = None def __init__(self, parent, node, lastname): self.parent = parent self.pac = parent.pac self.mod = self.pac.mod self.node = node self.filename = self.pac.filename self.lastname = lastname self.aspects = [] self.subjects = {} self.node_index = 0 self.tag = node.tag self.description_class = self.mod.get_description_class(node.tag) self.aspect_mode = None if self.parent is not self: self.fullname = self.parent.make_child_name(self.lastname) else: self.fullname = self.lastname def _visit_type_definition(self, node): names = self.get_arglist(node, min=1) for name in names: self.add_new_subject(node, name) def _visit_type_operator(self, node): shtag = self.mod.SpecNodes.reverse_node_aliases[node.tag] names = self.get_arglist(node, min=1) for name in names: name = '%s:%s' % (shtag, name) self.add_new_subject(node, name) def _visit_type_other(self, node): self.add_new_subject(node) def _visit_type_with_args(self, node): names = self.get_arglist(node) args = [self.find_subject(name, node) for name in names] subject = self.add_new_subject(node) if args: subject.args = args def _visit_type_with_opt_args(self, node): names = self.get_arglist(node, min=0) args = [self.find_subject(name, node) for name in names] subject = self.add_new_subject(node) if args: subject.args = args def add_new_subject(self, node, lastname=None): subject = self.new_subject(node, lastname) self.add_subject(subject) return subject def add_subject(self, subject): self.def_subject(subject) subject.add_top_node() return subject def add_top_node(self): node = self.node self._visit_children(node) def def_new_subject(self, node, lastname=None): subject = self.new_subject(node, lastname) self.def_subject(subject) return subject def def_subject(self, subject): if subject.description_class.d_is_def: name = subject.lastname if name in self.subjects: self.error('Redefinition of %r.' % name, subject.node, more=[( 'Previous definition of %r.' % name, self.subjects[name].node)] ) return # For clarity; there's most certainly an exception subject.definame = name self.subjects[name] = subject else: subject.definame = None self.aspects.append(subject) def error(self, msg, node=None, exception=ReportedError, **kwds): return self.pac.error(msg, node, exception, **kwds) def find_subject(self, name, node): return self.pac.find_subject(name, node, self) def get_arglist(self, node, min=0): arglist = node.get_arglist() for arg in node.get_arglist(): if not arg: if node.arg.strip().startswith(',') or node.arg.strip().endswith(','): m = 'Arg list to definition can not start or end with a comma.' else: m = 'Missing argument to definition.' self.error(m, node, exception=None) arglist = [x for x in arglist if x] break if len(arglist) < min: self.error( 'Not enough arguments, minimum %d expected to node %s' % ( min, node), node) return arglist def get_arglist_only(self, node, min=0): al = self.get_arglist(node, min) self.no_children(node) return al def get_line(self, index): try: with open(self.filename) as f: text = list(f.readlines())[index].rstrip() except Exception: text = None return text def _visit_aspect(self, node, mode): if self.aspect_mode is None: self.aspect_mode = mode else: if self.aspect_mode != mode: self.error('Inconsistent aspect mode: %r, was: %r' % (mode, self.aspect_mode), node) self._visit_children(node) def _visit_children(self, node): for ch in node.children: try: if ch.tag not in self.description_class.d_sub: self.error('Invalid tag: %r in: %r. Allowed = %s' % ( ch.tag, self.tag, self.description_class.d_sub), node) if self.mod.cover_check is not None: self.mod.cover_check.setdefault(self.tag, {})[ch.tag] = 1 ch.accept(self) except ReportedError: pass self.node_index += 1 def make_child_name(self, child_lastname): return '%s.%s' % (self.fullname, child_lastname) def new_subject(self, node, name=None): is_def = self.mod.get_description_class(node.tag).d_is_def assert is_def == (name is not None) if name is None: name = '<%d>' % self.node_index tag = node.tag if tag == 'macro': return MacroSubject(self, node, name) elif tag == 'document': return DocumentSubject(self, node, name) else: return Subject(self, node, name) def new_tag_node(self, tag, node): return self.mod.SpecNodes.node_of_taci(tag, '', node.children, node.index) def no_children(self, node): if node.children: self.error('No children expected for node with tag %r' % node.tag, node, exception=None) def visit_and(self, node): for name in self.get_arglist(node, min=1): ofsubject = self.find_subject(name, node) ofsubject._visit_aspect(node, 'and') def visit_aspects_of(self, node): for name in self.get_arglist(node, min=1): ofsubject = self.find_subject(name, node) ofsubject._visit_aspect(node, 'aspect') def visit_arg(self, node, must_have_name=False): arg = node.arg.strip() arg_name = None kind = None if arg: if ':' in arg: nk = arg.split(':') if len(nk) > 2: self.error('More than 1 colon in argument.', node) name, kind_name = [x.strip() for x in nk] if kind_name: kind = self.find_subject(kind_name, node) if name: arg_name = name else: # Is there an obvious default ? # For KeyArg, yes, the name is always. # let's say it's the name arg_name = arg subject = self.new_subject(node) if arg_name: subject.specified_name = arg_name self.add_subject(subject) if must_have_name and subject.specified_name is None: self.error('No argument name specified.', node) if kind is not None: subject.args = [kind] def visit_comment(self, node): pass def visit_condition(self, node): names = self.get_arglist(node, min=1) for name in names: self.add_new_subject(node, 'cond:%s' % name) def visit_default(self, node): description_class = self.mod.get_description_class(node.tag) arg = node.arg.strip() colon = arg.startswith(':') if (description_class.d_type == 'definition') != colon: if colon: msg = 'Tag %r is not a definition, should not have ::' % node.tag else: msg = 'Tag %r is a definition, requires ::' % node.tag self.error(msg, node, exception=None) getattr(self, '_visit_type_%s' % description_class.d_type)(node) def visit_description(self, node): self.def_new_subject(node) def visit_description_with_header(self, node): self.visit_description(node) def visit_example(self, node): subject = self.add_new_subject(node) partab = subject.description_class.partab ex = node.arg.strip() if '\n' in ex: if not (partab.get(ex[:1]) == ex[-1:] or partab.get(ex[:3]) == ex[-3:]): self.error('Multi-line expression should be in parentheses (for clarity).', node, exception=None, harmless=1) ex = '(%s)' % ex subject.ex_text = ex def visit_import(self, node): my_names = self.get_arglist(node, min=1) resolve_mode = None usings = None froms = [] for ch in node.children: t = ch.tag if t == 'from': for name in self.get_arglist_only(ch): froms.append((name, ch)) elif t == 'resolve_by': if resolve_mode: self.error("More than 1 'resolve' clause.", ch.node, exception=None) else: resolve_mode = ch.arg.strip() if not resolve_mode in ('and', 'or'): self.error("Resolve by: and / or expected.", ch, exception=None) resolve_mode = 'and' elif t == 'using': if usings is None: usings = [] for name in self.get_arglist_only(ch): usings.append((name, ch)) else: self.error('Unexpected clause in import', ch, exception=None) using_map = {} if usings is not None: if len(usings) != len(my_names): if len(using_names) < len(my_names): manyfew = 'few' else: manyfew = 'many' self.error( "Too %s 'using' names, should match number of names in .import" % manyfew, using_node, exception=None) for m, u in zip(my_names, usings): # zip stops at the shortest list, ok using_map[m] = u if len(froms) == 0: self.error("No 'from' clause", node) if len(froms) > 1: if not resolve_mode: self.error("Importing from multiple packages but no 'resolve by' clause", node, exception=None) resolve_mode = 'and' for name in my_names: subject = self.def_new_subject(node, name) subject.imp_resolve_mode = resolve_mode subject.imp_using_map = using_map subject.imp_froms = froms def visit_key_arg(self, node): self.visit_arg(node, must_have_name=True) def visit_method(self, node): arg = node.arg.strip() if not arg.startswith(':'): self.error("Tag 'method' is a definition, requires ::", node) self.mod.node_of_taci('attribute', arg, (self.mod.node_of_taci('mapping', '', node.children),)).accept(self) def visit_name(self, node): if self.specified_name is not None: self.error('Duplicate name specification.', node) name = node.arg.strip() if not name: self.error('No name specification.', node) self.specified_name = name def visit_or(self, node): for name in self.get_arglist(node, min=1): ofsubject = self.find_subject(name, node) ofsubject._visit_aspect(node, 'or') def visit_postcondition(self, node): arg = node.arg.strip() if not '(' in arg: self.error('No left parenthesis', node) lpar = arg.index('(') rpar = arg.find(')') if rpar < lpar: self.error('None or misplaced right parenthesis', node) n = arg[lpar+1:rpar].strip() if ',' in n: n = [x.strip() for x in n.split(',')] else: n = [n] arg_names = n cond_name = arg[:lpar].strip() if not cond_name: self.error('No condition name', node) is_not = 0 if cond_name.startswith('not '): cond_name = cond_name[4:].strip() is_not = 1 parts = cond_name.split('.') if not parts[-1].startswith('cond:'): parts[-1] = 'cond:'+parts[-1] cond_name = '.'.join(parts) cond_def = self.find_subject(cond_name, node) subject = self.add_new_subject(node) subject.cond_definition = cond_def subject.cond_name = cond_name subject.arg_names = arg_names subject.is_not = is_not def visit_precondition(self, node): self.visit_postcondition(node) class ErrorSubject(Subject): pass class PackageSubject(Subject): def __init__(self, mod, specenv, node, name, filename): self.mod = mod self.specenv = specenv self.pac = self self.filename = filename #name = 'package_%s'%(name,) name = '%s' % (name,) Subject.__init__(self, self, node, name) self.lastname = name.split('.')[-1] self.tag = 'package' self.description_class = Package self.documents = [] for s in mod.predefined_subjects: s = s(self) self.subjects[s.fullname] = s self._visit_children(node) del self.specenv # It was used only for error report def error(self, msg, node=None, exception=ReportedError, **kwds): return self.specenv.error(msg, node, exception, **kwds) def find_subject(self, name, node, context=None): if not name: self.error('Invalid subject name: %r' % name, node) parts = [x.strip() for x in name.split('.')] if not parts[0]: tag = parts[1] parts = parts[2:] else: tag = 'myfile' if tag == 'myfile': s = self elif tag == 'mykind': s = context if s is not None: kind_tags = ('kind', 'and', 'import') while s.parent != self and s.tag not in kind_tags: s = s.parent if s.tag not in kind_tags: s = None if s is None: self.error('mykind tag without such a context: %r' % name, node) else: self.error('Invalid tag %r in %r' % (tag, name), node) sname = s.lastname for i, n in enumerate(parts): ns = s.subjects.get(n) if ns is None: if s.tag != 'import': self.error('No such subject: %r in %r.' % (n, sname), node) return SubImportSubject(s, node, parts[i:]) sname = sname + '.' + n s = ns return s class SubImportSubject: def __init__(self, parent, node, rnparts): self.parent = parent self.node = node self.rnparts = rnparts self.fullname = '.'.join([parent.fullname]+rnparts) self.lastname = rnparts[-1] class MacroSubject(Subject): def add_top_node(self): pass class DocumentSubject(Subject): def add_top_node(self): self.parent.documents.append(self) class GuppyWorld(Subject): def __init__(self, env): self.pac = env self.fullname = self.lastname = "Guppy_World" self.node = None self.tag = '<GuppyWorld>' self.aspects = [] self.description_class = Description class _GLUECLAMP_: _imports_ = ( '_parent:Document', '_parent:FileIO', '_parent.FileIO:IO', '_parent:Filer', '_parent:Html', '_parent:Latex', '_parent:SpecNodes', '_parent.SpecNodes:node_of_taci', '_parent:Tester', '_root.hashlib:md5', '_root.guppy.etc:iterpermute', '_root.guppy.etc:RE', ) _chgable_ = ('cover_check', 'io_dir', 'max_errors') description_classes = { 'alt': Alt, 'arg': Arg, 'args': Args, 'attribute': Attribute, 'comment': Comment, 'condition': Condition, 'constructor': Constructor, 'default': Default, 'defines': Defines, 'delitem': DelItem, 'description': DescriptionDescription, 'description_with_header': DescriptionWithHeader, 'equation': Equation, 'example': Example, 'either': Either, 'draw': Draw, 'function_operator': FunctionOperator, 'getitem': GetItem, 'import': Import, 'in_context': InContext, 'inplace_operator': InplaceOperator, 'key_arg': KeyArg, 'kind': Kind, 'kind_of': KindOf, 'macro': Macro, 'mapping': Mapping, 'no_arg': NoArg, 'operator': Operator, 'postcondition': Postcondition, 'precondition': Precondition, 'python_code': PythonCode, 'reverse_operator': ReverseOperator, 'optionals': Optionals, 'package': Package, 'repeat': Repeat, 'returns': Returns, 'self': Self, 'seq': Seq, 'setitem': SetItem, 'subkind_of': SubkindOf, 'superkind': Superkind, 'superkind_of': SuperkindOf, } tgt_prefix = '.tgt.' cover_check = None io_dir = None max_errors = 10 def get_description_class(self, tag): return self.description_classes.get(tag, Description) def _get_predefined_subjects(self): return (GuppyWorld,) def _get_package_cache(self): return {} def main(self, filename, **kwds): se = SpecEnv(self) se.process_main(filename, **kwds) def _test_main_(self): pass def set_input_dir(self, dir): dir = self.IO.path.abspath(dir) self.input_dir = dir
Upload File
Create Folder