diff --git a/.gitlabci/gitlab-ci-pleiade.yml b/.gitlabci/gitlab-ci-pleiade.yml
index 37a4b88acf76308973ff26ae3da1eff760971b82..3212959175001de2178c560e66e614e3d260e9f5 100644
--- a/.gitlabci/gitlab-ci-pleiade.yml
+++ b/.gitlabci/gitlab-ci-pleiade.yml
@@ -15,6 +15,8 @@ workflow:
   rules:
     - if: $CI_MERGE_REQUEST_IID
     #   seems redudant using fast-forward merges
+  auto_cancel:
+    on_new_commit: interruptible
 
 stages:
   - setup
@@ -24,11 +26,13 @@ image:
   name: ${IMAGE_URL}
 
 prepare:
+  interruptible: true
   stage: setup
   script:
     - .gitlabci/prepare.sh
 
 unittests:
+  interruptible: true
   stage: test
   needs: ["prepare"]
   script:
@@ -43,7 +47,28 @@ unittests:
       junit: share/test/run_testcases.xml
 
 auto_install:
+  interruptible: true
   stage: test
   needs: ["prepare", "unittests"]
   script:
     - .gitlabci/test_auto_install.sh
+
+sonarqube:
+  interruptible: true
+  stage: test
+  image:
+    name: nexus.retd.edf.fr:5012/sonarsource/sonar-scanner-cli:latest
+    entrypoint: ["/bin/sh", "-c"]
+  script:
+    - sonar-scanner
+        -Dsonar.projectBaseDir=.
+        -Dsonar.sources=bin,lib,share
+        -Dsonar.projectKey="gitlab-${CI_PROJECT_ID}"
+        -Dsonar.projectName="${CI_PROJECT_PATH_SLUG}"
+        -Dsonar.host.url="${SQ_SERVER}"
+        -Dsonar.login="${SQ_TOKEN}"
+  variables:
+    SQ_SERVER: "https://sonar.pleiade.edf.fr:443"
+  allow_failure: true
+  # only:
+  #   - main
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