Hello community,

here is the log from the commit of package python3-pyte for openSUSE:Factory 
checked in at 2016-03-17 16:35:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python3-pyte (Old)
 and      /work/SRC/openSUSE:Factory/.python3-pyte.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python3-pyte"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python3-pyte/python3-pyte.changes        
2016-02-01 19:57:16.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python3-pyte.new/python3-pyte.changes   
2016-03-17 16:48:20.000000000 +0100
@@ -1,0 +2,9 @@
+Tue Mar 15 04:41:36 UTC 2016 - [email protected]
+
+- specfile:
+  * added python3-pytest-runner
+
+- update to version 0.5.2:
+  * Fixed a bug in handling DA request. See issue #46 on GitHub.
+
+-------------------------------------------------------------------

Old:
----
  pyte-0.5.1.tar.gz

New:
----
  pyte-0.5.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python3-pyte.spec ++++++
--- /var/tmp/diff_new_pack.Nv8vrR/_old  2016-03-17 16:48:20.000000000 +0100
+++ /var/tmp/diff_new_pack.Nv8vrR/_new  2016-03-17 16:48:20.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           python3-pyte
-Version:        0.5.1
+Version:        0.5.2
 Release:        0
 Summary:        Simple VTXXX-compatible linux terminal emulator
 License:        LGPL-3.0
@@ -26,6 +26,7 @@
 Source:         
https://pypi.python.org/packages/source/p/pyte/pyte-%{version}.tar.gz
 BuildRequires:  python3-devel
 BuildRequires:  python3-pytest
+BuildRequires:  python3-pytest-runner
 BuildRequires:  python3-setuptools
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildArch:      noarch

++++++ pyte-0.5.1.tar.gz -> pyte-0.5.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/CHANGES new/pyte-0.5.2/CHANGES
--- old/pyte-0.5.1/CHANGES      2016-01-10 20:44:45.000000000 +0100
+++ new/pyte-0.5.2/CHANGES      2016-03-14 20:48:50.000000000 +0100
@@ -3,12 +3,19 @@
 
 Here you can see the full list of changes between each pyte release.
 
+Version 0.5.2
+-------------
+
+Pi Day bugfix release, released on March 14th, 2016
+
+- Fixed a bug in handling DA request. See issue #46 on GitHub.
+
 Version 0.5.1
 -------------
 
 Bugfix release, released on January 10th 2015
 
-- Fixed dependencies in ``setup.py``.
+- Fixed dependencies in setup.py.
 
 Version 0.5.0
 -------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/PKG-INFO new/pyte-0.5.2/PKG-INFO
--- old/pyte-0.5.1/PKG-INFO     2016-01-10 20:45:41.000000000 +0100
+++ new/pyte-0.5.2/PKG-INFO     2016-03-14 20:53:20.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pyte
-Version: 0.5.1
+Version: 0.5.2
 Summary: Simple VTXXX-compatible terminal emulator.
 Home-page: https://github.com/selectel/pyte
 Author: Sergei Lebedev
@@ -17,7 +17,7 @@
                 | |_) || |_| || |_|  __/
                 | .__/  \__, | \__|\___|
                 | |      __/ |
-                |_|     |___/      0.5.1
+                |_|     |___/      0.5.2
         
         
         What is ``pyte``?
@@ -68,7 +68,7 @@
 Classifier: Environment :: Console
 Classifier: Intended Audience :: Developers
 Classifier: Operating System :: OS Independent
-Classifier: License :: OSI Approved :: GNU Library or Lesser General Public 
License (LGPL)
+Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 
(LGPLv3)
 Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/README new/pyte-0.5.2/README
--- old/pyte-0.5.1/README       2016-01-10 20:45:14.000000000 +0100
+++ new/pyte-0.5.2/README       2016-03-14 20:49:43.000000000 +0100
@@ -9,7 +9,7 @@
         | |_) || |_| || |_|  __/
         | .__/  \__, | \__|\___|
         | |      __/ |
-        |_|     |___/      0.5.1
+        |_|     |___/      0.5.2
 
 
 What is ``pyte``?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/docs/conf.py new/pyte-0.5.2/docs/conf.py
--- old/pyte-0.5.1/docs/conf.py 2016-01-10 20:45:00.000000000 +0100
+++ new/pyte-0.5.2/docs/conf.py 2016-03-14 20:49:12.000000000 +0100
@@ -52,9 +52,9 @@
 # built documents.
 #
 # The short X.Y version.
-version = '0.5.1'
+version = '0.5.2'
 # The full version, including alpha/beta/rc tags.
-release = '0.5.1'
+release = '0.5.2'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/docs/index.rst 
new/pyte-0.5.2/docs/index.rst
--- old/pyte-0.5.1/docs/index.rst       2016-01-10 17:43:45.000000000 +0100
+++ new/pyte-0.5.2/docs/index.rst       2016-03-14 12:23:17.000000000 +0100
@@ -20,7 +20,7 @@
 
 Head over to our brief :ref:`tutorial` or, if you're feeling brave, dive right
 into the :ref:`api`; ``pyte`` also has a couple of examples in the
-`examples <https://github.com/selectel/examples>`_ directory.
+`examples <https://github.com/selectel/pyte/tree/master/examples>`_ directory.
 
 
 .. toctree::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/docs/tutorial.rst 
new/pyte-0.5.2/docs/tutorial.rst
--- old/pyte-0.5.1/docs/tutorial.rst    2016-01-10 17:27:24.000000000 +0100
+++ new/pyte-0.5.2/docs/tutorial.rst    2016-03-14 12:23:17.000000000 +0100
@@ -14,7 +14,7 @@
 In general, if you just want to know what's being displayed on screen you
 can do something like the following:
 
-    >>> fromm __future__ import unicode_literals
+    >>> from __future__ import unicode_literals
     >>> import pyte
     >>> screen = pyte.Screen(80, 24)
     >>> stream = pyte.Stream()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/examples/inception.py 
new/pyte-0.5.2/examples/inception.py
--- old/pyte-0.5.1/examples/inception.py        2016-01-10 04:12:20.000000000 
+0100
+++ new/pyte-0.5.2/examples/inception.py        2016-03-14 12:23:17.000000000 
+0100
@@ -25,7 +25,7 @@
 
 
 def print_screen(screen, text):
-    print(pyte.ctrl.ESC + pyte.esc.RIS)
+    print(pyte.control.ESC + pyte.escape.RIS)
 
     for idx, line in enumerate(screen.display, 1):
         print("{0:2d} {1} ΒΆ".format(idx, line))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/pyte/screens.py 
new/pyte-0.5.2/pyte/screens.py
--- old/pyte-0.5.1/pyte/screens.py      2016-01-10 11:56:38.000000000 +0100
+++ new/pyte-0.5.2/pyte/screens.py      2016-03-14 12:23:17.000000000 +0100
@@ -864,14 +864,15 @@
 
         self.cursor.attrs = self.cursor.attrs._replace(**replace)
 
-    def report_device_attributes(self):
+    def report_device_attributes(self, mode=0, **kwargs):
         """Reports terminal identity.
 
         .. versionadded:: 0.5.0
         """
         # We only implement "primary" DA which is the only DA request
         # VT102 understood, see ``VT102ID`` in ``linux/drivers/tty/vt.c``.
-        self.write_process_input(ctrl.CSI + "?6c")
+        if mode == 0:
+            self.write_process_input(ctrl.CSI + "?6c")
 
     def report_device_status(self, mode):
         """Reports terminal status or cursor position.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/pyte/streams.py 
new/pyte-0.5.2/pyte/streams.py
--- old/pyte-0.5.1/pyte/streams.py      2016-01-10 17:20:49.000000000 +0100
+++ new/pyte-0.5.2/pyte/streams.py      2016-03-14 12:23:17.000000000 +0100
@@ -148,7 +148,7 @@
            Use :meth:`feed` instead.
         """
         warnings.warn(".consume is deprecated and will be removed in "
-                      "pyte 0.5.1. Please use .feed instead.",
+                      "pyte 0.5.2. Please use .feed instead.",
                       category=DeprecationWarning)
         return self.feed(char)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/pyte.egg-info/PKG-INFO 
new/pyte-0.5.2/pyte.egg-info/PKG-INFO
--- old/pyte-0.5.1/pyte.egg-info/PKG-INFO       2016-01-10 20:45:41.000000000 
+0100
+++ new/pyte-0.5.2/pyte.egg-info/PKG-INFO       2016-03-14 20:53:20.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pyte
-Version: 0.5.1
+Version: 0.5.2
 Summary: Simple VTXXX-compatible terminal emulator.
 Home-page: https://github.com/selectel/pyte
 Author: Sergei Lebedev
@@ -17,7 +17,7 @@
                 | |_) || |_| || |_|  __/
                 | .__/  \__, | \__|\___|
                 | |      __/ |
-                |_|     |___/      0.5.1
+                |_|     |___/      0.5.2
         
         
         What is ``pyte``?
@@ -68,7 +68,7 @@
 Classifier: Environment :: Console
 Classifier: Intended Audience :: Developers
 Classifier: Operating System :: OS Independent
-Classifier: License :: OSI Approved :: GNU Library or Lesser General Public 
License (LGPL)
+Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 
(LGPLv3)
 Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/pyte.egg-info/SOURCES.txt 
new/pyte-0.5.2/pyte.egg-info/SOURCES.txt
--- old/pyte-0.5.1/pyte.egg-info/SOURCES.txt    2016-01-10 20:45:41.000000000 
+0100
+++ new/pyte-0.5.2/pyte.egg-info/SOURCES.txt    2016-03-14 20:53:20.000000000 
+0100
@@ -3,6 +3,7 @@
 LICENSE
 MANIFEST.in
 README
+setup.cfg
 setup.py
 docs/api.rst
 docs/changelog.rst
@@ -29,7 +30,6 @@
 pyte.egg-info/requires.txt
 pyte.egg-info/top_level.txt
 tests/__init__.py
-tests/test_benchmarks.py
 tests/test_diff.py
 tests/test_history.py
 tests/test_screen.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/setup.cfg new/pyte-0.5.2/setup.cfg
--- old/pyte-0.5.1/setup.cfg    2016-01-10 20:45:41.000000000 +0100
+++ new/pyte-0.5.2/setup.cfg    2016-03-14 20:53:20.000000000 +0100
@@ -1,5 +1,8 @@
+[aliases]
+test = pytest
+
 [egg_info]
-tag_build = 
-tag_date = 0
 tag_svn_revision = 0
+tag_date = 0
+tag_build = 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/setup.py new/pyte-0.5.2/setup.py
--- old/pyte-0.5.1/setup.py     2016-01-10 20:44:33.000000000 +0100
+++ new/pyte-0.5.2/setup.py     2016-03-14 20:49:24.000000000 +0100
@@ -2,10 +2,8 @@
 # -*- coding: utf-8 -*-
 
 import os
-import sys
 
 from setuptools import setup
-from setuptools.command.test import test as TestCommand
 
 
 here = os.path.abspath(os.path.dirname(__file__))
@@ -23,7 +21,7 @@
     "Environment :: Console",
     "Intended Audience :: Developers",
     "Operating System :: OS Independent",
-    "License :: OSI Approved :: GNU Library or Lesser General Public License 
(LGPL)",
+    "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
     "Programming Language :: Python :: 2.6",
     "Programming Language :: Python :: 2.7",
     "Programming Language :: Python :: 3.4",
@@ -32,26 +30,11 @@
 ]
 
 
-class PyTest(TestCommand):
-    """Unfortunately :mod:`setuptools` support only :mod:`unittest`
-    based tests, thus, we have to overider build-in ``test`` command
-    to run :mod:`pytest`.
-    """
-    def finalize_options(self):
-        TestCommand.finalize_options(self)
-        self.test_args = []
-        self.test_suite = True
-
-    def run_tests(self):
-        import pytest
-        sys.exit(pytest.main(self.test_args + ["./tests"]))
-
-
 setup(name="pyte",
-      version="0.5.1",
+      version="0.5.2",
       packages=["pyte"],
       install_requires=["wcwidth"],
-      cmdclass={"test": PyTest},
+      setup_requires=["pytest-runner"],
       tests_require=["pytest"],
       platforms=["any"],
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/tests/test_benchmarks.py 
new/pyte-0.5.2/tests/test_benchmarks.py
--- old/pyte-0.5.1/tests/test_benchmarks.py     2016-01-10 11:48:32.000000000 
+0100
+++ new/pyte-0.5.2/tests/test_benchmarks.py     1970-01-01 01:00:00.000000000 
+0100
@@ -1,815 +0,0 @@
-import subprocess
-import sys
-import time
-
-import pytest
-
-from pyte import control as ctrl, escape as esc, Stream
-from pyte.screens import *
-
-
-class VanillaScreen(object):
-    """
-    A screen is an in-memory matrix of characters that represents the
-    screen display of the terminal. It can be instantiated on it's own
-    and given explicit commands, or it can be attached to a stream and
-    will respond to events.
-
-    .. attribute:: buffer
-
-       A ``lines x columns`` :class:`~pyte.screens.Char` matrix.
-
-    .. attribute:: cursor
-
-       Reference to the :class:`~pyte.screens.Cursor` object, holding
-       cursor position and attributes.
-
-    .. attribute:: margins
-
-       Top and bottom screen margins, defining the scrolling region;
-       the actual values are top and bottom line.
-
-    .. attribute:: charset
-
-       Current charset number; can be either ``0`` or ``1`` for `G0`
-       and `G1` respectively, note that `G0` is activated by default.
-
-    .. note::
-
-       According to ``ECMA-48`` standard, **lines and columnns are
-       1-indexed**, so, for instance ``ESC [ 10;10 f`` really means
-       -- move cursor to position (9, 9) in the display matrix.
-
-    .. versionchanged:: 0.4.7
-    .. warning::
-
-       :data:`~pyte.modes.LNM` is reset by default, to match VT220
-       specification.
-
-    .. versionchanged:: 0.4.8
-    .. warning::
-
-       If `DECAWM` mode is set than a cursor will be wrapped to the
-       **beginning** of the next line, which is the behaviour described
-       in ``man console_codes``.
-
-    .. seealso::
-
-       `Standard ECMA-48, Section 6.1.1 \
-       
<http://www.ecma-international.org/publications/standards/Ecma-048.htm>`_
-       for a description of the presentational component, implemented
-       by ``Screen``.
-    """
-    #: A plain empty character with default foreground and background
-    #: colors.
-    default_char = Char(data=" ", fg="default", bg="default")
-
-    #: An inifinite sequence of default characters, used for populating
-    #: new lines and columns.
-    default_line = repeat(default_char)
-
-    def __init__(self, columns, lines):
-        self.savepoints = []
-        self.columns = columns
-        self.lines = lines
-        self.buffer = []
-        self.reset()
-
-    def __repr__(self):
-        return ("{0}({1}, {2})".format(self.__class__.__name__,
-                                       self.columns, self.lines))
-
-    def __before__(self, command):
-        """Hook, called **before** a command is dispatched to the
-        :class:`Screen` instance.
-
-        :param str command: command name, for example ``"LINEFEED"``.
-        """
-
-    def __after__(self, command):
-        """Hook, called **after** a command is dispatched to the
-        :class:`Screen` instance.
-
-        :param str command: command name, for example ``"LINEFEED"``.
-        """
-
-    @property
-    def display(self):
-        """Returns a :func:`list` of screen lines as unicode strings."""
-        return ["".join(map(operator.attrgetter("data"), line))
-                for line in self.buffer]
-
-    def reset(self):
-        """Resets the terminal to its initial state.
-
-        * Scroll margins are reset to screen boundaries.
-        * Cursor is moved to home location -- ``(0, 0)`` and its
-          attributes are set to defaults (see :attr:`default_char`).
-        * Screen is cleared -- each character is reset to
-          :attr:`default_char`.
-        * Tabstops are reset to "every eight columns".
-
-        .. note::
-
-           Neither VT220 nor VT102 manuals mentioned that terminal modes
-           and tabstops should be reset as well, thanks to
-           :manpage:`xterm` -- we now know that.
-        """
-        self.buffer[:] = (take(self.columns, self.default_line)
-                          for _ in range(self.lines))
-        self.mode = set([mo.DECAWM, mo.DECTCEM])
-        self.margins = Margins(0, self.lines - 1)
-
-        # According to VT220 manual and ``linux/drivers/tty/vt.c``
-        # the default G0 charset is latin-1, but for reasons unknown
-        # latin-1 breaks ascii-graphics; so G0 defaults to cp437.
-        self.charset = 0
-        self.g0_charset = cs.IBMPC_MAP
-        self.g1_charset = cs.VT100_MAP
-
-        # From ``man terminfo`` -- "... hardware tabs are initially
-        # set every `n` spaces when the terminal is powered up. Since
-        # we aim to support VT102 / VT220 and linux -- we use n = 8.
-        self.tabstops = set(range(7, self.columns, 8))
-
-        self.cursor = Cursor(0, 0)
-        self.cursor_position()
-
-    def resize(self, lines=None, columns=None):
-        """Resize the screen to the given dimensions.
-
-        If the requested screen size has more lines than the existing
-        screen, lines will be added at the bottom. If the requested
-        size has less lines than the existing screen lines will be
-        clipped at the top of the screen. Similarly, if the existing
-        screen has less columns than the requested screen, columns will
-        be added at the right, and if it has more -- columns will be
-        clipped at the right.
-
-        .. note:: According to `xterm`, we should also reset origin
-                  mode and screen margins, see ``xterm/screen.c:1761``.
-
-        :param int lines: number of lines in the new screen.
-        :param int columns: number of columns in the new screen.
-        """
-        lines = lines or self.lines
-        columns = columns or self.columns
-
-        # First resize the lines:
-        diff = self.lines - lines
-
-        # a) if the current display size is less than the requested
-        #    size, add lines to the bottom.
-        if diff < 0:
-            self.buffer.extend(take(self.columns, self.default_line)
-                               for _ in range(diff, 0))
-        # b) if the current display size is greater than requested
-        #    size, take lines off the top.
-        elif diff > 0:
-            self.buffer[:diff] = ()
-
-        # Then resize the columns:
-        diff = self.columns - columns
-
-        # a) if the current display size is less than the requested
-        #    size, expand each line to the new size.
-        if diff < 0:
-            for y in range(lines):
-                self.buffer[y].extend(take(abs(diff), self.default_line))
-        # b) if the current display size is greater than requested
-        #    size, trim each line from the right to the new size.
-        elif diff > 0:
-            for line in self.buffer:
-                del line[columns:]
-
-        self.lines, self.columns = lines, columns
-        self.margins = Margins(0, self.lines - 1)
-        self.reset_mode(mo.DECOM)
-
-    def set_margins(self, top=None, bottom=None):
-        """Selects top and bottom margins for the scrolling region.
-
-        Margins determine which screen lines move during scrolling
-        (see :meth:`index` and :meth:`reverse_index`). Characters added
-        outside the scrolling region do not cause the screen to scroll.
-
-        :param int top: the smallest line number that is scrolled.
-        :param int bottom: the biggest line number that is scrolled.
-        """
-        if top is None or bottom is None:
-            return
-
-        # Arguments are 1-based, while :attr:`margins` are zero based --
-        # so we have to decrement them by one. We also make sure that
-        # both of them is bounded by [0, lines - 1].
-        top = max(0, min(top - 1, self.lines - 1))
-        bottom = max(0, min(bottom - 1, self.lines - 1))
-
-        # Even though VT102 and VT220 require DECSTBM to ignore regions
-        # of width less than 2, some programs (like aptitude for example)
-        # rely on it. Practicality beats purity.
-        if bottom - top >= 1:
-            self.margins = Margins(top, bottom)
-
-            # The cursor moves to the home position when the top and
-            # bottom margins of the scrolling region (DECSTBM) changes.
-            self.cursor_position()
-
-    def set_charset(self, code, mode):
-        """Set active ``G0`` or ``G1`` charset.
-
-        :param str code: character set code, should be a character
-                         from ``"B0UK"`` -- otherwise ignored.
-        :param str mode: if ``"("`` ``G0`` charset is set, if
-                         ``")"`` -- we operate on ``G1``.
-
-        .. warning:: User-defined charsets are currently not supported.
-        """
-        if code in cs.MAPS:
-            setattr(self, {"(": "g0_charset", ")": "g1_charset"}[mode],
-                    cs.MAPS[code])
-
-    def set_mode(self, *modes, **kwargs):
-        """Sets (enables) a given list of modes.
-
-        :param list modes: modes to set, where each mode is a constant
-                           from :mod:`pyte.modes`.
-        """
-        # Private mode codes are shifted, to be distingiushed from non
-        # private ones.
-        if kwargs.get("private"):
-            modes = [mode << 5 for mode in modes]
-
-        self.mode.update(modes)
-
-        # When DECOLM mode is set, the screen is erased and the cursor
-        # moves to the home position.
-        if mo.DECCOLM in modes:
-            self.resize(columns=132)
-            self.erase_in_display(2)
-            self.cursor_position()
-
-        # According to `vttest`, DECOM should also home the cursor, see
-        # vttest/main.c:303.
-        if mo.DECOM in modes:
-            self.cursor_position()
-
-        # Mark all displayed characters as reverse.
-        if mo.DECSCNM in modes:
-            self.buffer[:] = ([char._replace(reverse=True) for char in line]
-                              for line in self.buffer)
-            self.select_graphic_rendition(g._SGR["+reverse"])
-
-        # Make the cursor visible.
-        if mo.DECTCEM in modes:
-            self.cursor.hidden = False
-
-    def reset_mode(self, *modes, **kwargs):
-        """Resets (disables) a given list of modes.
-
-        :param list modes: modes to reset -- hopefully, each mode is a
-                           constant from :mod:`pyte.modes`.
-        """
-        # Private mode codes are shifted, to be distingiushed from non
-        # private ones.
-        if kwargs.get("private"):
-            modes = [mode << 5 for mode in modes]
-
-        self.mode.difference_update(modes)
-
-        # Lines below follow the logic in :meth:`set_mode`.
-        if mo.DECCOLM in modes:
-            self.resize(columns=80)
-            self.erase_in_display(2)
-            self.cursor_position()
-
-        if mo.DECOM in modes:
-            self.cursor_position()
-
-        if mo.DECSCNM in modes:
-            self.buffer[:] = ([char._replace(reverse=False) for char in line]
-                              for line in self.buffer)
-            self.select_graphic_rendition(g._SGR["-reverse"])
-
-        # Hide the cursor.
-        if mo.DECTCEM in modes:
-            self.cursor.hidden = True
-
-    def shift_in(self):
-        """Activates ``G0`` character set."""
-        self.charset = 0
-
-    def shift_out(self):
-        """Activates ``G1`` character set."""
-        self.charset = 1
-
-    def draw(self, char):
-        """Display a character at the current cursor position and advance
-        the cursor if :data:`~pyte.modes.DECAWM` is set.
-
-        :param str char: a character to display.
-
-        .. versionchanged:: 0.5.0
-
-           Character width is taken into account. Specifically, zero-width
-           and unprintable characters do not affect screen state. Full-width
-           characters are rendered into two consecutive character containers.
-        """
-        # Translating a given character.
-        if self.charset:
-            char = char.translate(self.g1_charset)
-        else:
-            char = char.translate(self.g0_charset)
-
-        char_width = wcwidth(char)
-        if char_width <= 0:
-            # Unprintable character or doesn't advance the cursor.
-            return
-
-        # If this was the last column in a line and auto wrap mode is
-        # enabled, move the cursor to the beginning of the next line,
-        # otherwise replace characters already displayed with newly
-        # entered.
-        if self.cursor.x == self.columns:
-            if mo.DECAWM in self.mode:
-                self.carriage_return()
-                self.linefeed()
-            else:
-                self.cursor.x -= char_width
-
-        # If Insert mode is set, new characters move old characters to
-        # the right, otherwise terminal is in Replace mode and new
-        # characters replace old characters at cursor position.
-        if mo.IRM in self.mode:
-            self.insert_characters(char_width)
-
-        line = self.buffer[self.cursor.y]
-        line[self.cursor.x] = self.cursor.attrs._replace(data=char)
-        if char_width > 1:
-            # Add a stub *after* a two-cell characters. See issue #9
-            # on GitHub.
-            line[self.cursor.x + 1] = self.cursor.attrs._replace(data=" ")
-
-        # .. note:: We can't use :meth:`cursor_forward()`, because that
-        #           way, we'll never know when to linefeed.
-        self.cursor.x += char_width
-
-    def carriage_return(self):
-        """Move the cursor to the beginning of the current line."""
-        self.cursor.x = 0
-
-    def index(self):
-        """Move the cursor down one line in the same column. If the
-        cursor is at the last line, create a new line at the bottom.
-        """
-        top, bottom = self.margins
-
-        if self.cursor.y == bottom:
-            self.buffer.pop(top)
-            self.buffer.insert(bottom, take(self.columns, self.default_line))
-        else:
-            self.cursor_down()
-
-    def reverse_index(self):
-        """Move the cursor up one line in the same column. If the cursor
-        is at the first line, create a new line at the top.
-        """
-        top, bottom = self.margins
-
-        if self.cursor.y == top:
-            self.buffer.pop(bottom)
-            self.buffer.insert(top, take(self.columns, self.default_line))
-        else:
-            self.cursor_up()
-
-    def linefeed(self):
-        """Performs an index and, if :data:`~pyte.modes.LNM` is set, a
-        carriage return.
-        """
-        self.index()
-
-        if mo.LNM in self.mode:
-            self.carriage_return()
-
-        self.ensure_bounds()
-
-    def tab(self):
-        """Move to the next tab space, or the end of the screen if there
-        aren't anymore left.
-        """
-        for stop in sorted(self.tabstops):
-            if self.cursor.x < stop:
-                column = stop
-                break
-        else:
-            column = self.columns - 1
-
-        self.cursor.x = column
-
-    def backspace(self):
-        """Move cursor to the left one or keep it in it's position if
-        it's at the beginning of the line already.
-        """
-        self.cursor_back()
-
-    def save_cursor(self):
-        """Push the current cursor position onto the stack."""
-        self.savepoints.append(Savepoint(copy.copy(self.cursor),
-                                         self.g0_charset,
-                                         self.g1_charset,
-                                         self.charset,
-                                         mo.DECOM in self.mode,
-                                         mo.DECAWM in self.mode))
-
-    def restore_cursor(self):
-        """Set the current cursor position to whatever cursor is on top
-        of the stack.
-        """
-        if self.savepoints:
-            savepoint = self.savepoints.pop()
-
-            self.g0_charset = savepoint.g0_charset
-            self.g1_charset = savepoint.g1_charset
-            self.charset = savepoint.charset
-
-            if savepoint.origin:
-                self.set_mode(mo.DECOM)
-            if savepoint.wrap:
-                self.set_mode(mo.DECAWM)
-
-            self.cursor = savepoint.cursor
-            self.ensure_bounds(use_margins=True)
-        else:
-            # If nothing was saved, the cursor moves to home position;
-            # origin mode is reset. :todo: DECAWM?
-            self.reset_mode(mo.DECOM)
-            self.cursor_position()
-
-    def insert_lines(self, count=None):
-        """Inserts the indicated # of lines at line with cursor. Lines
-        displayed **at** and below the cursor move down. Lines moved
-        past the bottom margin are lost.
-
-        :param count: number of lines to delete.
-        """
-        count = count or 1
-        top, bottom = self.margins
-
-        # If cursor is outside scrolling margins it -- do nothin'.
-        if top <= self.cursor.y <= bottom:
-            #                           v +1, because range() is exclusive.
-            for line in range(self.cursor.y,
-                              min(bottom + 1, self.cursor.y + count)):
-                self.buffer.pop(bottom)
-                self.buffer.insert(line, take(self.columns, self.default_line))
-
-            self.carriage_return()
-
-    def delete_lines(self, count=None):
-        """Deletes the indicated # of lines, starting at line with
-        cursor. As lines are deleted, lines displayed below cursor
-        move up. Lines added to bottom of screen have spaces with same
-        character attributes as last line moved up.
-
-        :param int count: number of lines to delete.
-        """
-        count = count or 1
-        top, bottom = self.margins
-
-        # If cursor is outside scrolling margins it -- do nothin'.
-        if top <= self.cursor.y <= bottom:
-            #                v -- +1 to include the bottom margin.
-            for _ in range(min(bottom - self.cursor.y + 1, count)):
-                self.buffer.pop(self.cursor.y)
-                self.buffer.insert(bottom, list(
-                    repeat(self.cursor.attrs, self.columns)))
-
-            self.carriage_return()
-
-    def insert_characters(self, count=None):
-        """Inserts the indicated # of blank characters at the cursor
-        position. The cursor does not move and remains at the beginning
-        of the inserted blank characters. Data on the line is shifted
-        forward.
-
-        :param int count: number of characters to insert.
-        """
-        count = count or 1
-
-        for _ in range(min(self.columns - self.cursor.y, count)):
-            self.buffer[self.cursor.y].insert(self.cursor.x, self.cursor.attrs)
-            self.buffer[self.cursor.y].pop()
-
-    def delete_characters(self, count=None):
-        """Deletes the indicated # of characters, starting with the
-        character at cursor position. When a character is deleted, all
-        characters to the right of cursor move left. Character attributes
-        move with the characters.
-
-        :param int count: number of characters to delete.
-        """
-        count = count or 1
-
-        for _ in range(min(self.columns - self.cursor.x, count)):
-            self.buffer[self.cursor.y].pop(self.cursor.x)
-            self.buffer[self.cursor.y].append(self.cursor.attrs)
-
-    def erase_characters(self, count=None):
-        """Erases the indicated # of characters, starting with the
-        character at cursor position. Character attributes are set
-        cursor attributes. The cursor remains in the same position.
-
-        :param int count: number of characters to erase.
-
-        .. warning::
-
-           Even though *ALL* of the VTXXX manuals state that character
-           attributes **should be reset to defaults**, ``libvte``,
-           ``xterm`` and ``ROTE`` completely ignore this. Same applies
-           too all ``erase_*()`` and ``delete_*()`` methods.
-        """
-        count = count or 1
-
-        for column in range(self.cursor.x,
-                            min(self.cursor.x + count, self.columns)):
-            self.buffer[self.cursor.y][column] = self.cursor.attrs
-
-    def erase_in_line(self, type_of=0, private=False):
-        """Erases a line in a specific way.
-
-        :param int type_of: defines the way the line should be erased in:
-
-            * ``0`` -- Erases from cursor to end of line, including cursor
-              position.
-            * ``1`` -- Erases from beginning of line to cursor,
-              including cursor position.
-            * ``2`` -- Erases complete line.
-        :param bool private: when ``True`` character attributes are left
-                             unchanged **not implemented**.
-        """
-        interval = (
-            # a) erase from the cursor to the end of line, including
-            # the cursor,
-            range(self.cursor.x, self.columns),
-            # b) erase from the beginning of the line to the cursor,
-            # including it,
-            range(0, self.cursor.x + 1),
-            # c) erase the entire line.
-            range(0, self.columns)
-        )[type_of]
-
-        for column in interval:
-            self.buffer[self.cursor.y][column] = self.cursor.attrs
-
-    def erase_in_display(self, type_of=0, private=False):
-        """Erases display in a specific way.
-
-        :param int type_of: defines the way the line should be erased in:
-
-            * ``0`` -- Erases from cursor to end of screen, including
-              cursor position.
-            * ``1`` -- Erases from beginning of screen to cursor,
-              including cursor position.
-            * ``2`` -- Erases complete display. All lines are erased
-              and changed to single-width. Cursor does not move.
-        :param bool private: when ``True`` character attributes are left
-                             unchanged **not implemented**.
-        """
-        interval = (
-            # a) erase from cursor to the end of the display, including
-            # the cursor,
-            range(self.cursor.y + 1, self.lines),
-            # b) erase from the beginning of the display to the cursor,
-            # including it,
-            range(0, self.cursor.y),
-            # c) erase the whole display.
-            range(0, self.lines)
-        )[type_of]
-
-        for line in interval:
-            self.buffer[line][:] = \
-                (self.cursor.attrs for _ in range(self.columns))
-
-        # In case of 0 or 1 we have to erase the line with the cursor.
-        if type_of in [0, 1]:
-            self.erase_in_line(type_of)
-
-    def set_tab_stop(self):
-        """Sest a horizontal tab stop at cursor position."""
-        self.tabstops.add(self.cursor.x)
-
-    def clear_tab_stop(self, type_of=None):
-        """Clears a horizontal tab stop in a specific way, depending
-        on the ``type_of`` value:
-
-        * ``0`` or nothing -- Clears a horizontal tab stop at cursor
-          position.
-        * ``3`` -- Clears all horizontal tab stops.
-        """
-        if not type_of:
-            # Clears a horizontal tab stop at cursor position, if it's
-            # present, or silently fails if otherwise.
-            self.tabstops.discard(self.cursor.x)
-        elif type_of == 3:
-            self.tabstops = set()  # Clears all horizontal tab stops.
-
-    def ensure_bounds(self, use_margins=None):
-        """Ensure that current cursor position is within screen bounds.
-
-        :param bool use_margins: when ``True`` or when
-                                 :data:`~pyte.modes.DECOM` is set,
-                                 cursor is bounded by top and and bottom
-                                 margins, instead of ``[0; lines - 1]``.
-        """
-        if use_margins or mo.DECOM in self.mode:
-            top, bottom = self.margins
-        else:
-            top, bottom = 0, self.lines - 1
-
-        self.cursor.x = min(max(0, self.cursor.x), self.columns - 1)
-        self.cursor.y = min(max(top, self.cursor.y), bottom)
-
-    def cursor_up(self, count=None):
-        """Moves cursor up the indicated # of lines in same column.
-        Cursor stops at top margin.
-
-        :param int count: number of lines to skip.
-        """
-        self.cursor.y -= count or 1
-        self.ensure_bounds(use_margins=True)
-
-    def cursor_up1(self, count=None):
-        """Moves cursor up the indicated # of lines to column 1. Cursor
-        stops at bottom margin.
-
-        :param int count: number of lines to skip.
-        """
-        self.cursor_up(count)
-        self.carriage_return()
-
-    def cursor_down(self, count=None):
-        """Moves cursor down the indicated # of lines in same column.
-        Cursor stops at bottom margin.
-
-        :param int count: number of lines to skip.
-        """
-        self.cursor.y += count or 1
-        self.ensure_bounds(use_margins=True)
-
-    def cursor_down1(self, count=None):
-        """Moves cursor down the indicated # of lines to column 1.
-        Cursor stops at bottom margin.
-
-        :param int count: number of lines to skip.
-        """
-        self.cursor_down(count)
-        self.carriage_return()
-
-    def cursor_back(self, count=None):
-        """Moves cursor left the indicated # of columns. Cursor stops
-        at left margin.
-
-        :param int count: number of columns to skip.
-        """
-        self.cursor.x -= count or 1
-        self.ensure_bounds()
-
-    def cursor_forward(self, count=None):
-        """Moves cursor right the indicated # of columns. Cursor stops
-        at right margin.
-
-        :param int count: number of columns to skip.
-        """
-        self.cursor.x += count or 1
-        self.ensure_bounds()
-
-    def cursor_position(self, line=None, column=None):
-        """Set the cursor to a specific `line` and `column`.
-
-        Cursor is allowed to move out of the scrolling region only when
-        :data:`~pyte.modes.DECOM` is reset, otherwise -- the position
-        doesn't change.
-
-        :param int line: line number to move the cursor to.
-        :param int column: column number to move the cursor to.
-        """
-        column = (column or 1) - 1
-        line = (line or 1) - 1
-
-        # If origin mode (DECOM) is set, line number are relative to
-        # the top scrolling margin.
-        if mo.DECOM in self.mode:
-            line += self.margins.top
-
-            # Cursor is not allowed to move out of the scrolling region.
-            if not self.margins.top <= line <= self.margins.bottom:
-                return
-
-        self.cursor.x, self.cursor.y = column, line
-        self.ensure_bounds()
-
-    def cursor_to_column(self, column=None):
-        """Moves cursor to a specific column in the current line.
-
-        :param int column: column number to move the cursor to.
-        """
-        self.cursor.x = (column or 1) - 1
-        self.ensure_bounds()
-
-    def cursor_to_line(self, line=None):
-        """Moves cursor to a specific line in the current column.
-
-        :param int line: line number to move the cursor to.
-        """
-        self.cursor.y = (line or 1) - 1
-
-        # If origin mode (DECOM) is set, line number are relative to
-        # the top scrolling margin.
-        if mo.DECOM in self.mode:
-            self.cursor.y += self.margins.top
-
-            # FIXME: should we also restrict the cursor to the scrolling
-            # region?
-
-        self.ensure_bounds()
-
-    def bell(self, *args):
-        """Bell stub -- the actual implementation should probably be
-        provided by the end-user.
-        """
-
-    def alignment_display(self):
-        """Fills screen with uppercase E's for screen focus and alignment."""
-        for line in self.buffer:
-            for column, char in enumerate(line):
-                line[column] = char._replace(data="E")
-
-    def select_graphic_rendition(self, *attrs):
-        """Set display attributes.
-
-        :param list attrs: a list of display attributes to set.
-        """
-        replace = {}
-
-        for attr in attrs or [0]:
-            if attr in g.FG:
-                replace["fg"] = g.FG[attr]
-            elif attr in g.BG:
-                replace["bg"] = g.BG[attr]
-            elif attr in g.TEXT:
-                attr = g.TEXT[attr]
-                replace[attr[1:]] = attr.startswith("+")
-            elif not attr:
-                replace = self.default_char._asdict()
-
-        self.cursor.attrs = self.cursor.attrs._replace(**replace)
-
-    def report_device_attributes(self):
-        """Reports terminal identity.
-
-        .. versionadded:: 0.5.0
-        """
-        # We only implement "primary" DA which is the only DA request
-        # VT102 understood, see ``VT102ID`` in ``linux/drivers/tty/vt.c``.
-        self.write_process_input(ctrl.CSI + "?6c")
-
-    def report_device_status(self, mode):
-        """Reports terminal status or cursor position.
-
-        :param int mode: if 5 -- terminal status, 6 -- cursor position,
-                         otherwise a noop.
-
-        .. versionadded:: 0.5.0
-        """
-        if mode == 5:    # Request for terminal status.
-            self.write_process_input(ctrl.CSI + "0n")
-        elif mode == 6:  # Request for cursor position.
-            x = self.cursor.x + 1
-            y = self.cursor.y + 1
-
-            # "Origin mode (DECOM) selects line numbering."
-            if mo.DECOM in self.mode:
-                y -= self.margins.top
-            self.write_process_input("{0}{1};{2}R".format(ctrl.CSI, y, x))
-
-    def write_process_input(self, data):
-        """Writes data to the process running inside the terminal.
-
-        By default is a noop.
-
-        :param str data: data to write to the process ``stdin``.
-
-        .. versionadded:: 0.5.0
-        """
-
-
-
-
[email protected]("screen_cls", [Screen, VanillaScreen])
-def test_stream_performance(benchmark, screen_cls):
-    def inner(contents):
-        s = Stream()
-        s.attach(screen_cls(80, 24))
-        s.feed(contents)
-
-    benchmark(inner, open("/tmp/mc").read())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyte-0.5.1/tests/test_screen.py 
new/pyte-0.5.2/tests/test_screen.py
--- old/pyte-0.5.1/tests/test_screen.py 2016-01-10 01:01:14.000000000 +0100
+++ new/pyte-0.5.2/tests/test_screen.py 2016-03-14 12:23:17.000000000 +0100
@@ -1220,10 +1220,29 @@
 
     acc = []
     screen.write_process_input = acc.append
+
+    # a) noop
+    screen.report_device_attributes(42)
+    assert not acc
+
+    # b) OK case
     screen.report_device_attributes()
     assert acc.pop() == ctrl.CSI + "?6c"
 
 
+def test_private_report_device_attributes():
+    # Some console apps (e.g. ADOM) might add ``?`` to the DA request,
+    # even though the VT102/VT220 spec does not allow this.
+    screen = Screen(10, 10)
+    stream = Stream()
+    stream.attach(screen)
+
+    acc = []
+    screen.write_process_input = acc.append
+    stream.feed(ctrl.CSI + "?0c")
+    assert acc.pop() == ctrl.CSI + "?6c"
+
+
 def test_report_device_status():
     screen = Screen(10, 10)
 


Reply via email to