From 1a82b0aad44c3e486a7e1663d1c1d1ff258124de Mon Sep 17 00:00:00 2001
From: Martin Larralde <martin.larralde@embl.de>
Date: Tue, 16 Jul 2024 12:39:06 +0200
Subject: [PATCH] Fix missing `__init__` signatures for most Cython types

---
 docs/api/plan7/misc.rst | 16 +++++++-
 docs/conf.py            |  1 -
 pyhmmer/daemon.pyx      | 50 ++++++++++---------------
 pyhmmer/easel.pyx       | 83 +++++++++++++++++++++++++++++++++--------
 pyhmmer/errors.pyx      | 16 ++++++++
 pyhmmer/plan7.pyx       | 69 ++++++++++++++++++++++++++++------
 6 files changed, 174 insertions(+), 61 deletions(-)

diff --git a/docs/api/plan7/misc.rst b/docs/api/plan7/misc.rst
index ae4a831c..046e0b39 100644
--- a/docs/api/plan7/misc.rst
+++ b/docs/api/plan7/misc.rst
@@ -13,15 +13,29 @@ Miscellaneous
 .. autoclass:: pyhmmer.plan7.Transitions(enum.IntEnum)
 
    .. autoattribute:: MM
+
+      :math:`M_{i} \to M_{i+1}`.
    
    .. autoattribute:: MI
+      
+      :math:`M_{i} \to I_{i+1}`.
    
    .. autoattribute:: MD
+      
+      :math:`M_{i} \to D_{i+1}`.
    
    .. autoattribute:: IM
+      
+      :math:`I_{i} \to M_{i+1}`.
    
    .. autoattribute:: II
+      
+      :math:`I_{i} \to I_{i+1}`.
    
    .. autoattribute:: DM
+
+      :math:`D_{i} \to M_{i+1}`.
    
-   .. autoattribute:: DD
\ No newline at end of file
+   .. autoattribute:: DD
+
+      :math:`D_{i} \to D_{i+1}`.
diff --git a/docs/conf.py b/docs/conf.py
index 95a01a96..e3a593af 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -191,7 +191,6 @@ autoclass_content = "class"
 autodoc_member_order = 'groupwise'
 autosummary_generate = []
 autodoc_typehints = 'none'
-autodoc_class_signature = 'separated'
 
 # -- Options for intersphinx extension ---------------------------------------
 
diff --git a/pyhmmer/daemon.pyx b/pyhmmer/daemon.pyx
index 099b04e9..db31f05c 100644
--- a/pyhmmer/daemon.pyx
+++ b/pyhmmer/daemon.pyx
@@ -107,7 +107,7 @@ cdef class Client:
         str address=DEFAULT_ADDRESS,
         uint16_t port=DEFAULT_PORT,
     ):
-        """__init__(self, address="127.0.0.1", port=51371)\n--
+        """__init__(self, address="127.0.0.1", port=51371)\n--\n
 
         Create a new `Client` connecting to the given HMMER daemon server.
 
@@ -144,10 +144,7 @@ cdef class Client:
     # --- C Methods ----------------------------------------------------------
 
     cdef bytearray _recvall(self, size_t message_size):
-        """_recvall(self, message_size)\n--
-
-        Receive exactly ``message_size`` bytes from ``self.socket``.
-
+        """Receive exactly ``message_size`` bytes from ``self.socket``.
         """
         cdef bytearray buffer = bytearray(message_size)
         cdef object    view   = memoryview(buffer)
@@ -169,9 +166,7 @@ cdef class Client:
         Pipeline pli,
         p7_pipemodes_e mode,
     ):
-        """_client(self, query, db, pli, mode)\n--
-
-        A generic implementation of the steps to communicate with the server.
+        """A generic implementation of the steps to communicate with the server.
 
         Arguments:
             query (`bytes`): A buffer storing the serialized query in
@@ -316,18 +311,12 @@ cdef class Client:
     # --- Python Methods -----------------------------------------------------
 
     def connect(self):
-        """connect(self)\n--
-
-        Connect the client to the HMMER daemon server.
-
+        """Connect the client to the HMMER daemon server.
         """
         self.socket.connect((self.address, self.port))
 
     def close(self):
-        """close(self)\n--
-
-        Close the connection to the HMMER daemon server.
-
+        """Close the connection to the HMMER daemon server.
         """
         self.socket.close()
 
@@ -338,9 +327,7 @@ cdef class Client:
         list ranges = None,
         **options
     ):
-        """search_seq(self, query, db=1, ranges=None, **options)\n--
-
-        Search the HMMER daemon database with a query sequence.
+        """Search the HMMER daemon database with a query sequence.
 
         Arguments:
             query (`~pyhmmer.easel.Sequence`): The sequence object to use
@@ -381,9 +368,7 @@ cdef class Client:
         list ranges = None,
         **options
     ):
-        """search_hmm(self, query, db=1, ranges=None, **options)\n--
-
-        Search the HMMER daemon database with a query HMM.
+        """Search the HMMER daemon database with a query HMM.
 
         Arguments:
             query (`~pyhmmer.easel.MSA`): The profile HMM object to use to
@@ -418,9 +403,7 @@ cdef class Client:
         return hits
 
     def scan_seq(self, Sequence query, uint64_t db = 1, **options):
-        """scan_seq(self, query, db=1, **options)\n--
-
-        Search the HMMER daemon database with a query sequence.
+        """Search the HMMER daemon database with a query sequence.
 
         Arguments:
             query (`~pyhmmer.easel.Sequence`): The sequence object to use
@@ -462,9 +445,7 @@ cdef class Client:
         object select_hits = None,
         **options
     ):
-        """iterate_seq(self, query, db=1, ranges=None, builder=None, select_hits=None, **options)\n--
-
-        Search iteratively against the daemon database with a query sequence.
+        """Search iteratively against the daemon database with a query sequence.
 
         Arguments:
             query (`~pyhmmer.easel.Sequence`): The sequence object to use
@@ -517,9 +498,7 @@ cdef class Client:
         object select_hits = None,
         **options
     ):
-        """iterate_hmm(self, query, db=1, ranges=None, builder=None, select_hits=None, **options)\n--
-
-        Search iteratively against the daemon database with a query HMM.
+        """Search iteratively against the daemon database with a query HMM.
 
         Arguments:
             query (`~pyhmmer.plan7.HMM`): The HMM object to use to query the
@@ -611,6 +590,15 @@ cdef class IterativeSearch(pyhmmer.plan7.IterativeSearch):
         object select_hits = None,
         dict options = None
     ):
+        """__init__(self, client, query, db, builder, ranges=None, select_hits=None, options=None)\n--\n
+
+        Create a new iterative search against the HMMER daemon.
+
+        Hint:
+            Use the `Client.iterate_hmm` method instead of creating this
+            object directly.
+
+        """
         self.client = client
         self.builder = builder
         self.select_hits = select_hits
diff --git a/pyhmmer/easel.pyx b/pyhmmer/easel.pyx
index 346a01db..aea2786c 100644
--- a/pyhmmer/easel.pyx
+++ b/pyhmmer/easel.pyx
@@ -470,7 +470,9 @@ cdef class GeneticCode:
         Alphabet nucleotide_alphabet not None = Alphabet.dna(),
         Alphabet amino_alphabet not None = Alphabet.amino(),
     ):
-        """Create a new genetic code for translating nucleotide sequences.
+        """__init__(self, translation_table=1, *, nucleotide_alphabet=None, amino_alphabet=None)\n--\n
+        
+        Create a new genetic code for translating nucleotide sequences.
 
         Arguments:
             translation_table (`int`): The translation table to use. Check the
@@ -707,7 +709,9 @@ cdef class Bitfield:
         libeasel.bitfield.esl_bitfield_Destroy(self._b)
 
     def __init__(self, object iterable):
-        """Create a new bitfield from an iterable of objects.
+        """__init__(self, iterable)\n--\n
+        
+        Create a new bitfield from an iterable of objects.
 
         Objects yielded by the iterable can be of any type and will be
         tested for truth before setting the corresponding field.
@@ -967,7 +971,10 @@ cdef class KeyHash:
         libeasel.keyhash.esl_keyhash_Destroy(self._kh)
 
     def __init__(self):
-        """Create a new empty key-hash collection.
+        """__init__(self)\n--\n
+        
+        Create a new empty key-hash collection.
+        
         """
         with nogil:
             if self._kh == NULL:
@@ -1235,7 +1242,10 @@ cdef class Vector:
         self._data = NULL
 
     def __init__(self, object iterable = ()):
-        """Create a new vector from the given iterable of values.
+        """__init__(self, iterable=())\n--\n
+        
+        Create a new vector from the given iterable of values.
+        
         """
         raise TypeError("Can't instantiate abstract class 'Vector'")
 
@@ -1486,7 +1496,10 @@ cdef class VectorF(Vector):
     # --- Magic methods ------------------------------------------------------
 
     def __init__(self, object iterable = ()):
-        """Create a new float vector from the given data.
+        """__init__(self, iterable=())\n--\n
+        
+        Create a new float vector from the given data.
+        
         """
         cdef int        n
         cdef size_t     i
@@ -1910,7 +1923,10 @@ cdef class VectorU8(Vector):
     # --- Magic methods ------------------------------------------------------
 
     def __init__(self, object iterable = ()):
-        """Create a new byte vector from the given data.
+        """__init__(self, iterable=())\n--\n
+        
+        Create a new byte vector from the given data.
+        
         """
         cdef int          n
         cdef size_t       i
@@ -2571,6 +2587,11 @@ cdef class MatrixF(Matrix):
     # --- Magic methods ------------------------------------------------------
 
     def __init__(self, object iterable = ()):
+        """__init__(self, iterable=())\n--\n
+
+        Create a new matrix from an iterable of rows.
+
+        """
         cdef int     i
         cdef int     j
         cdef size_t  m
@@ -2821,6 +2842,11 @@ cdef class MatrixU8(Matrix):
     # --- Magic methods ------------------------------------------------------
 
     def __init__(self, object iterable = ()):
+        """__init__(self, iterable=())\n--\n
+
+        Create a new matrix from an iterable of rows.
+
+        """
         cdef int       i
         cdef int       j
         cdef size_t    m
@@ -3487,7 +3513,9 @@ cdef class TextMSA(MSA):
         object sequences=None,
         bytes author=None,
     ):
-        """Create a new text-mode alignment with the given ``sequences``.
+        """__init__(self, name=None, description=None, accession=None, sequences=None, author=None)\n--\n
+        
+        Create a new text-mode alignment with the given ``sequences``.
 
         Arguments:
             name (`bytes`, optional): The name of the alignment, if any.
@@ -3814,7 +3842,9 @@ cdef class DigitalMSA(MSA):
         object sequences=None,
         bytes author=None,
     ):
-        """Create a new digital-mode alignment with the given ``sequences``.
+        """__init__(self, alphabet, name=None, description=None, accession=None, sequences=None, author=None)\n--\n
+        
+        Create a new digital-mode alignment with the given ``sequences``.
 
         Arguments:
             alphabet (`Alphabet`): The alphabet of the alignmed sequences.
@@ -4042,7 +4072,9 @@ cdef class MSAFile:
         bint digital = False,
         Alphabet alphabet = None,
     ):
-        """Create a new MSA file parser wrapping the given ``file``.
+        """__init__(self, file, format=None, *, digital=False, alphabet=False)\n--\n
+        
+        Create a new MSA file parser wrapping the given ``file``.
 
         Arguments:
             file (`str` or file-like object): Either the path to a file
@@ -4290,7 +4322,9 @@ cdef class Randomness:
         self._rng = NULL
 
     def __init__(self, object seed=None, bint fast=False):
-        """Create a new random number generator with the given seed.
+        """__init__(self, seed=None, fast=False)\n--\n
+        
+        Create a new random number generator with the given seed.
 
         Arguments:
             seed (`int`): The seed to initialize the generator with. If ``0``
@@ -4743,7 +4777,9 @@ cdef class TextSequence(Sequence):
         bytes source=None,
         dict  residue_markups=None,
     ):
-        """Create a new text-mode sequence with the given attributes.
+        """__init__(self, name=None, description=None, accession=None, sequence=None, source=None, residue_markups=None)\n--\n
+        
+        Create a new text-mode sequence with the given attributes.
 
         .. versionadded:: 0.10.4
             The ``residue_markups`` argument.
@@ -4937,7 +4973,9 @@ cdef class DigitalSequence(Sequence):
               bytes                 source          = None,
               dict                  residue_markups = None,
     ):
-        """Create a new digital-mode sequence with the given attributes.
+        """__init__(self, alphabet, name=None, description=None, accession=None, sequence=None, source=None, residue_markups=None)\n--\n
+        
+        Create a new digital-mode sequence with the given attributes.
 
         Raises:
             `ValueError`: When ``sequence`` contains digits outside the
@@ -5468,6 +5506,11 @@ cdef class TextSequenceBlock(SequenceBlock):
     # --- Magic methods ------------------------------------------------------
 
     def __init__(self, object iterable = ()):
+        """__init__(self, iterable=())\n--\n
+
+        Create a new block from an iterable of text sequences.
+
+        """
         self.clear()
         self.extend(iterable)
 
@@ -5598,7 +5641,9 @@ cdef class DigitalSequenceBlock(SequenceBlock):
         self.alphabet = alphabet
 
     def __init__(self, Alphabet alphabet not None, object iterable = ()):
-        """Create a new digital sequence block with the given alphabet.
+        """__init__(self, alphabet, iterable=())\n--\n
+        
+        Create a new digital sequence block with the given alphabet.
 
         Arguments:
             alphabet (`~pyhmmer.easel.Alphabet`): The alphabet to use for all
@@ -6139,7 +6184,9 @@ cdef class SequenceFile:
         bint digital = False,
         Alphabet alphabet = None,
     ):
-        """Create a new sequence file parser wrapping the given ``file``.
+        """__init__(self, file, format=None, *, digital=False, alphabet=None)\n--\n
+        
+        Create a new sequence file parser wrapping the given ``file``.
 
         Arguments:
             file (`str` or file-like object): Either the path to a file
@@ -6577,7 +6624,9 @@ cdef class SSIReader:
         self._ssi = NULL
 
     def __init__(self, object file):
-        """Create a new SSI file reader for the file at the given location.
+        """__init__(self, file)\n--\n
+        
+        Create a new SSI file reader for the file at the given location.
 
         Arguments:
             file (`str`, `bytes` or `os.PathLike`): The path to a
@@ -6669,7 +6718,9 @@ cdef class SSIWriter:
         self._newssi = NULL
 
     def __init__(self, object file, bint exclusive = False):
-        """Create a new SSI file write for the file at the given location.
+        """__init__(self, file, exclusive=False)\n--\n
+        
+        Create a new SSI file write for the file at the given location.
 
         Arguments:
             file (`str`, `bytes` or `os.PathLike`): The path to a
diff --git a/pyhmmer/errors.pyx b/pyhmmer/errors.pyx
index 83178388..44126bfe 100644
--- a/pyhmmer/errors.pyx
+++ b/pyhmmer/errors.pyx
@@ -49,6 +49,8 @@ class UnexpectedError(RuntimeError):
     """
 
     def __init__(self, int code, str function):
+        """__init__(self, code, function)\n--\n
+        """
         self.code = code
         self.function = function
 
@@ -68,6 +70,8 @@ class AllocationError(MemoryError):
     """
 
     def __init__(self, str ctype, size_t itemsize, size_t count=1):
+        """__init__(self, ctype, itemsize, count=1)\n--\n
+        """
         self.ctype = ctype
         self.itemsize = itemsize
         self.count = count
@@ -89,6 +93,8 @@ class EaselError(RuntimeError):
     """
 
     def __init__(self, int code, str message):
+        """__init__(self, code, message)\n--\n
+        """
         self.code = code
         self.message = message
 
@@ -124,6 +130,8 @@ class AlphabetMismatch(ValueError):
     """
 
     def __init__(self, expected, actual=None):
+        """__init__(self, expected, actual=None)\n--\n
+        """
         super().__init__(self)
         self.expected = expected
         self.actual = actual
@@ -150,6 +158,8 @@ class ServerError(RuntimeError):
     """
 
     def __init__(self, int code, str message):
+        """__init__(self, code, message)\n--\n
+        """
         self.code = code
         self.message = message
 
@@ -176,6 +186,8 @@ class MissingCutoffs(ValueError):
     """
 
     def __init__(self, str model_name = None, str bit_cutoffs = None):
+        """__init__(self, model_name=None, bit_cutoffs=None)\n--\n
+        """
         self.model_name = model_name
         self.bit_cutoffs = bit_cutoffs
 
@@ -203,6 +215,8 @@ class InvalidParameter(ValueError):
     """
 
     def __init__(self, str name, object value, *, list choices=None, str hint=None):
+        """__init__(self, name, value, *, choices=None, hint=None)\n--\n
+        """
         self.name = name
         self.value = value
         self.choices = choices
@@ -241,6 +255,8 @@ class InvalidHMM(ValueError):
     """
 
     def __init__(self, object hmm, str message):
+        """__init__(self, hmm, message)\n--\n
+        """
         super().__init__(hmm, message)
         self.message = message
         self.hmm = hmm
diff --git a/pyhmmer/plan7.pyx b/pyhmmer/plan7.pyx
index 73ead609..22a1c19b 100644
--- a/pyhmmer/plan7.pyx
+++ b/pyhmmer/plan7.pyx
@@ -486,7 +486,9 @@ cdef class Background:
         self.uniform = False
 
     def __init__(self, Alphabet alphabet, bint uniform=False):
-        """Create a new background model for the given ``alphabet``.
+        """__init__(self, alphabet, uniform=False)\n--\n
+        
+        Create a new background model for the given ``alphabet``.
 
         Arguments:
           alphabet (`~pyhmmer.easel.Alphabet`): The alphabet to create 
@@ -655,7 +657,9 @@ cdef class Builder:
         object window_length=None,
         object window_beta=None,
     ):
-        """Create a new sequence builder with the given configuration.
+        """__init__(self, alphabet, *, architecture="fast", weighting="pb", effective_number="entropy", prior_scheme="alphabet", symfrac=0.5, fragthres=0.5, wid=0.62, esigma=45.0, eid=0.62, EmL=200, EmN=200, EvL=200, EvN=200, EfL=100, EfN=200, Eft=0.04, seed=42, ere=None, popen=None, pextend=None, score_matrix=None, window_length=None, window_beta=None)\n--\n
+        
+        Create a new sequence builder with the given configuration.
 
         Arguments:
             alphabet (`~pyhmmer.easel.Alphabet`): The alphabet the builder
@@ -1157,6 +1161,8 @@ cdef class Cutoffs:
         self._is_profile = True
 
     def __init__(self, object owner):
+        """__init__(self, owner)\n--\n
+        """
         cdef str ty
         if isinstance(owner, Profile):
             self._cutoffs = &(<Profile> owner)._gm.cutoff
@@ -1693,6 +1699,8 @@ cdef class EvalueParameters:
         self._evparams = NULL
 
     def __init__(self, object owner):
+        """__init__(self, owner)\n--\n
+        """
         cdef str ty
         if isinstance(owner, Profile):
             self._evparams = &(<Profile> owner)._gm.evparam
@@ -2276,7 +2284,9 @@ cdef class HMM:
         self._hmm = NULL
 
     def __init__(self, Alphabet alphabet not None, int M, bytes name not None):
-        """Create a new HMM from scratch.
+        """__init__(self, alphabet, M, name)\n--\n
+        
+        Create a new HMM from scratch.
 
         Arguments:
             alphabet (`~pyhmmer.easel.Alphabet`): The alphabet of the model.
@@ -3495,7 +3505,9 @@ cdef class HMMFile:
         self._name = None
 
     def __init__(self, object file, bint db = True):
-        """Create a new HMM reader from the given file.
+        """__init__(self, file, db=True)\n--\n
+        
+        Create a new HMM reader from the given file.
 
         Arguments:
             file (`str`, `bytes`, `os.PathLike` or file-like object): Either
@@ -3739,7 +3751,9 @@ cdef class HMMPressedFile:
         self._hfp = NULL
 
     def __init__(self, object file):
-        """Create a new pressed file from the given filename.
+        """__init__(self, file)\n--\n
+        
+        Create a new pressed file from the given filename.
 
         Arguments:
             file (`str`, `bytes` or `os.PathLike`): The path to the pressed
@@ -3949,6 +3963,8 @@ cdef class IterativeSearch:
         DigitalSequenceBlock targets,
         object select_hits = None,
     ):
+        """__init__(self, pipeline, builder, query, targets, select_hits=None)\n--\n
+        """
         self.pipeline = pipeline
         self.background = pipeline.background
         self.builder = builder
@@ -4051,7 +4067,9 @@ cdef class OptimizedProfile:
         self.alphabet = None
 
     def __init__(self, int M, Alphabet alphabet):
-        """Create a new optimized profile from scratch.
+        """__init__(self, M, alphabet)\n--\n
+        
+        Create a new optimized profile from scratch.
 
         Once allocated, you must call the `~OptimizedProfile.convert`
         method with a `~plan7.Profile` object. It's actually easier to
@@ -4644,6 +4662,11 @@ cdef class OptimizedProfileBlock:
         self.alphabet = alphabet
 
     def __init__(self, Alphabet alphabet, object iterable = ()):
+        """__init__(self, alphabet, iterable=())\n--\n
+
+        Create a new block from an iterable of `OptimizedProfile` objects.
+
+        """
         if self._block == NULL:
             self._block = p7_oprofile_CreateBlock(8)
             if self._block == NULL:
@@ -4894,6 +4917,8 @@ cdef class Offsets:
         self._offs  = NULL
 
     def __init__(self, object owner):
+        """__init__(self, owner)\n--\n
+        """
         cdef str ty
 
         if isinstance(owner, Profile):
@@ -5034,7 +5059,9 @@ cdef class Pipeline:
         object incdomT=None,
         str bit_cutoffs=None,
     ):
-        """Instantiate and configure a new accelerated comparison pipeline.
+        """__init__(self, alphabet, background=None, *, bias_filter=True, null2=True, seed=42, Z=None, domZ=None, F1=0.02, F2=1e-3, F3=1e-5, E=10.0, T=None, domE=10.0, domT=None, incE=0.01, incT=None, incdomE=0.01, incdomT=None, bit_cutoffs=None)\n--\n
+        
+        Instantiate and configure a new accelerated comparison pipeline.
 
         Arguments:
             alphabet (`~pyhmmer.easel.Alphabet`): The biological alphabet the
@@ -6509,7 +6536,9 @@ cdef class LongTargetsPipeline(Pipeline):
         object window_beta=None,
         **kwargs,
     ):
-        """Instantiate and configure a new long targets pipeline.
+        """__init__(self, alphabet, background=None, *, F1=0.02, F2=3e-3, F3=3e-5, strand=None, B1=100, B2=240, B3=1000, block_length=0x40000, window_length=None, window_beta=None, **kwargs)\n--\n
+        
+        Instantiate and configure a new long targets pipeline.
 
         Arguments:
             alphabet (`~pyhmmer.easel.Alphabet`): The biological alphabet the
@@ -7282,7 +7311,9 @@ cdef class Profile:
         self.alphabet = None
 
     def __init__(self, int M, Alphabet alphabet):
-        """Create a new profile for the given ``alphabet``.
+        """__init__(self, M, alphabet)\n--\n
+        
+        Create a new profile for the given ``alphabet``.
 
         Arguments:
             M (`int`): The length of the profile, i.e. the number of nodes.
@@ -7582,7 +7613,8 @@ cdef class ScoreData:
         self._sd = NULL
 
     def __init__(self, OptimizedProfile om, Profile gm = None):
-
+        """__init__(self, om, gm=None)\n--\n
+        """
         cdef P7_PROFILE*  _gm = NULL if gm is None else gm._gm
         cdef P7_OPROFILE* _om = om._om
 
@@ -7646,7 +7678,10 @@ cdef class TopHits:
         memset(&self._pli, 0, sizeof(P7_PIPELINE))
 
     def __init__(self):
-        """Create an empty `TopHits` instance.
+        """__init__(self)\n--\n
+        
+        Create an empty `TopHits` instance.
+        
         """
         with nogil:
             # free allocated memory (in case __init__ is called more than once)
@@ -8592,7 +8627,9 @@ cdef class Trace:
         self.traces = None
 
     def __init__(self, posteriors=False):
-        """Create a new `Trace` object.
+        """__init__(self, posteriors=False)\n--\n
+        
+        Create a new `Trace` object.
 
         Arguments:
             posteriors (`bool`): Whether or not to allocate additional memory
@@ -8714,6 +8751,14 @@ cdef class Traces:
     def __dealloc__(self):
         libhmmer.p7_trace.p7_trace_DestroyArray(self._traces, self._ntraces)
 
+    def __init__(self):
+        """__init__(self)\n--\n
+
+        Create an empty list of traces.
+
+        """
+        pass
+
     def __len__(self):
         return self._ntraces
 
-- 
GitLab