diff --git a/lib/aslint/fortran/free/fortran_code.py b/lib/aslint/fortran/free/fortran_code.py index a4b573bdb4e07497fdd748988352f356f7a99d98..29437ed968bb6799ac673b55b8be6b191cc869af 100644 --- a/lib/aslint/fortran/free/fortran_code.py +++ b/lib/aslint/fortran/free/fortran_code.py @@ -20,14 +20,13 @@ from aslint.decorators import interrupt_decorator import aslint.fortran.free.code_func as CF import aslint.fortran.free.regexp as RX -_EMPTY_LINE = '_EMPTY_LINE_' -INDENT = ' ' * 4 +_EMPTY_LINE = "_EMPTY_LINE_" +INDENT = " " * 4 MAXLENGTH = 98 MINLENGTH = 12 class FortranParserError(Exception): - """Exception during parsing a fortran source code""" def __init__(self, msg, child_exc): @@ -38,25 +37,25 @@ class FortranParserError(Exception): def __str__(self): """To string""" - return ' '.join([self.msg, ':', str(self.child)]) + return " ".join([self.msg, ":", str(self.child)]) def report_decorator(func): """Decorator to locate the error""" + @wraps(func) def wrapper(inst, *args, **kwds): """Wrapper around a method of Block""" try: return func(inst, *args, **kwds) except Exception as exc: - msg = "in '%s.%s()' at line %d" % (inst.__class__.__name__, - func.__name__, inst.lnum) + msg = "in '%s.%s()' at line %d" % (inst.__class__.__name__, func.__name__, inst.lnum) raise FortranParserError(msg, exc) + return wrapper class Block(object): - """A block of fortran code. The method 'parse' is automatically called after the code is registered. Attributes: @@ -68,12 +67,13 @@ class Block(object): - code: formatted text of the code - attr: specific attributes of the statement. """ + regexp = None expr = None end_block = None - _rx_eol = re.compile('& *$') - _rm_end = partial(re.compile('& *$', re.M).sub, '') - _rm_beg = partial(re.compile('^ *&?', re.M).sub, '') + _rx_eol = re.compile("& *$") + _rm_end = partial(re.compile("& *$", re.M).sub, "") + _rm_beg = partial(re.compile("^ *&?", re.M).sub, "") def __init__(self, lnum, level, opts=None): """Initialization""" @@ -123,9 +123,8 @@ class Block(object): def set_options(self, opts): """Set and check the options""" self.opts = opts or {} - self.opts['maxlength'] = self.opts.get('maxlength', MAXLENGTH) - assert self.opts['maxlength'] > 8, '%s: maxlength=%d' \ - % (self, self.opts['maxlength']) + self.opts["maxlength"] = self.opts.get("maxlength", MAXLENGTH) + assert self.opts["maxlength"] > 8, "%s: maxlength=%d" % (self, self.opts["maxlength"]) def copy(self): """Return a copy of the Block object.""" @@ -164,9 +163,9 @@ class Block(object): def lines2text(self): """Make a text from the read lines to make the parser work easier.""" lines = CF.apply_on_lines(CF.remove_continuation, self.lines) - frepl = partial(CF.replace_extra, char=' ') + frepl = partial(CF.replace_extra, char=" ") lines = CF.apply_on_lines(frepl, lines) - self.code = ''.join(lines) + self.code = "".join(lines) def loop_on_lines(self, lines): """Create the list of blocks. @@ -193,16 +192,17 @@ class Block(object): # fill inside up to next "End of block" instance next_level = self.level + 1 while not self.is_closed() and len(lines) > 0: - blck = statement_factory(lines[0], lnum, next_level, - self.opts, self.attr) + blck = statement_factory(lines[0], lnum, next_level, self.opts, self.attr) self.blocks.append(blck) lnum, sub_clst = blck.loop_on_lines(lines) if self.end_block: # does blck (or another sub-close stmt) ends this block may_close = [blck] + sub_clst for mcl in may_close: - close_this = isinstance(mcl, self.end_block) and \ - mcl.search(mcl.code, self.attr) is not None + close_this = ( + isinstance(mcl, self.end_block) + and mcl.search(mcl.code, self.attr) is not None + ) self._closed = self._closed or close_this if isinstance(mcl, MultipleCloseStatement): close_st.append(mcl) @@ -230,11 +230,11 @@ class Block(object): def _init_lines(self, start, indent): """init lines""" lines = [] - length = self.opts['maxlength'] - len(start) + length = self.opts["maxlength"] - len(start) if length < MINLENGTH: - lines.append(start + '&') + lines.append(start + "&") start = indent = self.indent() - length = self.opts['maxlength'] - len(start) + length = self.opts["maxlength"] - len(start) return lines, start, indent, length def _dbg(self): @@ -242,8 +242,7 @@ class Block(object): if not self.code: return _EMPTY_LINE klname = self.__class__.__name__ - return '%04d:%d:%-8s: %s\n %s' % ( - self.lnum, self.level, klname, self.code, self.attr) + return "%04d:%d:%-8s: %s\n %s" % (self.lnum, self.level, klname, self.code, self.attr) def indent(self): """Return the indentation of the block/statement""" @@ -258,7 +257,7 @@ class Block(object): try: self._parse() except: - logger.error('parse failed: %s', self._dbg()) + logger.error("parse failed: %s", self._dbg()) raise self._parsed = True for blck in self: @@ -289,12 +288,11 @@ class Block(object): def write_code(self, fname): """Write the code into 'fname'""" - with open(fname, 'w') as fobj: + with open(fname, "w") as fobj: fobj.write(self.code_text()) class Statement(Block): - """A statement: some code and the line number in the parent source code""" def loop_on_lines(self, lines): @@ -314,8 +312,7 @@ class Statement(Block): def is_closed(self): """Return True if the end of the statement is reached.""" - self._closed = len(self.lines) > 0 and \ - self._rx_eol.search(self.lines[-1]) is None + self._closed = len(self.lines) > 0 and self._rx_eol.search(self.lines[-1]) is None return self._closed def _code_text(self): @@ -324,7 +321,6 @@ class Statement(Block): class NoIndentStatement(Statement): - """Not indented statement""" def _code_text(self): @@ -333,7 +329,6 @@ class NoIndentStatement(Statement): class CloseStatement(Statement): - """A statement that ends a block of code.""" def indent(self): @@ -342,15 +337,14 @@ class CloseStatement(Statement): class MultipleCloseStatement(CloseStatement): - """Statement that must be signaled to the parent block because it may close it too.""" + # attributes class Attribute(object): - """Base class for attributes""" def __init__(self): @@ -360,27 +354,27 @@ class Attribute(object): class HasName(Attribute): - """For a named statement.""" def __get_attr(self): """Return the name""" - return self.attr['name'] + return self.attr["name"] + name = property(__get_attr) class HasArgs(Attribute): - """For a statement with arguments""" def _get_attr(self): """Return the name""" - return self.attr['arg'] + return self.attr["arg"] + args = property(_get_attr) def get_arg(self, arg): """The 'arg' as found in code or None""" - expr = re.compile('^%s($| *\()' % re.escape(arg)) + expr = re.compile("^%s($| *\()" % re.escape(arg)) for tst in self.args: if expr.search(tst) is not None: return tst @@ -396,43 +390,44 @@ class HasArgs(Attribute): class HasCondition(Attribute): - """For a statement with condition""" def _get_attr(self): """Return the condition""" - return self.attr['cond'] + return self.attr["cond"] + cond = property(_get_attr) class HasLabel(Attribute): - """For a statement with label""" def _get_attr(self): """Return the label""" - return self.attr['label'] + return self.attr["label"] + label = property(_get_attr) # TODO see the MRO to use _code_text def _label_in_indent(self, orig): """Insert the label into the first indentation""" indent = self.indent() - noindent = re.sub('^ *%s *' % self.label, '', orig) - indent = '%3s ' % self.label.strip() + indent.replace(INDENT, '', 1) + noindent = re.sub("^ *%s *" % self.label, "", orig) + indent = "%3s " % self.label.strip() + indent.replace(INDENT, "", 1) return indent + noindent def _clean_label(self): """Normalize the label""" - self.attr['label'] = re.sub('^0*', '', self.attr['label']) + self.attr["label"] = re.sub("^0*", "", self.attr["label"]) + # statements and blocks class EmptyLine(NoIndentStatement): - """An empty line""" - regexp = re.compile('^[!]? *$') + + regexp = re.compile("^[!]? *$") def _code_text(self): """Return a single comment""" @@ -440,9 +435,9 @@ class EmptyLine(NoIndentStatement): class Comment(NoIndentStatement): - """A comment""" - regexp = re.compile('^ *![^$]') + + regexp = re.compile("^ *![^$]") def is_closed(self): """Single line statement.""" @@ -454,74 +449,75 @@ class Comment(NoIndentStatement): class Preproc(NoIndentStatement): - """A preprocessor directive""" - regexp = re.compile('^#\W*') + regexp = re.compile("^#\W*") -class PreprocDefine(NoIndentStatement, HasName): +class PreprocDefine(NoIndentStatement, HasName): """A preprocessor directive""" - regexp = re.compile('^# *define *(?P<name>.*?)[\( ]*') + + regexp = re.compile("^# *define *(?P<name>.*?)[\( ]*") def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected #include: %r' % self.code + assert mat, "unexpected #include: %r" % self.code self.attr = mat.groupdict() class PreprocInclude(NoIndentStatement, HasName): - """A preprocessor directive""" - regexp = re.compile('^# *include *[\'"](?P<name>.*?)[\'"]') + + regexp = re.compile("^# *include *['\"](?P<name>.*?)['\"]") def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected #include: %r' % self.code + assert mat, "unexpected #include: %r" % self.code self.attr = mat.groupdict() + # ifdef/#endif is not a block else it would need store the no-indentation level # XXX instead of passing next_level to statement_factory, pass "next # attrs" from parent class PreprocEndIf(CloseStatement): - """End of a IfThen block""" - regexp = re.compile('^# *endif *$') + regexp = re.compile("^# *endif *$") -class PreprocElse(CloseStatement): +class PreprocElse(CloseStatement): """A else statement""" - regexp = re.compile('^# *else *$') + regexp = re.compile("^# *else *$") -class PreprocElseIf(CloseStatement): +class PreprocElseIf(CloseStatement): """A else if statement""" - regexp = re.compile('^# *(elseif|else if)\W*') + regexp = re.compile("^# *(elseif|else if)\W*") -class PreprocIfDef(NoIndentStatement, HasCondition): +class PreprocIfDef(NoIndentStatement, HasCondition): """A conditional block #if, #ifdef, #ifndef""" - regexp = re.compile('^# *(?:if|ifdef|ifndef) *(?P<cond>.*?) *$') + + regexp = re.compile("^# *(?:if|ifdef|ifndef) *(?P<cond>.*?) *$") end_block = PreprocEndIf def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected #ifdef: %r' % self.code + assert mat, "unexpected #ifdef: %r" % self.code self.attr = mat.groupdict() class Directive(Statement): - """A fortran directive (OpenMP)""" - regexp = re.compile('^ *!$') + + regexp = re.compile("^ *!$") def is_closed(self): """Must not be concatenated""" @@ -529,9 +525,9 @@ class Directive(Statement): class Untyped(Statement): - """Not yet supported statement""" - regexp = re.compile('.*') + + regexp = re.compile(".*") def lines2text(self): """Keep lines unchanged.""" @@ -539,73 +535,74 @@ class Untyped(Statement): class Implicit(Statement): - """An empty line""" - regexp = re.compile('^ *implicit ') + regexp = re.compile("^ *implicit ") -class Decl(Statement, HasArgs): +class Decl(Statement, HasArgs): """A declaration statement""" - regexp = re.compile('^ *(' - '(integer|logical|real|complex|character)\W' - '|[^\'"]*?::)', re.I) - _re1 = re.compile('^ *(?P<type>(%s)) *:: *(?P<arg>.*)$' % RX.DECLS) - _ret = re.compile('^ *(?P<type>(%s)) *:: *(?P<arg>.*)$' % RX.DECLS_TYPE) - _re2 = re.compile('^ *(?P<type>(%s)) +(?P<arg>.*?)$' % RX.DECLS) - _re3 = re.compile('^ *(?P<type>\w.*?) *:: *(?P<arg>.*)$') - _re4 = re.compile('^ *(?P<type>\w.*?) *(?P<arg>.*)$') + + regexp = re.compile("^ *(" "(integer|logical|real|complex|character)\W" "|[^'\"]*?::)", re.I) + _re1 = re.compile("^ *(?P<type>(%s)) *:: *(?P<arg>.*)$" % RX.DECLS) + _ret = re.compile("^ *(?P<type>(%s)) *:: *(?P<arg>.*)$" % RX.DECLS_TYPE) + _re2 = re.compile("^ *(?P<type>(%s)) +(?P<arg>.*?)$" % RX.DECLS) + _re3 = re.compile("^ *(?P<type>\w.*?) *:: *(?P<arg>.*)$") + _re4 = re.compile("^ *(?P<type>\w.*?) *(?P<arg>.*)$") def _parse(self): """Parse the code, store attributes...""" - mat = self._re1.search(self.code) or self._ret.search(self.code) or self._re2.search(self.code) \ - or self._re3.search(self.code) or self._re4.search(self.code) - assert mat, 'unexpected decl: %r' % self.code + mat = ( + self._re1.search(self.code) + or self._ret.search(self.code) + or self._re2.search(self.code) + or self._re3.search(self.code) + or self._re4.search(self.code) + ) + assert mat, "unexpected decl: %r" % self.code self.attr = mat.groupdict() try: # use RX.DECLS - decltype = re.sub( - 'type *\(', 'type(', self.attr['decltype'].strip()) - self.attr['type'] = decltype \ - + self.attr['declsize'].strip() - kind = (self.attr['declkind'] or '').strip() - self.attr['kind'] = kind.isdigit() and int(kind) or kind - self.attr['attr'] = self.attr['declattr'] or '' - self.attr['attr'] = CF.ArgSplitter(self.attr['attr']).strings() + decltype = re.sub("type *\(", "type(", self.attr["decltype"].strip()) + self.attr["type"] = decltype + self.attr["declsize"].strip() + kind = (self.attr["declkind"] or "").strip() + self.attr["kind"] = kind.isdigit() and int(kind) or kind + self.attr["attr"] = self.attr["declattr"] or "" + self.attr["attr"] = CF.ArgSplitter(self.attr["attr"]).strings() except KeyError: - self.attr['type'] = self.attr['type'].strip() - self.attr['kind'] = '' - self.attr['attr'] = [] - self.attr['arg'] = CF.ArgSplitter(self.attr['arg']).strings() + self.attr["type"] = self.attr["type"].strip() + self.attr["kind"] = "" + self.attr["attr"] = [] + self.attr["arg"] = CF.ArgSplitter(self.attr["arg"]).strings() vsiz = {} vini = {} - for i in self.attr['arg']: + for i in self.attr["arg"]: ini = None - for assign in ('=>', '='): + for assign in ("=>", "="): spl = i.split(assign) if len(spl) == 2: i, ini = spl[0], spl[1].strip() break spl = CF.ParSplitter(i).strings() if len(spl) == 3: - nam = spl[0].split('(')[0].strip() + nam = spl[0].split("(")[0].strip() sub = CF.ArgSplitter(spl[1]).strings() else: nam, sub = i.strip(), [] vsiz[nam] = sub vini[nam] = ini - self.attr['varsize'] = vsiz - self.attr['init'] = vini - self.attr['names'] = list(vsiz.keys()) + self.attr["varsize"] = vsiz + self.attr["init"] = vini + self.attr["names"] = list(vsiz.keys()) def _code_text(self): """Split long decls""" if len(self.args) == 0: return _EMPTY_LINE - typ = [self.attr['type'].strip()] - if self.attr['attr']: - typ.extend(self.attr['attr']) - start = self.indent() + ', '.join(typ) + ' :: ' + typ = [self.attr["type"].strip()] + if self.attr["attr"]: + typ.extend(self.attr["attr"]) + start = self.indent() + ", ".join(typ) + " :: " lines, start, dummy, length = self._init_lines(start, start) args = CF.args_from_list(self.args) allocd = args.alloc(length, cont=False) @@ -618,11 +615,11 @@ class Decl(Statement, HasArgs): class Call(Statement, HasName, HasArgs): - """A call statement""" - regexp = re.compile('^ *call +[a-zA-Z0-9_%]+', re.I) - _re1 = re.compile('^ *call *(?P<name>[a-zA-Z0-9_%]+) *?\((?P<arg>.*)\)', re.I) - _re2 = re.compile('^ *call *(?P<name>[a-zA-Z0-9_%]+) *$', re.I) + + regexp = re.compile("^ *call +[a-zA-Z0-9_%]+", re.I) + _re1 = re.compile("^ *call *(?P<name>[a-zA-Z0-9_%]+) *?\((?P<arg>.*)\)", re.I) + _re2 = re.compile("^ *call *(?P<name>[a-zA-Z0-9_%]+) *$", re.I) def _parse(self): """Parse the code, store attributes...""" @@ -630,42 +627,42 @@ class Call(Statement, HasName, HasArgs): if not mat: mat = self._re2.search(self.code) self.attr = mat.groupdict() - self.attr['arg'] = [] + self.attr["arg"] = [] else: - assert mat, 'unexpected call: %r' % self.code + assert mat, "unexpected call: %r" % self.code self.attr = mat.groupdict() - self.attr['arg'] = CF.ArgSplitter(self.attr['arg']).strings() + self.attr["arg"] = CF.ArgSplitter(self.attr["arg"]).strings() def _code_text(self): """Split lines in groups of 5 arguments""" - start = self.indent() + 'call ' + self.name + '(' - indent = ' ' * len(start) + start = self.indent() + "call " + self.name + "(" + indent = " " * len(start) if len(self.args) == 0: - return start + ')' + return start + ")" lines, start, indent, length = self._init_lines(start, indent) args = CF.args_from_list(self.args) allocd = args.alloc(length, maxi=5, cont=True) lines.append(start + allocd.pop(0)) lines.extend([indent + grp for grp in allocd]) - lines[-1] = lines[-1] + ')' + lines[-1] = lines[-1] + ")" return join_lines(lines, end_cr=False) class EndSub(CloseStatement): - """End of a Subroutine or Function block""" - regexp = re.compile('^ *end(| +(subroutine|function)(| +\w+)) *$', re.I) + regexp = re.compile("^ *end(| +(subroutine|function)(| +\w+)) *$", re.I) -class Subroutine(Block, HasName, HasArgs): +class Subroutine(Block, HasName, HasArgs): """A subroutine statement""" - regexp = re.compile("^ *(?P<qual>(|recursive|)) *subroutine +\w+", re.I) + + regexp = re.compile("^ *(?P<qual>(|recursive)) *subroutine +\w+", re.I) end_block = EndSub - _re1 = re.compile('^ *(?P<qual>(|recursive|)) *subroutine *(?P<name>\w+) *?' - '\((?P<arg>.*?)\)', re.I) - _re2 = re.compile( - '^ *(?P<qual>(|recursive)) *subroutine *(?P<name>\w+) *$', re.I) + _re1 = re.compile( + "^ *(?P<qual>(|recursive)) *subroutine *(?P<name>\w+) *?" "\((?P<arg>.*?)\)", re.I + ) + _re2 = re.compile("^ *(?P<qual>(|recursive)) *subroutine *(?P<name>\w+) *$", re.I) def _parse(self): """Parse the code, store attributes...""" @@ -673,40 +670,40 @@ class Subroutine(Block, HasName, HasArgs): if not mat: mat = self._re2.search(self.code) self.attr = mat.groupdict() - self.attr['arg'] = [] + self.attr["arg"] = [] else: - assert mat, 'unexpected subroutine: %r' % self.code + assert mat, "unexpected subroutine: %r" % self.code self.attr = mat.groupdict() - self.attr['arg'] = CF.ArgSplitter(self.attr['arg']).strings() + self.attr["arg"] = CF.ArgSplitter(self.attr["arg"]).strings() def _code_text(self): """Split lines in groups of 5 arguments""" - qual = self.attr.get('qual', '') - start = self.indent() + qual + 'subroutine ' + self.name + '(' - indent = ' ' * len(start) + qual = self.attr.get("qual", "") + start = self.indent() + qual + "subroutine " + self.name + "(" + indent = " " * len(start) if len(self.args) == 0: - return start + ')' + return start + ")" lines, start, indent, length = self._init_lines(start, indent) args = CF.args_from_list(self.args) allocd = args.alloc(length, maxi=5, cont=True) lines.append(start + allocd.pop(0)) lines.extend([indent + grp for grp in allocd]) - lines[-1] = lines[-1] + ')' + lines[-1] = lines[-1] + ")" return join_lines(lines, end_cr=False) class Function(Block, HasName, HasArgs): - """A function statement""" + regexp = re.compile("^ *(%s)? *function +\w+" % RX.DECLS, re.I) end_block = EndSub - _re1 = re.compile('^ *(?P<type>(%s)?) *function *' - '(?P<name>\w+) *?\((?P<arg>.*?)\)' % RX.DECLS, re.I) - _re2 = re.compile('^ *(?P<type>(%s)?) *function *' - '(?P<name>\w+) *$' % RX.DECLS, re.I) - _re0 = re.compile('^ *function *' - '(?P<name>\w+) *?\((?P<arg>.*?)\) *' - 'result *\((?P<result>.*?)\)', re.I) + _re1 = re.compile( + "^ *(?P<type>(%s)?) *function *" "(?P<name>\w+) *?\((?P<arg>.*?)\)" % RX.DECLS, re.I + ) + _re2 = re.compile("^ *(?P<type>(%s)?) *function *" "(?P<name>\w+) *$" % RX.DECLS, re.I) + _re0 = re.compile( + "^ *function *" "(?P<name>\w+) *?\((?P<arg>.*?)\) *" "result *\((?P<result>.*?)\)", re.I + ) def _parse(self): """Parse the code, store attributes...""" @@ -716,42 +713,42 @@ class Function(Block, HasName, HasArgs): if not mat: mat = self._re2.search(self.code) self.attr = mat.groupdict() - self.attr['arg'] = [] + self.attr["arg"] = [] else: - assert mat, 'unexpected Function: %r' % self.code + assert mat, "unexpected Function: %r" % self.code self.attr = mat.groupdict() - self.attr['type'] = self.attr.get('type', '').strip() - self.attr['arg'] = CF.ArgSplitter(self.attr['arg']).strings() + self.attr["type"] = self.attr.get("type", "").strip() + self.attr["arg"] = CF.ArgSplitter(self.attr["arg"]).strings() def _code_text(self): """Split lines in groups of 5 arguments""" - typ = self.attr.get('type', '') - res = '' - if self.attr.get('result'): + typ = self.attr.get("type", "") + res = "" + if self.attr.get("result"): res = f' result ({self.attr["result"]})' - start = self.indent() + typ + 'function ' + self.name + '(' - indent = ' ' * len(start) + start = self.indent() + typ + "function " + self.name + "(" + indent = " " * len(start) if len(self.args) == 0: - return start + ')' + res + return start + ")" + res lines, start, indent, length = self._init_lines(start, indent) args = CF.args_from_list(self.args) allocd = args.alloc(length, maxi=5, cont=True) lines.append(start + allocd.pop(0)) lines.extend([indent + grp for grp in allocd]) - lines[-1] = lines[-1] + ')' + res + lines[-1] = lines[-1] + ")" + res return join_lines(lines, end_cr=False) class EndDo(CloseStatement, HasLabel): - """End of a LoopDo block""" - expr = '^ *(|%(label)s +)(end *do)(|\W.*)$' - _re1 = re.compile('^ *(?P<label>|[0-9]* +)end *do', re.I) + + expr = "^ *(|%(label)s +)(end *do)(|\W.*)$" + _re1 = re.compile("^ *(?P<label>|[0-9]* +)end *do", re.I) @classmethod def search(cls, first_line, kwargs=None): """Use the label of the Loop with label""" - if kwargs.get('label') is None: + if kwargs.get("label") is None: return False expr = re.compile(cls.expr % kwargs, flags=re.I) return expr.search(first_line) @@ -759,7 +756,7 @@ class EndDo(CloseStatement, HasLabel): def _parse(self): """Parse the code, store attributes...""" mat = self._re1.search(self.code) - assert mat, 'unexpected EndDo: %r' % self.code + assert mat, "unexpected EndDo: %r" % self.code self.attr = mat.groupdict() self._clean_label() @@ -770,14 +767,14 @@ class EndDo(CloseStatement, HasLabel): class Continue(Statement, HasLabel): - """A Continue statement not appaired to a loop""" - regexp = re.compile('^ *(?P<label>|[0-9]* +)continue *$', re.I) + + regexp = re.compile("^ *(?P<label>|[0-9]* +)continue *$", re.I) def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected Continue: %r' % self.code + assert mat, "unexpected Continue: %r" % self.code self.attr = mat.groupdict() self._clean_label() @@ -788,97 +785,97 @@ class Continue(Statement, HasLabel): class CloseContinue(Continue, MultipleCloseStatement): - """End of a Loop block using label""" - expr = '^ *%(label)s +continue *$' + + expr = "^ *%(label)s +continue *$" @classmethod def search(cls, first_line, kwargs=None): """Use the label of the Loop with label""" - if kwargs.get('label') is None: + if kwargs.get("label") is None: return False expr = re.compile(cls.expr % kwargs, flags=re.I) return expr.search(first_line) class LoopDo(Block, HasArgs, HasLabel): - """A block of type loop Do""" + # should be UseLabel - regexp = re.compile('^ *do +(?P<label>[0-9]*)(|,) *(?P<var>\w+) *' - '= *(?P<arg>.+? *, *.+(| *,.+))$', re.I) + regexp = re.compile( + "^ *do +(?P<label>[0-9]*)(|,) *(?P<var>\w+) *" "= *(?P<arg>.+? *, *.+(| *,.+))$", re.I + ) end_block = (EndDo, CloseContinue) def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected LoopDo: %r' % self.code + assert mat, "unexpected LoopDo: %r" % self.code self.attr = mat.groupdict() self._clean_label() - self.attr['arg'] = CF.ArgSplitter(self.attr['arg']).strings() + self.attr["arg"] = CF.ArgSplitter(self.attr["arg"]).strings() def _code_text(self): """Command line""" attrs = self.attr.copy() - attrs['args'] = str(CF.args_from_list(self.args)) - if attrs['label']: - attrs['label'] += ' ' - text = 'do %(label)s%(var)s = %(args)s' % attrs + attrs["args"] = str(CF.args_from_list(self.args)) + if attrs["label"]: + attrs["label"] += " " + text = "do %(label)s%(var)s = %(args)s" % attrs return self.indent() + text class LoopDoWhile(Block, HasCondition): - """A block of type loop Do while""" - regexp = re.compile('^ *do +(?P<label>[0-9]*) *while *' - '\( *(?P<cond>.*?) *\) *$', re.I) + + regexp = re.compile("^ *do +(?P<label>[0-9]*) *while *" "\( *(?P<cond>.*?) *\) *$", re.I) end_block = (EndDo, CloseContinue) def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected LoopDoWhile: %r' % self.code + assert mat, "unexpected LoopDoWhile: %r" % self.code self.attr = mat.groupdict() def _code_text(self): """Command line""" - text = 'do while (%s)' % self.cond + text = "do while (%s)" % self.cond return self.indent() + text class EndIf(CloseStatement): - """End of a IfThen block""" - regexp = re.compile('^ *end *if *$', re.I) + regexp = re.compile("^ *end *if *$", re.I) -class Else(CloseStatement): +class Else(CloseStatement): """A else statement""" - regexp = re.compile('^ *else *$', re.I) + regexp = re.compile("^ *else *$", re.I) -class ElseIf(CloseStatement, HasCondition): +class ElseIf(CloseStatement, HasCondition): """A else if statement""" - regexp = re.compile('^ *else *if *\( *(?P<cond>.*?) *\) *then', re.I) + + regexp = re.compile("^ *else *if *\( *(?P<cond>.*?) *\) *then", re.I) def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected ElseIf: %r' % self.code + assert mat, "unexpected ElseIf: %r" % self.code self.attr = mat.groupdict() def _code_text(self): """Command line""" - text = 'else if (%s) then' % self.cond + text = "else if (%s) then" % self.cond return self.indent() + text class Assert(Statement, HasCondition): - """A assert statement""" - regexp = re.compile('^ *ASSERT *\((?P<cond>.*)\)') + + regexp = re.compile("^ *ASSERT *\((?P<cond>.*)\)") def _parse(self): """Parse the code, store attributes...""" @@ -891,53 +888,53 @@ class Assert(Statement, HasCondition): class IfThen(Block, HasCondition): - """A conditional block if or if/then""" - regexp = re.compile('^ *if((?: +|\().*)$', re.I) - _re1 = re.compile('^ *if *\( *(?P<cond>.*) *\) *then', re.I) + + regexp = re.compile("^ *if((?: +|\().*)$", re.I) + _re1 = re.compile("^ *if *\( *(?P<cond>.*) *\) *then", re.I) end_block = EndIf def _parse(self): """Parse the code, store attributes...""" mat = self._re1.search(self.code) if mat: - assert mat, 'unexpected IfThen: %r' % self.code + assert mat, "unexpected IfThen: %r" % self.code self.attr = mat.groupdict() - self.attr['cond'] = self.attr['cond'].strip() - self.attr['then'] = 'then' + self.attr["cond"] = self.attr["cond"].strip() + self.attr["then"] = "then" else: # single line if mat = self.regexp.search(self.code) - assert mat, 'unexpected IfThen: %r' % self.code - txt = re.sub('^ +', '', mat.group(1)) - assert txt.startswith('('), 'unexpected If: %r' % self.code + assert mat, "unexpected IfThen: %r" % self.code + txt = re.sub("^ +", "", mat.group(1)) + assert txt.startswith("("), "unexpected If: %r" % self.code cond = CF.first_enclosed(txt) - self.attr['cond'] = str(CF.ParSplitter(cond)[1]) - self.attr['instr'] = txt.replace(cond, '', 1).strip() - self.attr['then'] = '' + self.attr["cond"] = str(CF.ParSplitter(cond)[1]) + self.attr["instr"] = txt.replace(cond, "", 1).strip() + self.attr["then"] = "" self._closed = True def _code_text(self): """Command line""" - start, then = self.indent() + 'if (', ') %s' % self.attr['then'] - indent = ' ' * len(start) + start, then = self.indent() + "if (", ") %s" % self.attr["then"] + indent = " " * len(start) lines, start, indent, length = self._init_lines(start, indent) cond = CF.LogicalSplitter(self.cond) allocd = cond.alloc(length - len(then), cont=True) lines.append(start + allocd.pop(0)) lines.extend([indent + grp for grp in allocd]) last = lines.pop() + then - if self.attr['then'] != '': + if self.attr["then"] != "": lines.append(last) text = join_lines(lines, end_cr=False) else: - indent = ' ' * len(last) + indent = " " * len(last) line2, start2, indent, length = self._init_lines(last, indent) - instr = source(self.attr['instr'], opts={'maxlength': length}) + instr = source(self.attr["instr"], opts={"maxlength": length}) if not isinstance(instr[0], Untyped): allocd = instr.code_text().splitlines() else: - instr = CF.BaseSplitter(self.attr['instr']) + instr = CF.BaseSplitter(self.attr["instr"]) allocd = instr.alloc(length, cont=True) line2.append(start2 + allocd.pop(0)) line2.extend([indent + grp for grp in allocd]) @@ -947,7 +944,6 @@ class IfThen(Block, HasCondition): class Assign(Statement): - """An assignment""" @classmethod @@ -955,25 +951,25 @@ class Assign(Statement): """Tell if the 'first_line' matches the block/statement. 'dummy' (dict) allows more complicated search function.""" spl = CF.SpaceSplitter(first_line) - return spl.size() >= 3 and spl[1] == '=' + return spl.size() >= 3 and spl[1] == "=" def _parse(self): """Parse the code, store attributes...""" spl = CF.SpaceSplitter(self.code) - assert spl[1] == '=', 'unexpected Assign: %r' % self.code - self.attr['dest'] = str(spl[0]) - self.attr['instr'] = ' '.join(spl[2:]) + assert spl[1] == "=", "unexpected Assign: %r" % self.code + self.attr["dest"] = str(spl[0]) + self.attr["instr"] = " ".join(spl[2:]) def _code_text(self): """Command line""" - start = self.indent() + '%(dest)s = ' % self.attr - indent = ' ' * len(start) + start = self.indent() + "%(dest)s = " % self.attr + indent = " " * len(start) lines, start, indent, length = self._init_lines(start, indent) - instr = source(self.attr['instr'], opts={'maxlength': length}) + instr = source(self.attr["instr"], opts={"maxlength": length}) if not isinstance(instr[0], Untyped): allocd = instr.code_text().splitlines() else: - instr = CF.BaseSplitter(self.attr['instr']) + instr = CF.BaseSplitter(self.attr["instr"]) allocd = instr.alloc(length, cont=True) lines.append(start + allocd.pop(0)) lines.extend([indent + grp for grp in allocd]) @@ -981,14 +977,14 @@ class Assign(Statement): class EndInterface(CloseStatement): - """End of a Interface block""" - regexp = re.compile(r'^ *end(| +interface(| +\w+)) *$', re.I) + regexp = re.compile(r"^ *end(| +interface(| +\w+)) *$", re.I) -class Interface(Block): +class Interface(Block): """A interface statement""" + # 'assignment(=)' or 'operator(+)' are ignored, kept as 'name' regexp = re.compile("^ *interface *(?P<name>|.*) *$", re.I) end_block = EndInterface @@ -996,7 +992,7 @@ class Interface(Block): def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected interface: %r' % self.code + assert mat, "unexpected interface: %r" % self.code self.attr = mat.groupdict() def _code_text(self): @@ -1005,89 +1001,89 @@ class Interface(Block): class EndSelectCase(CloseStatement): - """End of a select case block""" - regexp = re.compile('^ *end(| +select) *$', re.I) + regexp = re.compile("^ *end(| +select) *$", re.I) -class SelectCase(Block, HasArgs): +class SelectCase(Block, HasArgs): """A select case block""" + regexp = re.compile("^ *select case *\( *(?P<arg>\w+) *\) *$", re.I) end_block = EndSelectCase def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected select case: %r' % self.code + assert mat, "unexpected select case: %r" % self.code self.attr = mat.groupdict() def _code_text(self): """Command line""" - text = 'select case (%s)' % self.args + text = "select case (%s)" % self.args return self.indent() + text -_re_case = re.compile( - "^ *case *((?P<def>default)|\( *(?P<arg>\w+) *\)) *$", re.I) +_re_case = re.compile("^ *case *((?P<def>default)|\( *(?P<arg>\w+) *\)) *$", re.I) -class EndCase(CloseStatement, HasArgs): +class EndCase(CloseStatement, HasArgs): """A case marks the end of the previous case""" + regexp = _re_case def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected case: %r' % self.code + assert mat, "unexpected case: %r" % self.code self.attr = mat.groupdict() - if mat.group('def'): - self.attr['arg'] = mat.group('def') + if mat.group("def"): + self.attr["arg"] = mat.group("def") def _code_text(self): """Command line""" - arg = self.args if self.args.strip().lower() == 'default' else '(%s)' % self.args - text = 'case %s' % arg + arg = self.args if self.args.strip().lower() == "default" else "(%s)" % self.args + text = "case %s" % arg return self.indent() + text class Case(Block, HasArgs): - """A case block""" + regexp = _re_case end_block = EndCase def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected case: %r' % self.code + assert mat, "unexpected case: %r" % self.code self.attr = mat.groupdict() - if mat.group('def'): - self.attr['arg'] = mat.group('def') + if mat.group("def"): + self.attr["arg"] = mat.group("def") def _code_text(self): """Command line""" - arg = self.args if self.args == 'default' else '(%s)' % self.args - text = 'case %s' % arg + arg = self.args if self.args == "default" else "(%s)" % self.args + text = "case %s" % arg return self.indent() + text class EndModule(CloseStatement): - """End of a Module block""" - regexp = re.compile('^ *end(| +module(| +\w+)) *$', re.I) + regexp = re.compile("^ *end(| +module(| +\w+)) *$", re.I) -class Module(Block, HasName): +class Module(Block, HasName): """A module statement""" + regexp = re.compile("^ *module +(?P<name>\w+) *$", re.I) end_block = EndModule def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected module: %r' % self.code + assert mat, "unexpected module: %r" % self.code self.attr = mat.groupdict() def _code_text(self): @@ -1096,32 +1092,32 @@ class Module(Block, HasName): class Contains(CloseStatement): - """A contains statement""" - regexp = re.compile('^ *contains *$', re.I) + regexp = re.compile("^ *contains *$", re.I) -class GlobalPrivate(Statement): +class GlobalPrivate(Statement): """A global private statement""" - regexp = re.compile('^ *private *$', re.I) + regexp = re.compile("^ *private *$", re.I) -class GlobalPublic(Statement): +class GlobalPublic(Statement): """A global public statement""" - regexp = re.compile('^ *public *$', re.I) + regexp = re.compile("^ *public *$", re.I) -class EndType(CloseStatement): +class EndType(CloseStatement): """End of a Type block""" - regexp = re.compile(r'^ *end(| +type(| +\w+)) *$', re.I) + regexp = re.compile(r"^ *end(| +type(| +\w+)) *$", re.I) -class Type(Block): +class Type(Block): """A module statement""" + regexp = re.compile(r"^ *type(| +\w+) *$", re.I) end_block = EndType @@ -1131,50 +1127,80 @@ class Type(Block): class Use(Statement, HasArgs): - """A use statement""" - regexp = re.compile(r'^ *use +(?P<mod>\w+)(' - r'|(?P<rename>( *, *\w+ *=> *\w+)+)' - r'| *, *only *: *(?P<only>(.*)+)' - r') *$', re.I) - _rename = re.compile(r' *(?P<local>\w+) *=> *(?P<orig>\w+)') + + regexp = re.compile( + r"^ *use +(?P<mod>\w+)(" + r"|(?P<rename>( *, *\w+ *=> *\w+)+)" + r"| *, *only *: *(?P<only>(.*)+)" + r") *$", + re.I, + ) + _rename = re.compile(r" *(?P<local>\w+) *=> *(?P<orig>\w+)") def _parse(self): """Parse the code, store attributes...""" mat = self.regexp.search(self.code) - assert mat, 'unexpected use: %r' % self.code + assert mat, "unexpected use: %r" % self.code self.attr = mat.groupdict() - if self.attr['rename']: + if self.attr["rename"]: rename = {} - txt = self.attr['rename'] + txt = self.attr["rename"] for mat in self._rename.finditer(txt): rename[mat.group("orig")] = mat.group("local") - self.attr['rename'] = rename - if self.attr['only']: + self.attr["rename"] = rename + if self.attr["only"]: symb = {} - for txt in self.attr['only'].split(","): + for txt in self.attr["only"].split(","): mat = self._rename.search(txt) if mat: symb[mat.group("orig")] = mat.group("local") else: symb[txt.strip()] = txt.strip() - self.attr['only'] = symb + self.attr["only"] = symb _ALL_STMT = [ - EmptyLine, Directive, Comment, Implicit, - PreprocIfDef, PreprocElse, PreprocElseIf, PreprocEndIf, - PreprocDefine, PreprocInclude, Preproc, - Subroutine, Function, EndSub, - Interface, EndInterface, - Module, EndModule, - Type, EndType, - SelectCase, EndSelectCase, EndCase, Case, - Decl, Call, Assert, - Assign, Contains, Use, - GlobalPublic, GlobalPrivate, - LoopDo, LoopDoWhile, EndDo, CloseContinue, - IfThen, Else, ElseIf, EndIf, + EmptyLine, + Directive, + Comment, + Implicit, + PreprocIfDef, + PreprocElse, + PreprocElseIf, + PreprocEndIf, + PreprocDefine, + PreprocInclude, + Preproc, + Subroutine, + Function, + EndSub, + Interface, + EndInterface, + Module, + EndModule, + Type, + EndType, + SelectCase, + EndSelectCase, + EndCase, + Case, + Decl, + Call, + Assert, + Assign, + Contains, + Use, + GlobalPublic, + GlobalPrivate, + LoopDo, + LoopDoWhile, + EndDo, + CloseContinue, + IfThen, + Else, + ElseIf, + EndIf, Continue, ] @@ -1186,13 +1212,14 @@ def statement_factory(first_line, lnum, parent_level, opts, search_args=None): return klass(lnum, parent_level, opts) return Untyped(lnum, parent_level, opts) + # convenient functions def source(text=None, filename=None, init_level=-1, opts=None): """Create a Block object parsing 'text' or reading 'filename'.""" if not text: - with open(filename, 'r') as fobj: + with open(filename, "r") as fobj: text = fobj.read() src = Block(1, level=init_level, opts=opts) src.set_code(text) @@ -1219,7 +1246,7 @@ def beautify(fname, backup_ext=None): os.rename(fname, fname + backup_ext) src.write_code(fname) except (AssertionError, Exception): - print('error reading', fname) + print("error reading", fname) raise diff --git a/lib/decode_jeimpm.py b/lib/decode_jeimpm.py new file mode 100755 index 0000000000000000000000000000000000000000..f69e8095e30df9c6a389a1c09da014751c0b9e1d --- /dev/null +++ b/lib/decode_jeimpm.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +# coding=utf-8 + +""" +Décodage d'un fichier obtenu avec IMPR_JEVEUX(ENTITE="MEMOIRE", IMPRESSION=_F(UNITE=nn)) +""" + +import argparse +import re + + +class Obj: + name = size = attr = None + + def __init__(self, name, size, attr=""): + self.name = name + self.size = size + self.attr = attr + + def copy(self): + return Obj(self.name, self.size, self.attr) + + def __repr__(self): + return f"{self.name:32s} {self.size:16d}" + + +class Mem: + filename = data = None + + def __init__(self, filename=None): + self.filename = filename + self.data = {} + if filename: + self.decode() + + @staticmethod + def read(filename): + """Factory that returns the relevant object to read the given file.""" + with open(filename) as fobj: + memory = "OBJETS ALLOUES DYNAMIQUEMENT" in fobj.read() + klas = Mem + if not memory: + klas = MemDisque + return klas(filename) + + def decode(self): + """Decode the content of jeimpm output (ENTITE="MEMOIRE").""" + re0 = re.compile("^\|[GV]\|", re.M) + with open(self.filename) as fobj: + lines = [line.strip() for line in fobj.readlines() if re0.search(line)] + + for line in lines: + if not line.strip(): + continue + spl = line.split("|") + assert len(spl) == 10, spl + obj = Obj(spl[9].strip(), int(spl[7]), spl[8].strip()) + self.data[obj.name] = obj + + def __len__(self): + return len(self.data) + + def get_names(self): + """Return the list of objects names.""" + return sorted(self.data.keys()) + + def sizeof(self, names=None): + """Return the size of the objects passed or all.""" + names = names or self.get_names() + return sum([self.data[name].size for name in names]) + + def sizeofMB(self, names=None): + """Return the size of the objects passed or all in MB.""" + return self.sizeof(names) * 8 / 1024 / 1024 + + def extend(self, other): + """Extend by union with another.""" + for name, obj in other.data.items(): + obj = obj.copy() + if name in self.data: + current = self.data[name] + if "__GLOBALE" not in name and current.size != obj.size and "A" not in current.attr: + # no yet rewritten on disk + print(f" mem & disque: {name}: {current.attr}: {current.size} vs {obj.size}") + obj.size = max(current.size, obj.size) + obj.attr = current.attr or obj.attr + self.data[name] = obj + + def difference(self, other): + """Return the difference with another. + + (i.e. all objects that are in this *Mem* but not in the other.) + """ + diff = Mem() + new = set(self.get_names()).difference(other.get_names()) + for name in new: + diff.data[name] = self.data[name] + return diff + + def changed(self, other): + """Return the change of size of the objects common with another.""" + diff = Mem() + common = set(self.get_names()).intersection(other.get_names()) + for name in common: + diff.data[name] = self.data[name].copy() + diff.data[name].size -= other.data[name].size + return diff + + def root_names(self): + """Return the root objects names.""" + return sorted(set([self._root(name) for name in self.get_names()])) + + @staticmethod + def _root(name): + return name.split(".")[0].strip() + + def group(self): + """Group objects by root name.""" + grp = Mem() + data = grp.data + for obj in self.data.values(): + name = self._root(obj.name) + data.setdefault(name, Obj(name, 0, obj.attr)) + data[name].size += obj.size + return grp + + def __repr__(self): + nbroot = len(self.root_names()) + return ( + f"{nbroot:4d} objets ({len(self)} au total) " + f"pour {self.sizeof() * 8 / 1024 / 1024:.3f} Mo" + ) + + def show(self, sortby="name", groupby=None): + """Print content""" + assert sortby in ("name", "size") + assert groupby in (None, "root") + + def fkey(item): + return item[0] if sortby == "name" else item[1].size + + items = sorted(list(self.data.items()), key=fkey) + for _, obj in items: + print(obj) + + +# 0 1 2 3 4 5 6 7 8 +# 01234567890123456789012345678901234567890123456789012345678901234567890123456789 +# 1123 00000033.NUME000000.DELG -V-I- 8 179070 1128 0 1 + + +class MemDisque(Mem): + + def decode(self): + """Decode the content of jeimpm output (ENTITE="DISQUE").""" + re0 = re.compile("^ +[0-9]+", re.M) + with open(self.filename) as fobj: + lines = [line for line in fobj.readlines() if re0.search(line)] + + for line in lines: + assert line[43] == line[45] == line[47] == "-", line[43:47] + name = line[9:43].strip() + size = line[51:58].strip() + obj = Obj(name, int(size)) + self.data[obj.name] = obj + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("filename", nargs="*") + args = parser.parse_args() + mem = [Mem.read(fn) for fn in args.filename] diff --git a/lib/hgaster/ascommands.py b/lib/hgaster/ascommands.py index d800d46c05499cc22286a753e10d7b0a5a4bb6a9..eed57cd936b2cabd9c5e770b0628c8ad6d0f9100 100644 --- a/lib/hgaster/ascommands.py +++ b/lib/hgaster/ascommands.py @@ -116,7 +116,6 @@ SEPAR = """ class CandidateRevisionCheck(object): - """Offer several unit command to check a revision, to submit it, to integrate it @@ -547,7 +546,6 @@ class CandidateRevisionCheck(object): class CandidateRevisionCheckAster(CandidateRevisionCheck): - """Abstract class for code_aster repositories.""" def check_repositories_updates(self): @@ -704,7 +702,6 @@ class CandidateRevisionCheckAster(CandidateRevisionCheck): class AbstractSubmit(CandidateRevisionCheck): - """Check code_aster source files at the parent revision and, in case of success, submit a request for integration. @@ -805,79 +802,6 @@ class AbstractSubmit(CandidateRevisionCheck): logger.warn(_("do not send notification to persons in charge")) return logger.errcode - if self._local: - logger.warn(_("do not send notification to persons in charge")) - return logger.errcode - from aslint.common_checkers import PersonInCharge - - assert self._report is not None - res = self._report.report_by_type() - nbchg = res[1].get(PersonInCharge.id, 0) - if nbchg < 1: - logger.info(_("no person in charge of the changed modules")) - return logger.errcode - logger.info(_("%d source files have a person in charge"), nbchg) - # list of files by person in charge - fname_pic = {} - for fname, msglist in self._report.with_msg_iter(not_empty=True): - pic = [msg.result["main"] for msg in msglist if isinstance(msg, PersonInCharge)] - list_addr = convert_to_addr(pic) - if not list_addr: - continue - for add in list_addr: - fname_pic[add] = fname_pic.get(add, []) + [ - fname, - ] - # send diff to dvp - wrkrev = self.wrkrev - refrev = self.refrev - revs = [refrev, wrkrev.hex()] - if self.get_cfg("admin_push_uri"): - url = get_hgpath(self.repo.root, self.get_cfg("admin_push_uri")) - else: - url = None - dest = convert_to_addr(self.get_cfg("notify.user")) - dest = dest and dest[0] or "" - header = HEADER_DIFF % { - "dvp": self.dvp, - "address": dest, - "wrkrev": shortrev(wrkrev), - "refrev": shortrev_s(refrev), - "url": url, - "related_issues": self._issues_descr, - } - trunc = _("The entire diff is too long. It has been truncated.") - for add, lfiles in list(fname_pic.items()): - if "@" not in add: - logger.warn(_("invalid address '{0}' in files: {1}").format(add, lfiles)) - continue - if add.strip() == dest.strip(): - logger.info( - _("no mail sent for the files which you are the person in charge: {0}").format( - lfiles - ) - ) - continue - text = [header] - diffs = get_diff(self.repo.root, revs, lfiles) - if len(diffs) > MAX_MESSAGE_SIZE: - text.append(trunc) - diffs = diffs[:MAX_MESSAGE_SIZE] - diffs += os.linesep + "[...]" - text.extend([SEPAR, _("List of changed files:"), ""]) - text.extend(lfiles) - text.append(SEPAR) - text.append(diffs) - text = [convert(part) for part in text] - text = os.linesep.join(text) - sendmail( - add, - "[submit@{host}] %s is changing files you are responsible" % self.dvp, - text, - dry_run=self._dry, - ) - return logger.errcode - @allow_cancel_error def _check_command(self, title, command): """Execute a shell command""" @@ -974,7 +898,6 @@ class AbstractSubmit(CandidateRevisionCheck): class SubmitAster(CandidateRevisionCheckAster, AbstractSubmit): - """Check code_aster source files at the parent revision and, in case of success, submit changesets for continuous integration. """ @@ -1068,7 +991,6 @@ class SubmitAster(CandidateRevisionCheckAster, AbstractSubmit): class SubmitDevtools(AbstractSubmit): - """Check devtools source files at the parent revision and, in case of success, submit changesets for continuous integration. """ @@ -1098,7 +1020,6 @@ class SubmitDevtools(AbstractSubmit): class AbstractSubmitSmeca(AbstractSubmit): - """Minimal 'submit' command for some salome_meca tools (only push changes).""" def __init__(self, ui, repo, *args, **opts): @@ -1113,7 +1034,6 @@ class AbstractSubmitSmeca(AbstractSubmit): class SubmitAsterStudy(AbstractSubmitSmeca): - """Check AsterStudy source files at the parent revision and, in case of success, submit changesets for continuous integration. """ @@ -1134,7 +1054,6 @@ class SubmitAsterStudy(AbstractSubmitSmeca): class SubmitRTool(AbstractSubmitSmeca): - """Submit command for some salome_meca RTOOL plugin.""" @staticmethod @@ -1146,7 +1065,6 @@ class SubmitRTool(AbstractSubmitSmeca): class Integration(CandidateRevisionCheckAster): - """Set of elementary commands to manage the requests for integration scenarii for integration: diff --git a/share/test/test_repository_api/test_mercurial.py b/share/test/test_repository_api/test_mercurial.py index b266382c32590b64518f4294b1ec7a513cf3b518..aa75c01609564da32ae8e9c522bf73a5b9ef9ad5 100644 --- a/share/test/test_repository_api/test_mercurial.py +++ b/share/test/test_repository_api/test_mercurial.py @@ -49,17 +49,6 @@ def test_hg(): assert_that(calling(ui.configbool).with_args("ui", "username"), raises(ValueError)) -@only_on_repository("hg") -def test_utils(): - assert_that(is_repository(REPO), equal_to(True)) - iret = hgcmd(("status",), REPO)[0] - assert_that(iret, equal_to(0)) - iret = shell_cmd(REPO, "status")[0] - assert_that(iret, equal_to(0)) - iret = shell_cmd(REPO, ("status",))[0] - assert_that(iret, equal_to(0)) - - if __name__ == "__main__": import sys