def child(kind):
        import warnings
        warnings.filterwarnings("error", category=RuntimeWarning)
        warnings.filterwarnings("error", category=UserWarning)

        try:
            TestTerminal(kind=kind, force_styling=True)
        except UserWarning:
            err = sys.exc_info()[1]
            assert (err.args[0] == BINTERM_UNSUPPORTED_MSG.format(kind) or
                    err.args[0].startswith('Unknown parameter in ') or
                    err.args[0].startswith('Failed to setupterm(')
                    ), err
        else:
            assert 'warnings should have been emitted.'
        warnings.resetwarnings()
def test_unit_binpacked_unittest():
    """Unit Test known binary-packed terminals emit a warning (travis-safe)."""
    import warnings
    from blessed._binterms import BINTERM_UNSUPPORTED_MSG
    from blessed.sequences import init_sequence_patterns
    warnings.filterwarnings("error", category=UserWarning)
    term = mock.Mock()
    term.kind = 'tek4207-s'

    try:
        init_sequence_patterns(term)
    except UserWarning:
        err = sys.exc_info()[1]
        assert err.args[0] == BINTERM_UNSUPPORTED_MSG.format(term.kind)
    else:
        assert False, 'Previous stmt should have raised exception.'
    warnings.resetwarnings()
Example #3
0
def init_sequence_patterns(term):
    """
    Build database of regular expressions of terminal sequences.

    Given a Terminal instance, ``term``, this function processes
    and parses several known terminal capabilities, and builds and
    returns a dictionary database of regular expressions, which is
    re-attached to the terminal by attributes of the same key-name.

    :arg blessed.Terminal term: :class:`~.Terminal` instance.
    :rtype: dict
    :returns: dictionary containing mappings of sequence "groups",
        containing a compiled regular expression which it matches:

        - ``_re_will_move``

          Any sequence matching this pattern will cause the terminal
          cursor to move (such as *term.home*).

        - ``_re_wont_move``

          Any sequence matching this pattern will not cause the cursor
          to move (such as *term.bold*).

        - ``_re_cuf``

          Regular expression that matches term.cuf(N) (move N characters
          forward), or None if temrinal is without cuf sequence.

        - ``_cuf1``

          *term.cuf1* sequence (cursor forward 1 character) as a static value.

        - ``_re_cub``

          Regular expression that matches term.cub(N) (move N characters
          backward), or None if terminal is without cub sequence.

        - ``_cub1``

          *term.cuf1* sequence (cursor backward 1 character) as a static value.

    These attributes make it possible to perform introspection on strings
    containing sequences generated by this terminal, to determine the
    printable length of a string.
    """
    if term.kind in BINARY_TERMINALS:
        warnings.warn(BINTERM_UNSUPPORTED_MSG.format(term.kind))

    # Build will_move, a list of terminal capabilities that have
    # indeterminate effects on the terminal cursor position.
    _will_move = set()
    if term.does_styling:
        _will_move = _sort_sequences(get_movement_sequence_patterns(term))

    # Build wont_move, a list of terminal capabilities that mainly affect
    # video attributes, for use with measure_length().
    _wont_move = set()
    if term.does_styling:
        _wont_move = _sort_sequences(get_wontmove_sequence_patterns(term))
        _wont_move += [
            # some last-ditch match efforts; well, xterm and aixterm is going
            # to throw \x1b(B and other oddities all around, so, when given
            # input such as ansi art (see test using wall.ans), and well,
            # there is no reason a vt220 terminal shouldn't be able to
            # recognize blue_on_red, even if it didn't cause it to be
            # generated.  These are final "ok, i will match this, anyway" for
            # basic SGR sequences.
            re.escape(u'\x1b') + r'\[(\d+)\;(\d+)\;(\d+)\;(\d+)m',
            re.escape(u'\x1b') + r'\[(\d+)\;(\d+)\;(\d+)m',
            re.escape(u'\x1b') + r'\[(\d+)\;(\d+)m',
            re.escape(u'\x1b') + r'\[(\d+)?m',
            re.escape(u'\x1b(B'),
        ]

    # compile as regular expressions, OR'd.
    _re_will_move = re.compile(u'({0})'.format(u'|'.join(_will_move)))
    _re_wont_move = re.compile(u'({0})'.format(u'|'.join(_wont_move)))

    # static pattern matching for horizontal_distance(ucs, term)
    bnc = functools.partial(_build_numeric_capability, term)

    # parm_right_cursor: Move #1 characters to the right
    _cuf = bnc(cap='cuf', optional=True)
    _re_cuf = re.compile(_cuf) if _cuf else None

    # cursor_right: Non-destructive space (move right one space)
    _cuf1 = term.cuf1

    # parm_left_cursor: Move #1 characters to the left
    _cub = bnc(cap='cub', optional=True)
    _re_cub = re.compile(_cub) if _cub else None

    # cursor_left: Move left one space
    _cub1 = term.cub1

    return {'_re_will_move': _re_will_move,
            '_re_wont_move': _re_wont_move,
            '_re_cuf': _re_cuf,
            '_re_cub': _re_cub,
            '_cuf1': _cuf1,
            '_cub1': _cub1, }