<commit_before>from nipype.interfaces.base import (traits, Undefined, isdefined)
from nipype.interfaces.io import (IOBase, add_traits)
from nipype.interfaces.utility import IdentityInterface
from .interface_error import InterfaceError


class Gate(IOBase):
    """
    The Gate interface class is a copy of the Nipype IdentityInterface.
    Since Nipype elides IdentityInterface nodes from the execution graph,
    IdentityInterface cannot be used to constrain execution order, as in
    the example below. Gate is an IdentityInterface look-alike that
    preserves the node connection in the execution graph.

    Example::

        from qipipe.interfaces import Gate
        gate = Node(Gate(fields'['a', 'b']))
        workflow.connect(upstream1, 'a', gate, 'a')
        workflow.connect(upstream2, 'b', gate, 'b')
        workflow.connect(gate, 'a', downstream, 'a')

    In this example, the ``gate`` node starts after both ``upstream1`` and
    ``upstream2`` finish. Consequently, the ``downstream`` node starts only
    after ``upstream2`` finishes. This execution precedence constraint does
    not hold if gate were an IdentityInterface.
    """
    input_spec = IdentityInterface.input_spec
    output_spec = IdentityInterface.output_spec

    def __init__(self, fields=None, mandatory_inputs=True, **inputs):
        super(Gate, self).__init__(**inputs)
        if fields is None or not fields:
            raise InterfaceError('Gate fields must be a non-empty list')
        # Each input must be in the fields.<commit_msg>Add an improvement note.<commit_after>from nipype.interfaces.base import (traits, Undefined, isdefined)
from nipype.interfaces.io import (IOBase, add_traits)
from nipype.interfaces.utility import IdentityInterface
from .interface_error import InterfaceError


class Gate(IOBase):
    """
    The Gate interface class is a copy of the Nipype IdentityInterface.
    Since Nipype elides IdentityInterface nodes from the execution graph,
    IdentityInterface cannot be used to constrain execution order, as in
    the example below. Gate is an IdentityInterface look-alike that
    preserves the node connection in the execution graph.

    Example::

        from qipipe.interfaces import Gate
        gate = Node(Gate(fields'['a', 'b']))
        workflow.connect(upstream1, 'a', gate, 'a')
        workflow.connect(upstream2, 'b', gate, 'b')
        workflow.connect(gate, 'a', downstream, 'a')

    In this example, the ``gate`` node starts after both ``upstream1`` and
    ``upstream2`` finish. Consequently, the ``downstream`` node starts only
    after ``upstream2`` finishes. This execution precedence constraint does
    not hold if gate were an IdentityInterface.
    
    :Note: a better solution is to set a *preserve* flag on
        IdentityInterface. If this solution is implemented by Nipype,
        then this :class:`Gate` class will be deprecated.
    """
    input_spec = IdentityInterface.input_spec
    output_spec = IdentityInterface.output_spec

    def __init__(self, fields=None, mandatory_inputs=True, **inputs):
        super(Gate, self).__init__(**inputs)
        if fields is None or not fields:
            raise InterfaceError('Gate fields must be a non-empty list')
        # Each input must be in the fields.
{'fraction_non_alphanumeric': 0.08496332518337409, 'fraction_numerical': 0.003056234718826406, 'mean_word_length': 3.6228813559322033, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5777666', 'n_tokens_mistral': 891, 'n_tokens_neox': 860, 'n_words': 340}