From 177454a694b8f4e2379f1c062f77edb6aa5f7c5c64e7ace01b6dfea5d4e71b45 Mon Sep 17 00:00:00 2001 From: Steve Kowalik Date: Thu, 26 Oct 2023 00:26:49 +0000 Subject: [PATCH] - Update to 1.15.0: * Dropped support for Python 2, Python 3.9 or above is now required. * Added support for ColouredText titles in MultiColumnLIstBox. * Added gutter option to Layout. * Added speed option to Sprite. * Fixed bug where moving focus between Frames resulted in no current focus. * Fixed internal state of RadioButton values to be consistent with selection. * Fixed handling of zero width modifiers. * Fixed image conversion to use modern PIL API and sort off-by-one height error. * Fixed parser bug returning list instead of colour tuple. - Drop patch move-to-python3.patch, included upstream. OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-asciimatics?expand=0&rev=19 --- asciimatics-1.14.0.tar.gz | 3 - asciimatics-1.15.0.tar.gz | 3 + move-to-python3.patch | 3277 ------------------------------------ python-asciimatics.changes | 16 + python-asciimatics.spec | 5 +- 5 files changed, 21 insertions(+), 3283 deletions(-) delete mode 100644 asciimatics-1.14.0.tar.gz create mode 100644 asciimatics-1.15.0.tar.gz delete mode 100644 move-to-python3.patch diff --git a/asciimatics-1.14.0.tar.gz b/asciimatics-1.14.0.tar.gz deleted file mode 100644 index 0ce8044..0000000 --- a/asciimatics-1.14.0.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:16d20ce42210b434eb05ba469ecdb8293ac7ed3c0ce0dd4f70e30d72d7602227 -size 2631618 diff --git a/asciimatics-1.15.0.tar.gz b/asciimatics-1.15.0.tar.gz new file mode 100644 index 0000000..466e7d8 --- /dev/null +++ b/asciimatics-1.15.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfdd398042727519d8b73e62b8ef82c0becfed4eb420899c3b96c98d0b96821a +size 2642946 diff --git a/move-to-python3.patch b/move-to-python3.patch deleted file mode 100644 index f3f899a..0000000 --- a/move-to-python3.patch +++ /dev/null @@ -1,3277 +0,0 @@ -From 961fdc754e655c68835aee1e7f71af1fdc677668 Mon Sep 17 00:00:00 2001 -From: Steve Kowalik -Date: Mon, 11 Sep 2023 13:18:54 +1000 -Subject: [PATCH] Move to Python 3 only - -With setup.py declaring Python 3.8 and above is supported, use pyupgrade -to reformat the code for that version, along with removing use of mock -and future modules. - -Fixes #347 ---- - asciimatics/constants.py | 5 - - asciimatics/effects.py | 48 ++++---- - asciimatics/event.py | 6 +- - asciimatics/exceptions.py | 13 +- - asciimatics/parsers.py | 15 +-- - asciimatics/particles.py | 46 ++++--- - asciimatics/paths.py | 16 +-- - asciimatics/renderers/base.py | 16 +-- - asciimatics/renderers/box.py | 7 +- - asciimatics/renderers/charts.py | 12 +- - asciimatics/renderers/figlettext.py | 8 +- - asciimatics/renderers/fire.py | 9 +- - asciimatics/renderers/images.py | 14 +-- - asciimatics/renderers/kaleidoscope.py | 9 +- - asciimatics/renderers/plasma.py | 9 +- - asciimatics/renderers/players.py | 12 +- - asciimatics/renderers/rainbow.py | 8 +- - asciimatics/renderers/rotatedduplicate.py | 8 +- - asciimatics/renderers/scales.py | 11 +- - asciimatics/renderers/speechbubble.py | 8 +- - asciimatics/scene.py | 9 +- - asciimatics/screen.py | 54 ++++----- - asciimatics/sprites.py | 10 +- - asciimatics/strings.py | 4 +- - asciimatics/utilities.py | 64 +++++----- - asciimatics/widgets/baselistbox.py | 11 +- - asciimatics/widgets/button.py | 11 +- - asciimatics/widgets/checkbox.py | 9 +- - asciimatics/widgets/datepicker.py | 17 +-- - asciimatics/widgets/divider.py | 11 +- - asciimatics/widgets/dropdownlist.py | 11 +- - asciimatics/widgets/filebrowser.py | 19 ++- - asciimatics/widgets/frame.py | 10 +- - asciimatics/widgets/label.py | 8 +- - asciimatics/widgets/layout.py | 9 +- - asciimatics/widgets/listbox.py | 9 +- - asciimatics/widgets/multicolumnlistbox.py | 11 +- - asciimatics/widgets/popupdialog.py | 7 +- - asciimatics/widgets/popupmenu.py | 9 +- - asciimatics/widgets/radiobuttons.py | 11 +- - asciimatics/widgets/scrollbar.py | 14 +-- - asciimatics/widgets/temppopup.py | 9 +- - asciimatics/widgets/text.py | 10 +- - asciimatics/widgets/textbox.py | 9 +- - asciimatics/widgets/timepicker.py | 16 +-- - asciimatics/widgets/utilities.py | 11 +- - asciimatics/widgets/verticaldivider.py | 10 +- - asciimatics/widgets/widget.py | 12 +- - doc/source/troubleshooting.rst | 7 -- - doc/source/widgets.rst | 2 +- - requirements/base.txt | 3 - - requirements/dev.txt | 1 - - samples/256colour.py | 1 - - samples/basics.py | 2 - - samples/bg_colours.py | 1 - - samples/cogs.py | 1 - - samples/contact_list.py | 2 +- - samples/credits.py | 1 - - samples/images.py | 1 - - samples/maps.py | 2 - - samples/quick_model.py | 2 +- - samples/ray_casting.py | 10 +- - samples/simple.py | 1 - - samples/xmas.py | 1 - - setup.py | 7 -- - tests/mock_objects.py | 2 +- - tests/renderers/test_base.py | 6 - - tests/renderers/test_charts.py | 6 - - tests/renderers/test_images.py | 5 - - tests/renderers/test_other.py | 16 +-- - tests/renderers/test_players.py | 6 - - tests/test_effects.py | 3 +- - tests/test_events.py | 2 +- - tests/test_parsers.py | 5 - - tests/test_particles.py | 2 +- - tests/test_screen.py | 39 +++--- - tests/test_strings.py | 5 - - tests/test_utilities.py | 5 - - tests/test_widgets.py | 139 ++++++++++------------ - 79 files changed, 293 insertions(+), 668 deletions(-) - -Index: asciimatics-1.14.0/asciimatics/constants.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/constants.py -+++ asciimatics-1.14.0/asciimatics/constants.py -@@ -1,11 +1,6 @@ -- - """ - This module is just a collection of simple helper functions. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - - #: Attribute conversion table for the ${c,a} form of attributes for - #: :py:obj:`~.Screen.paint`. -Index: asciimatics-1.14.0/asciimatics/effects.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/effects.py -+++ asciimatics-1.14.0/asciimatics/effects.py -@@ -1,16 +1,8 @@ --# -*- coding: utf-8 -*- - """ - This module defines `Effects` which can be used for animations. For more details see - http://asciimatics.readthedocs.io/en/latest/animation.html - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import chr --from builtins import object --from builtins import range --from future.utils import with_metaclass -+ - from abc import ABCMeta, abstractmethod, abstractproperty - from random import randint, random, choice - from math import sin, cos, pi -@@ -19,7 +11,7 @@ from asciimatics.screen import Screen - import datetime - - --class Effect(with_metaclass(ABCMeta, object)): -+class Effect(metaclass=ABCMeta): - """ - Abstract class to handle a special effect on the screen. An Effect can - cover anything from a static image at the start of the Scene through to -@@ -175,7 +167,7 @@ class Scroll(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Scroll, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._rate = rate - self._last_frame = None - -@@ -207,7 +199,7 @@ class Cycle(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Cycle, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._renderer = renderer - self._y = y - self._colour = 0 -@@ -249,7 +241,7 @@ class BannerText(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(BannerText, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._renderer = renderer - self._y = y - self._colour = colour -@@ -314,7 +306,7 @@ class Print(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Print, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._renderer = renderer - self._transparent = transparent - self._y = y -@@ -373,7 +365,7 @@ class Mirage(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Mirage, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._renderer = renderer - self._y = y - self._colour = colour -@@ -407,7 +399,7 @@ class Mirage(Effect): - return self._stop_frame - - --class _Star(object): -+class _Star(): - """ - Simple class to represent a single star for the Stars special effect. - """ -@@ -473,7 +465,7 @@ class Stars(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Stars, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._pattern = pattern - self._max = count - self._stars = [] -@@ -490,7 +482,7 @@ class Stars(Effect): - return 0 - - --class _Trail(object): -+class _Trail(): - """ - Track a single trail for a falling character effect (a la Matrix). - """ -@@ -564,7 +556,7 @@ class Matrix(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Matrix, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._chars = [] - - def reset(self): -@@ -594,7 +586,7 @@ class Wipe(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Wipe, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._bg = bg - self._y = None - -@@ -630,7 +622,7 @@ class Sprite(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Sprite, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._renderer_dict = renderer_dict - self._path = path - self._index = None -@@ -754,7 +746,7 @@ class Sprite(Effect): - return event - - --class _Flake(object): -+class _Flake(): - """ - Track a single snow flake. - """ -@@ -828,7 +820,7 @@ class Snow(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Snow, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._chars = [] - - def reset(self): -@@ -864,7 +856,7 @@ class Clock(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Clock, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._x = x - self._y = y - self._r = r -@@ -946,7 +938,7 @@ class Cog(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Cog, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._x = x - self._y = y - self._radius = radius -@@ -1004,7 +996,7 @@ class RandomNoise(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(RandomNoise, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._signal = signal - self._strength = 0.0 - self._step = 0.0 -@@ -1076,7 +1068,7 @@ class Julia(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Julia, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._width = screen.width - self._height = screen.height - self._centre = [0.0, 0.0] -@@ -1135,7 +1127,7 @@ class Background(Effect): - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(Background, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._bg = bg - - def reset(self): -Index: asciimatics-1.14.0/asciimatics/event.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/event.py -+++ asciimatics-1.14.0/asciimatics/event.py -@@ -4,7 +4,7 @@ http://asciimatics.readthedocs.io/en/lat - """ - - --class Event(object): -+class Event(): - """ - A class to hold information about an input event. - -@@ -31,7 +31,7 @@ class KeyboardEvent(Event): - """ - :returns: a string representation of the keyboard event. - """ -- return "KeyboardEvent: {}".format(self.key_code) -+ return f"KeyboardEvent: {self.key_code}" - - - class MouseEvent(Event): -@@ -61,4 +61,4 @@ class MouseEvent(Event): - """ - :returns: a string representation of the mouse event. - """ -- return "MouseEvent ({}, {}) {}".format(self.x, self.y, self.buttons) -+ return f"MouseEvent ({self.x}, {self.y}) {self.buttons}" -Index: asciimatics-1.14.0/asciimatics/exceptions.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/exceptions.py -+++ asciimatics-1.14.0/asciimatics/exceptions.py -@@ -1,11 +1,6 @@ - """ - This module defines the exceptions used by asciimatics. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -- - - class ResizeScreenError(Exception): - """ -@@ -18,7 +13,7 @@ class ResizeScreenError(Exception): - :param message: Error message for this exception. - :param scene: Scene that was active at time of resize. - """ -- super(ResizeScreenError, self).__init__() -+ super().__init__() - self._scene = scene - self._message = message - -@@ -48,7 +43,7 @@ class StopApplication(Exception): - """ - :param message: Error message for this exception. - """ -- super(StopApplication, self).__init__() -+ super().__init__() - self._message = message - - def __str__(self): -@@ -68,7 +63,7 @@ class NextScene(Exception): - """ - :param name: Next Scene to invoke. Defaults to next in the list. - """ -- super(NextScene, self).__init__() -+ super().__init__() - self._name = name - - @property -@@ -90,7 +85,7 @@ class InvalidFields(Exception): - """ - :param fields: The list of the fields that are invalid. - """ -- super(InvalidFields, self).__init__() -+ super().__init__() - self._fields = fields - - @property -Index: asciimatics-1.14.0/asciimatics/parsers.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/parsers.py -+++ asciimatics-1.14.0/asciimatics/parsers.py -@@ -1,14 +1,8 @@ -- - """ - This module provides parsers to create ColouredText objects from embedded control strings. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -+ - import re --from builtins import str --from future.utils import with_metaclass - from abc import ABCMeta, abstractmethod - from logging import getLogger - import asciimatics.constants as constants -@@ -19,7 +13,7 @@ from asciimatics.utilities import _DotDi - logger = getLogger(__name__) - - --class Parser(with_metaclass(ABCMeta, object)): -+class Parser(metaclass=ABCMeta): - """ - Abstract class to represent text parsers that extract colour control codes from raw text and - convert them to displayable text and associated colour maps. -@@ -171,7 +165,7 @@ class AnsiTerminalParser(Parser): - :param text: raw text to process. - :param colours: colour tuple to initialise the colour map. - """ -- super(AnsiTerminalParser, self).reset(text, colours) -+ super().reset(text, colours) - if self._state.attributes is None: - self._state.init_colours = False - self._state.attributes = [None, None, None] -@@ -382,8 +376,7 @@ class AnsiTerminalParser(Parser): - if new_offset == -1: - break - if results is not None: -- for result in results: -- yield result -+ yield from results - else: - logger.debug("Ignoring character: %d", char) - yield (self._state.last_offset, Parser.DISPLAY_TEXT, " ") -Index: asciimatics-1.14.0/asciimatics/particles.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/particles.py -+++ asciimatics-1.14.0/asciimatics/particles.py -@@ -2,22 +2,16 @@ - This module implements a particle system for complex animcation effects. For more details, see - http://asciimatics.readthedocs.io/en/latest/animation.html - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -+ - from abc import ABCMeta, abstractmethod --from builtins import object --from builtins import range - from copy import copy - from math import pi, sin, cos, sqrt - from random import uniform, randint --from future.utils import with_metaclass - from asciimatics.effects import Effect - from asciimatics.screen import Screen - - --class Particle(object): -+class Particle(): - """ - A single particle in a Particle Effect. - """ -@@ -117,7 +111,7 @@ class Particle(object): - return self._last - - --class ParticleEmitter(object): -+class ParticleEmitter(): - """ - An emitter for a particle system to create a set of :py:obj:`._Particle` - objects for a :py:obj:`.ParticleEffect`. After initialization, the -@@ -140,7 +134,7 @@ class ParticleEmitter(object): - Each Particle individually as they are drawn. - Defaults to False. - """ -- super(ParticleEmitter, self).__init__() -+ super().__init__() - self._screen = screen - self._x = x - self._y = y -@@ -201,7 +195,7 @@ class ParticleEmitter(object): - self.particles.remove(particle) - - --class ParticleEffect(with_metaclass(ABCMeta, Effect)): -+class ParticleEffect(Effect, metaclass=ABCMeta): - """ - An Effect that uses a :py:obj:`.ParticleEmitter` to create the animation. - -@@ -219,7 +213,7 @@ class ParticleEffect(with_metaclass(ABCM - - Also see the common keyword arguments in :py:obj:`.Effect`. - """ -- super(ParticleEffect, self).__init__(screen, **kwargs) -+ super().__init__(screen, **kwargs) - self._x = x - self._y = y - self._life_time = life_time -@@ -259,7 +253,7 @@ class Rocket(ParticleEmitter): - :param life_time: The life time of the rocket. - :param on_destroy: The function to call when the rocket explodes. - """ -- super(Rocket, self).__init__( -+ super().__init__( - screen, x, screen.height - 1, 1, self._next_particle, 1, life_time) - self._end_y = y - self._acceleration = (self._end_y - self._y) // life_time -@@ -299,7 +293,7 @@ class RingExplosion(ParticleEmitter): - :param y: The line (y coordinate) for the origin of this explosion. - :param life_time: The life time of this explosion. - """ -- super(RingExplosion, self).__init__( -+ super().__init__( - screen, x, y, 30, self._next_particle, 1, life_time) - self._colour = randint(1, 7) - self._acceleration = 1.0 - (1.0 / life_time) -@@ -339,7 +333,7 @@ class SerpentExplosion(ParticleEmitter): - :param y: The line (y coordinate) for the origin of this explosion. - :param life_time: The life time of this explosion. - """ -- super(SerpentExplosion, self).__init__( -+ super().__init__( - screen, x, y, 8, self._next_particle, 2, life_time) - self._colour = randint(1, 7) - -@@ -383,7 +377,7 @@ class StarExplosion(ParticleEmitter): - :param points: Number of points the explosion should have. - :param on_each: The function to call to spawn a trail. - """ -- super(StarExplosion, self).__init__( -+ super().__init__( - screen, x, y, points, self._next_particle, 1, life_time) - self._colour = randint(1, 7) - self._acceleration = 1.0 - (1.0 / life_time) -@@ -427,7 +421,7 @@ class StarTrail(ParticleEmitter): - :param life_time: The life time of this trail. - :param colour: The colour of this trail. - """ -- super(StarTrail, self).__init__( -+ super().__init__( - screen, x, y, 1, self._next_particle, 1, life_time) - self._colour = colour - -@@ -465,7 +459,7 @@ class PalmExplosion(ParticleEmitter): - :param life_time: The life time of this explosion. - :param on_each: The function to call to spawn a trail. - """ -- super(PalmExplosion, self).__init__( -+ super().__init__( - screen, x, y, 6, self._next_particle, 2, life_time) - self._colour = randint(1, 7) - self._on_each = on_each -@@ -507,7 +501,7 @@ class ExplosionFlames(ParticleEmitter): - :param y: The line (y coordinate) for the origin of this explosion. - :param life_time: The life time of this explosion. - """ -- super(ExplosionFlames, self).__init__( -+ super().__init__( - screen, x, y, 30, self._next_particle, life_time - 10, life_time, - blend=True) - -@@ -553,7 +547,7 @@ class DropEmitter(ParticleEmitter): - :param screen: The Screen being used for this particle system. - :param life_time: The life time of this particle system. - """ -- super(DropEmitter, self).__init__( -+ super().__init__( - screen, 0, 0, 20, self._next_particle, life_time, life_time) - self._particles = None - self._full_count = 0 -@@ -603,7 +597,7 @@ class ShotEmitter(ParticleEmitter): - :param diameter: The diameter of the explosion. - :param life_time: The life time of this particle system. - """ -- super(ShotEmitter, self).__init__( -+ super().__init__( - screen, x, y, 50, self._next_particle, life_time, life_time) - self._particles = None - self._diameter = diameter -@@ -669,7 +663,7 @@ class RainSource(ParticleEmitter): - :param life_time: The life time of this particle system. - :param on_each: Function to call on each iteration of the particle. - """ -- super(RainSource, self).__init__( -+ super().__init__( - screen, 0, 0, 4, self._next_particle, life_time, life_time) - self._particles = None - self._on_each = on_each -@@ -701,7 +695,7 @@ class Splash(ParticleEmitter): - """ - :param screen: The Screen being used for this particle system. - """ -- super(Splash, self).__init__( -+ super().__init__( - screen, x, y, 1, self._next_particle, 1, 3) - - def _next_particle(self): -@@ -819,7 +813,7 @@ class DropScreen(ParticleEffect): - See :py:obj:`.ParticleEffect` for details of the parameters. - """ - # No need for an origin as this uses the whole screen. -- super(DropScreen, self).__init__(screen, 0, 0, life_time, **kwargs) -+ super().__init__(screen, 0, 0, life_time, **kwargs) - - def reset(self): - self._active_systems = [] -@@ -840,7 +834,7 @@ class ShootScreen(ParticleEffect): - """ - # Need to set the field first because the underlying constructor calls reset. - self._diameter = diameter -- super(ShootScreen, self).__init__(screen, x, y, life_time, **kwargs) -+ super().__init__(screen, x, y, life_time, **kwargs) - - def reset(self): - self._active_systems = [] -@@ -858,7 +852,7 @@ class Rain(ParticleEffect): - See :py:obj:`.ParticleEffect` for details of the parameters. - """ - # No need for an origin as this uses the whole screen. -- super(Rain, self).__init__(screen, 0, 0, life_time, **kwargs) -+ super().__init__(screen, 0, 0, life_time, **kwargs) - - def reset(self): - self._active_systems = [] -Index: asciimatics-1.14.0/asciimatics/paths.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/paths.py -+++ asciimatics-1.14.0/asciimatics/paths.py -@@ -2,14 +2,8 @@ - This module provides `Paths` to create animation effects with Sprites. For more details see - http://asciimatics.readthedocs.io/en/latest/animation.html - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from future.utils import with_metaclass -+ - from abc import ABCMeta, abstractmethod --from builtins import object --from builtins import range - - - def _spline(t, p0, p1, p2, p3): -@@ -29,7 +23,7 @@ def _spline(t, p0, p1, p2, p3): - (t - 1) * t * t * p3) / 2 - - --class _AbstractPath(with_metaclass(ABCMeta, object)): -+class _AbstractPath(metaclass=ABCMeta): - """ - Class to represent the motion of a Sprite. - -@@ -81,7 +75,7 @@ class Path(_AbstractPath): - To define a Path, use the methods to jump to a location, wait or move - between points. - """ -- super(Path, self).__init__() -+ super().__init__() - self._steps = [] - self._index = 0 - self._rec_x = 0 -@@ -184,7 +178,7 @@ class Path(_AbstractPath): - self._add_step((x, int(y))) - - --class DynamicPath(with_metaclass(ABCMeta, _AbstractPath)): -+class DynamicPath(_AbstractPath, metaclass=ABCMeta): - """ - Class to create a dynamic path that reacts to events - -@@ -198,7 +192,7 @@ class DynamicPath(with_metaclass(ABCMeta - To implement a DynamicPath, override the :py:meth:`.process_event()` - method to react to any user input. - """ -- super(DynamicPath, self).__init__() -+ super().__init__() - self._screen = screen - self._x = self._start_x = x - self._y = self._start_y = y -Index: asciimatics-1.14.0/asciimatics/renderers/base.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/base.py -+++ asciimatics-1.14.0/asciimatics/renderers/base.py -@@ -1,14 +1,8 @@ --# -*- coding: utf-8 -*- - """ - This module provides common code for all Renderers. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import object -+ - from abc import ABCMeta, abstractproperty, abstractmethod --from future.utils import with_metaclass - import re - - from wcwidth.wcwidth import wcswidth -@@ -26,7 +20,7 @@ ATTRIBUTES = { - } - - --class Renderer(with_metaclass(ABCMeta, object)): -+class Renderer(metaclass=ABCMeta): - """ - A Renderer is simply a class that will return one or more text renderings - for display by an Effect. -@@ -90,7 +84,7 @@ class StaticRenderer(Renderer): - :param animation: A function to pick the image (from images) to be - rendered for any given frame. - """ -- super(StaticRenderer, self).__init__() -+ super().__init__() - self._images = images if images is not None else [] - self._index = 0 - self._max_width = 0 -@@ -195,7 +189,7 @@ class StaticRenderer(Renderer): - return self._max_width - - --class DynamicRenderer(with_metaclass(ABCMeta, Renderer)): -+class DynamicRenderer(Renderer, metaclass=ABCMeta): - """ - A DynamicRenderer is a Renderer that creates each image as requested. It - has a defined maximum size on construction. -@@ -206,7 +200,7 @@ class DynamicRenderer(with_metaclass(ABC - :param height: The max height of the rendered image. - :param width: The max width of the rendered image. - """ -- super(DynamicRenderer, self).__init__() -+ super().__init__() - self._must_clear = clear - self._canvas = TemporaryCanvas(height, width) - -Index: asciimatics-1.14.0/asciimatics/renderers/box.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/box.py -+++ asciimatics-1.14.0/asciimatics/renderers/box.py -@@ -1,11 +1,6 @@ --# -*- coding: utf-8 -*- - """ - This module implements an ASCII box renderer. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - - from asciimatics.constants import SINGLE_LINE - from asciimatics.renderers.base import StaticRenderer -@@ -29,5 +24,5 @@ class Box(StaticRenderer): - `DOUBLE_LINE`. `uni` parameter takes precedence and the style will be - ignored if `uni==False` - """ -- super(Box, self).__init__() -+ super().__init__() - self._images = [BoxTool(uni, style).box(width, height)] -Index: asciimatics-1.14.0/asciimatics/renderers/charts.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/charts.py -+++ asciimatics-1.14.0/asciimatics/renderers/charts.py -@@ -1,11 +1,7 @@ --# -*- coding: utf-8 -*- - """ - This module implements bar chart renderers. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -+ - from abc import abstractmethod - - from asciimatics.constants import DOUBLE_LINE, SINGLE_LINE -@@ -33,7 +29,7 @@ class _BarChartBase(DynamicRenderer): - bg=Screen.COLOUR_BLACK, gradient=None, scale=None, axes=Y_AXIS, intervals=None, - labels=False, border=True, keys=None, gap=None): - ### See children BarChart and VBarChart for argument descriptions and pydocs -- super(_BarChartBase, self).__init__(height, width) -+ super().__init__(height, width) - self._functions = functions - self._char = char - self._colours = [colour] if isinstance(colour, int) else colour -@@ -174,7 +170,7 @@ class BarChart(_BarChartBase): - * A Y_AXIS uses a width of 1 - """ - # Have to have a call to super as the defaults for the class are different than the parent -- super(BarChart, self).__init__( -+ super().__init__( - height, width, functions, char, colour, bg, gradient, scale, axes, intervals, labels, border, - keys, gap) - -@@ -325,7 +321,7 @@ class VBarChart(_BarChartBase): - * An X_AXIS uses a height of 1 - * A Y_AXIS uses a width of 1 - """ -- super(VBarChart, self).__init__( -+ super().__init__( - height, width, functions, char, colour, bg, gradient, scale, axes, intervals, labels, border, - keys, gap) - -Index: asciimatics-1.14.0/asciimatics/renderers/figlettext.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/figlettext.py -+++ asciimatics-1.14.0/asciimatics/renderers/figlettext.py -@@ -1,11 +1,7 @@ --# -*- coding: utf-8 -*- - """ - This module implements Figlet text renderer. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -+ - from pyfiglet import Figlet, DEFAULT_FONT - - from asciimatics.renderers.base import StaticRenderer -@@ -23,5 +19,5 @@ class FigletText(StaticRenderer): - :param font: The Figlet font to use (optional). - :param width: The maximum width for this text in characters. - """ -- super(FigletText, self).__init__() -+ super().__init__() - self._images = [Figlet(font=font, width=width).renderText(text)] -Index: asciimatics-1.14.0/asciimatics/renderers/fire.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/fire.py -+++ asciimatics-1.14.0/asciimatics/renderers/fire.py -@@ -1,12 +1,7 @@ --# -*- coding: utf-8 -*- - """ - This module implements a fire effect renderer. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range -+ - import copy - from random import randint, random - -@@ -77,7 +72,7 @@ class Fire(DynamicRenderer): - :param colours: Number of colours the screen supports. - :param bg: (Optional) Whether to render background colours only. - """ -- super(Fire, self).__init__(height, width) -+ super().__init__(height, width) - self._emitter = emitter - self._intensity = intensity - self._spot_heat = spot -Index: asciimatics-1.14.0/asciimatics/renderers/images.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/images.py -+++ asciimatics-1.14.0/asciimatics/renderers/images.py -@@ -1,20 +1,14 @@ --# -*- coding: utf-8 -*- - """ - This module implements renderers that produce content based on image files. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import object --from builtins import range -+ - from PIL import Image - - from asciimatics.renderers.base import StaticRenderer - from asciimatics.screen import Screen - - --class _ImageSequence(object): -+class _ImageSequence(): - """ - Simple class to make an iterator for a PIL Image object. - """ -@@ -46,7 +40,7 @@ class ImageFile(StaticRenderer): - :param height: The height of the text rendered image. - :param colours: The number of colours the terminal supports. - """ -- super(ImageFile, self).__init__() -+ super().__init__() - with Image.open(filename) as image: - background = image.info['background'] if 'background' in \ - image.info else None -@@ -101,7 +95,7 @@ class ColourImageFile(StaticRenderer): - :param uni: Whether to use unicode box characters or not. - :param dither: Whether to dither the rendered image or not. - """ -- super(ColourImageFile, self).__init__() -+ super().__init__() - with Image.open(filename) as image: - # Find any PNG or GIF background colour. - background = None -Index: asciimatics-1.14.0/asciimatics/renderers/kaleidoscope.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/kaleidoscope.py -+++ asciimatics-1.14.0/asciimatics/renderers/kaleidoscope.py -@@ -1,12 +1,7 @@ --# -*- coding: utf-8 -*- - """ - This module implements a kaeldioscope effect renderer. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range -+ - from math import sin, cos, pi, atan2 - - from asciimatics.renderers.base import DynamicRenderer -@@ -38,7 +33,7 @@ class Kaleidoscope(DynamicRenderer): - :param cell: A Renderer to use as the backing cell for the kaleidoscope. - :param symmetry: The desired rotational symmetry. Must be a non-negative integer. - """ -- super(Kaleidoscope, self).__init__(height, width) -+ super().__init__(height, width) - self._symmetry = symmetry - self._rotation = 0 - self._cell = cell -Index: asciimatics-1.14.0/asciimatics/renderers/plasma.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/plasma.py -+++ asciimatics-1.14.0/asciimatics/renderers/plasma.py -@@ -1,12 +1,7 @@ --# -*- coding: utf-8 -*- - """ - This module implements a plasma effect renderer. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range -+ - from math import sin, pi, sqrt - - from asciimatics.renderers.base import DynamicRenderer -@@ -57,7 +52,7 @@ class Plasma(DynamicRenderer): - :param width: Width of the box to contain the plasma. - :param colours: Number of colours the screen supports. - """ -- super(Plasma, self).__init__(height, width) -+ super().__init__(height, width) - self._palette = self._palette_256 if colours >= 256 else self._palette_8 - self._t = 0 - -Index: asciimatics-1.14.0/asciimatics/renderers/players.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/players.py -+++ asciimatics-1.14.0/asciimatics/renderers/players.py -@@ -1,13 +1,7 @@ --# -*- coding: utf-8 -*- - """ - This module implements renderers that play content to the screen. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from abc import abstractmethod --from builtins import range - import json - - from asciimatics.renderers.base import DynamicRenderer -@@ -25,7 +19,7 @@ class AbstractScreenPlayer(DynamicRender - :param height: required height of the renderer. - :param width: required width of the renderer. - """ -- super(AbstractScreenPlayer, self).__init__(height, width, clear=False) -+ super().__init__(height, width, clear=False) - self._parser = AnsiTerminalParser() - self._current_colours = [Screen.COLOUR_WHITE, Screen.A_NORMAL, Screen.COLOUR_BLACK] - self._show_cursor = False -@@ -157,7 +151,7 @@ class AnsiArtPlayer(AbstractScreenPlayer - :param strip: whether to strip CRLF from the file content. - :param rate: number of lines to render on each update. - """ -- super(AnsiArtPlayer, self).__init__(height, width) -+ super().__init__(height, width) - self._file = open(filename, "rb") - self._strip = strip - self._rate = rate -@@ -216,7 +210,7 @@ class AsciinemaPlayer(AbstractScreenPlay - width = width if width else header["width"] - - # Construct the full player now we have all the details. -- super(AsciinemaPlayer, self).__init__(height, width) -+ super().__init__(height, width) - self._max_delay = max_delay - - def __enter__(self): -Index: asciimatics-1.14.0/asciimatics/renderers/rainbow.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/rainbow.py -+++ asciimatics-1.14.0/asciimatics/renderers/rainbow.py -@@ -1,12 +1,6 @@ --# -*- coding: utf-8 -*- - """ - This module implements a rainbow effect renderer. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -- - from asciimatics.renderers.base import StaticRenderer - - -@@ -33,7 +27,7 @@ class Rainbow(StaticRenderer): - :param screen: The screen object for this renderer. - :param renderer: The renderer to wrap. - """ -- super(Rainbow, self).__init__() -+ super().__init__() - palette = self._256_palette if screen.colours > 16 else self._16_palette - for image in renderer.images: - new_image = "" -Index: asciimatics-1.14.0/asciimatics/renderers/rotatedduplicate.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/rotatedduplicate.py -+++ asciimatics-1.14.0/asciimatics/renderers/rotatedduplicate.py -@@ -1,12 +1,6 @@ --# -*- coding: utf-8 -*- - """ - This module implements a renderer that renders another renderer but rotated. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range - - from asciimatics.renderers.base import StaticRenderer - -@@ -23,7 +17,7 @@ class RotatedDuplicate(StaticRenderer): - :param height: The maximum height of the rendered text. - :param renderer: The renderer to wrap. - """ -- super(RotatedDuplicate, self).__init__() -+ super().__init__() - for image in renderer.images: - mx = (width - max([len(x) for x in image])) // 2 - my = height // 2 - len(image) -Index: asciimatics-1.14.0/asciimatics/renderers/scales.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/scales.py -+++ asciimatics-1.14.0/asciimatics/renderers/scales.py -@@ -1,13 +1,6 @@ --# -*- coding: utf-8 -*- - """ - This module implements renderers that show measuring scales to the screen. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range -- - from asciimatics.renderers.base import StaticRenderer - - -@@ -21,7 +14,7 @@ class Scale(StaticRenderer): - """ - :param width: The width of the scale - """ -- super(Scale, self).__init__() -+ super().__init__() - - contents = [] - for x in range(1, width + 1): -@@ -47,7 +40,7 @@ class VScale(StaticRenderer): - """ - :param width: The width of the scale - """ -- super(VScale, self).__init__() -+ super().__init__() - - contents = [str(i)[-1] for i in range(1, height + 1)] - text = '\n'.join(contents) -Index: asciimatics-1.14.0/asciimatics/renderers/speechbubble.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/renderers/speechbubble.py -+++ asciimatics-1.14.0/asciimatics/renderers/speechbubble.py -@@ -1,12 +1,6 @@ --# -*- coding: utf-8 -*- - """ - This module implements a speech-bubble effect renderer. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -- - from wcwidth.wcwidth import wcswidth - - from asciimatics.renderers.base import StaticRenderer -@@ -23,7 +17,7 @@ class SpeechBubble(StaticRenderer): - :param tail: Where to put the bubble callout tail, specifying "L" or - "R" for left or right tails. Can be None for no tail. - """ -- super(SpeechBubble, self).__init__() -+ super().__init__() - max_len = max([wcswidth(x) for x in text.split("\n")]) - if uni: - bubble = "╭─" + "─" * max_len + "─╮\n" -Index: asciimatics-1.14.0/asciimatics/scene.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/scene.py -+++ asciimatics-1.14.0/asciimatics/scene.py -@@ -4,14 +4,7 @@ http://asciimatics.readthedocs.io/en/lat - """ - - --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import object -- -- --class Scene(object): -+class Scene(): - """ - Class to store the details of a single scene to be displayed. This is - made up of a set of :py:obj:`.Effect` objects. See the documentation for -Index: asciimatics-1.14.0/asciimatics/screen.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/screen.py -+++ asciimatics-1.14.0/asciimatics/screen.py -@@ -1,13 +1,7 @@ --# -*- coding: utf-8 -*- - """ - This module defines common screen output function. For more details, see - http://asciimatics.readthedocs.io/en/latest/io.html - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -- - import os - import signal - import struct -@@ -15,17 +9,11 @@ import sys - import time - from abc import ABCMeta, abstractmethod - from functools import update_wrapper, partial -+from itertools import zip_longest - from locale import getlocale, getdefaultlocale - from logging import getLogger - from math import sqrt - --from builtins import object --from builtins import range --from builtins import ord --from builtins import chr --from builtins import str --from future.utils import with_metaclass --from future.moves.itertools import zip_longest - from wcwidth import wcwidth, wcswidth - - from asciimatics.event import KeyboardEvent, MouseEvent -@@ -40,7 +28,7 @@ ENABLE_EXTENDED_FLAGS = 0x0080 - ENABLE_QUICK_EDIT_MODE = 0x0040 - - --class _DoubleBuffer(object): -+class _DoubleBuffer(): - """ - Pure python Screen buffering. - """ -@@ -50,11 +38,11 @@ class _DoubleBuffer(object): - :param height: Height of the buffer to create. - :param width: Width of the buffer to create. - """ -- super(_DoubleBuffer, self).__init__() -+ super().__init__() - self._height = height - self._width = width - self._double_buffer = None -- line = [(u" ", Screen.COLOUR_WHITE, 0, 0, 1) for _ in range(self._width)] -+ line = [(" ", Screen.COLOUR_WHITE, 0, 0, 1) for _ in range(self._width)] - self._screen_buffer = [line[:] for _ in range(self._height)] - self.clear(Screen.COLOUR_WHITE, 0, 0) - -@@ -77,7 +65,7 @@ class _DoubleBuffer(object): - height = self._height if h is None else h - width = max(0, min(self._width - x, width)) - height = max(0, min(self._height - y, height)) -- line = [(u" ", fg, attr, bg, 1) for _ in range(width)] -+ line = [(" ", fg, attr, bg, 1) for _ in range(width)] - if x == 0 and y == 0 and w is None and h is None: - self._double_buffer = [line[:] for _ in range(height)] - else: -@@ -129,7 +117,7 @@ class _DoubleBuffer(object): - - :param lines: Number of lines to scroll. Negative numbers move the buffer up. - """ -- line = [(u" ", Screen.COLOUR_WHITE, 0, 0, 1) for _ in range(self._width)] -+ line = [(" ", Screen.COLOUR_WHITE, 0, 0, 1) for _ in range(self._width)] - if lines > 0: - # Limit to buffer size - this will just invalidate all the data - lines = min(lines, self._height) -@@ -213,7 +201,7 @@ class _DoubleBuffer(object): - return [[x[1:4] for x in self.slice(0, y, self.width)] for y in range(self.height)] - - --class _AbstractCanvas(with_metaclass(ABCMeta, object)): -+class _AbstractCanvas(metaclass=ABCMeta): - """ - Abstract class to handle screen buffering. - """ -@@ -502,7 +490,7 @@ class _AbstractCanvas(with_metaclass(ABC - :param colours: Number of colours for this object. - :param unicode_aware: Force use of unicode options for this object. - """ -- super(_AbstractCanvas, self).__init__() -+ super().__init__() - - # Can we handle unicode environments? - self._unicode_aware = unicode_aware -@@ -1122,7 +1110,7 @@ class TemporaryCanvas(_AbstractCanvas): - :param width: The width of the screen buffer to be used. - """ - # Colours and unicode rendering are up to the user. Pick defaults that won't limit them. -- super(TemporaryCanvas, self).__init__(height, width, None, 256, True) -+ super().__init__(height, width, None, 256, True) - - @property - def plain_image(self): -@@ -1158,7 +1146,7 @@ class Canvas(_AbstractCanvas): - to centring within the current Screen for that location. - """ - # Save off the screen details. -- super(Canvas, self).__init__( -+ super().__init__( - height, width, None, screen.colours, screen.unicode_aware) - self._screen = screen - self._dx = (screen.width - width) // 2 if x is None else x -@@ -1184,7 +1172,7 @@ class Canvas(_AbstractCanvas): - return self._dx, self._dy - - --class Screen(with_metaclass(ABCMeta, _AbstractCanvas)): -+class Screen(_AbstractCanvas, metaclass=ABCMeta): - """ - Class to track basic state of the screen. This constructs the necessary - resources to allow us to do the ASCII animations. -@@ -1283,7 +1271,7 @@ class Screen(with_metaclass(ABCMeta, _Ab - """ - Don't call this constructor directly. - """ -- super(Screen, self).__init__( -+ super().__init__( - height, width, buffer_height, 0, unicode_aware) - - # Initialize base class variables - e.g. those used for drawing. -@@ -1741,7 +1729,7 @@ class Screen(with_metaclass(ABCMeta, _Ab - break - else: - raise RuntimeError( -- "Could not find Scene: '{}'".format(e.name)) -+ f"Could not find Scene: '{e.name}'") - - # Reset the screen if needed. - scene = self._scenes[self._scene_index] -@@ -2021,7 +2009,7 @@ if sys.platform == "win32": - if unicode_aware is None: - # According to MSDN, 65001 is the Windows UTF-8 code page. - unicode_aware = win32console.GetConsoleCP() == 65001 -- super(_WindowsScreen, self).__init__( -+ super().__init__( - height, width, buffer_height, unicode_aware) - - # Save off the console details. -@@ -2333,7 +2321,7 @@ else: - encoding.lower() == "utf-8") - - # Save off the screen details. -- super(_CursesScreen, self).__init__( -+ super().__init__( - win.getmaxyx()[0], win.getmaxyx()[1], height, unicode_aware) - self._screen = win - self._screen.keypad(1) -@@ -2433,7 +2421,7 @@ else: - """ - try: - sys.stdout.write(msg) -- except IOError: -+ except OSError: - # Screen resize can throw IOErrors. These can be safely - # ignored as the screen will be shortly reset anyway. - pass -@@ -2481,10 +2469,10 @@ else: - """ - Refresh the screen. - """ -- super(_CursesScreen, self).refresh() -+ super().refresh() - try: - sys.stdout.flush() -- except IOError: -+ except OSError: - pass - - @staticmethod -@@ -2618,7 +2606,7 @@ else: - :param width: The width of the character (for dual-width glyphs in CJK languages). - """ - # Move the cursor if necessary -- cursor = u"" -+ cursor = "" - if x != self._cur_x or y != self._cur_y: - cursor = curses.tparm(self._move_y_x, y, x).decode("utf-8") - -@@ -2643,7 +2631,7 @@ else: - """ - try: - select.select([sys.stdin], [], [], timeout) -- except select.error: -+ except OSError: - # Any error will almost certainly result in a a Screen. Ignore. - pass - -@@ -2658,7 +2646,7 @@ else: - self._safe_write("{}{}{}".format(self._start_title, title, - self._end_title)) - -- class _SignalState(object): -+ class _SignalState(): - """ - Save previous user signal state while setting signals. - -Index: asciimatics-1.14.0/asciimatics/sprites.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/sprites.py -+++ asciimatics-1.14.0/asciimatics/sprites.py -@@ -2,10 +2,6 @@ - This module provides `Sprites` to create animation effects with Paths. For more details see - http://asciimatics.readthedocs.io/en/latest/animation.html - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from asciimatics.effects import Sprite - from asciimatics.renderers import StaticRenderer - import random -@@ -128,7 +124,7 @@ class Sam(Sprite): - """ - See :py:obj:`.Sprite` for details. - """ -- super(Sam, self).__init__( -+ super().__init__( - screen, - renderer_dict={ - "default": StaticRenderer(images=sam_default, animation=_blink), -@@ -152,7 +148,7 @@ class Arrow(Sprite): - """ - See :py:obj:`.Sprite` for details. - """ -- super(Arrow, self).__init__( -+ super().__init__( - screen, - renderer_dict={ - "default": StaticRenderer(images=default_arrow, -@@ -179,7 +175,7 @@ class Plot(Sprite): - """ - See :py:obj:`.Sprite` for details. - """ -- super(Plot, self).__init__( -+ super().__init__( - screen, - renderer_dict={ - "default": StaticRenderer(images=["X"]) -Index: asciimatics-1.14.0/asciimatics/strings.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/strings.py -+++ asciimatics-1.14.0/asciimatics/strings.py -@@ -4,7 +4,7 @@ This module provides classes to handle e - from asciimatics.parsers import Parser - - --class ColouredText(object): -+class ColouredText(): - """ - Unicode string-like object to store text and colour maps, using a parser to convert the raw text - passed in into visible text and an associated colour map. This only handles simple colour -@@ -23,7 +23,7 @@ class ColouredText(object): - The colour_map, offsets and text options are to optimize creation of substrings from an - existing ColouredText object and should not be used in general. - """ -- super(ColouredText, self).__init__() -+ super().__init__() - self._raw_text = raw_text - self._raw_offsets = [] - self._parser = parser -Index: asciimatics-1.14.0/asciimatics/utilities.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/utilities.py -+++ asciimatics-1.14.0/asciimatics/utilities.py -@@ -1,12 +1,6 @@ --# -*- coding: utf-8 -*- - """ - This module is just a collection of simple helper functions. - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import str - from datetime import date, datetime - from logging import getLogger - -@@ -24,9 +18,9 @@ def readable_mem(mem): - """ - for suffix in ["", "K", "M", "G", "T"]: - if mem < 10000: -- return "{}{}".format(int(mem), suffix) -+ return f"{int(mem)}{suffix}" - mem /= 1024 -- return "{}P".format(int(mem)) -+ return f"{int(mem)}P" - - - def readable_timestamp(stamp): -@@ -52,7 +46,7 @@ class _DotDict(dict): - __delattr__ = dict.__delitem__ - - --class BoxTool(object): -+class BoxTool(): - """ - Tool for building boxes out of characters. - -@@ -111,33 +105,33 @@ class BoxTool(object): - self._style = style - - if style == SINGLE_LINE and self.unicode_aware: -- self.down_right = u"┌" -- self.down_left = u"┐" -- self.up_right = u"└" -- self.up_left = u"┘" -- self.h = u"─" -- self.h_inside = u"─" -- self.v = u"│" -- self.v_inside = u"│" -- self.v_left = u"┤" -- self.v_right = u"├" -- self.h_up = u"┴" -- self.h_down = u"┬" -- self.cross = u"┼" -+ self.down_right = "┌" -+ self.down_left = "┐" -+ self.up_right = "└" -+ self.up_left = "┘" -+ self.h = "─" -+ self.h_inside = "─" -+ self.v = "│" -+ self.v_inside = "│" -+ self.v_left = "┤" -+ self.v_right = "├" -+ self.h_up = "┴" -+ self.h_down = "┬" -+ self.cross = "┼" - elif style == DOUBLE_LINE and self.unicode_aware: -- self.down_right = u"╔" -- self.down_left = u"╗" -- self.up_right = u"╚" -- self.up_left = u"╝" -- self.h = u"═" -- self.h_inside = u"═" -- self.v = u"║" -- self.v_inside = u"║" -- self.v_left = u"╣" -- self.v_right = u"╠" -- self.h_up = u"╩" -- self.h_down = u"╦" -- self.cross = u"╬" -+ self.down_right = "╔" -+ self.down_left = "╗" -+ self.up_right = "╚" -+ self.up_left = "╝" -+ self.h = "═" -+ self.h_inside = "═" -+ self.v = "║" -+ self.v_inside = "║" -+ self.v_left = "╣" -+ self.v_right = "╠" -+ self.h_up = "╩" -+ self.h_down = "╦" -+ self.cross = "╬" - else: - self.down_left = "+" - self.down_right = "+" -Index: asciimatics-1.14.0/asciimatics/widgets/baselistbox.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/baselistbox.py -+++ asciimatics-1.14.0/asciimatics/widgets/baselistbox.py -@@ -1,20 +1,13 @@ --# -*- coding: utf-8 -*- - """This is the baseclass for list box types""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import chr - from datetime import datetime, timedelta - from abc import ABCMeta, abstractmethod, abstractproperty --from future.utils import with_metaclass - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.screen import Screen - from asciimatics.widgets.widget import Widget - from asciimatics.widgets.scrollbar import _ScrollBar - - --class _BaseListBox(with_metaclass(ABCMeta, Widget)): -+class _BaseListBox(Widget, metaclass=ABCMeta): - """ - An Internal class to contain common function between list box types. - """ -@@ -35,7 +28,7 @@ class _BaseListBox(with_metaclass(ABCMet - this list - e.g. by double-clicking or pressing Enter. - :param validator: Optional function to validate selection for this widget. - """ -- super(_BaseListBox, self).__init__(name) -+ super().__init__(name) - self._titles = titles - self._label = label - self._parser = parser -Index: asciimatics-1.14.0/asciimatics/widgets/button.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/button.py -+++ asciimatics-1.14.0/asciimatics/widgets/button.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module defines a button widget""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.widgets.widget import Widget - -@@ -28,7 +23,7 @@ class Button(Widget): - - Also see the common keyword arguments in :py:obj:`.Widget`. - """ -- super(Button, self).__init__(name, **kwargs) -+ super().__init__(name, **kwargs) - self._add_box = add_box - self.text = text - self._on_click = on_click -@@ -37,7 +32,7 @@ class Button(Widget): - def set_layout(self, x, y, offset, w, h): - # Do the usual layout work. then recalculate exact x/w values for the - # rendered button. -- super(Button, self).set_layout(x, y, offset, w, h) -+ super().set_layout(x, y, offset, w, h) - text_width = self.string_len(self._text) - if self._add_box: - # Minimize widget to make a nice little button. Only centre it if there are no label offsets. -@@ -88,7 +83,7 @@ class Button(Widget): - @text.setter - def text(self, new_text): - self._text_raw = new_text -- self._text = "< {} >".format(new_text) if self._add_box else new_text -+ self._text = f"< {new_text} >" if self._add_box else new_text - - @property - def value(self): -Index: asciimatics-1.14.0/asciimatics/widgets/checkbox.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/checkbox.py -+++ asciimatics-1.14.0/asciimatics/widgets/checkbox.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module defines a checkbox widget""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.widgets.widget import Widget - -@@ -27,7 +22,7 @@ class CheckBox(Widget): - - Also see the common keyword arguments in :py:obj:`.Widget`. - """ -- super(CheckBox, self).__init__(name, **kwargs) -+ super().__init__(name, **kwargs) - self._text = text - self._label = label - self._on_change = on_change -@@ -36,7 +31,7 @@ class CheckBox(Widget): - self._draw_label() - - # Render this checkbox. -- check_char = u"✓" if self._frame.canvas.unicode_aware else "X" -+ check_char = "✓" if self._frame.canvas.unicode_aware else "X" - (colour, attr, bg) = self._pick_colours("control", self._has_focus) - self._frame.canvas.print_at( - "[{}] ".format(check_char if self._value else " "), -Index: asciimatics-1.14.0/asciimatics/widgets/datepicker.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/datepicker.py -+++ asciimatics-1.14.0/asciimatics/widgets/datepicker.py -@@ -1,12 +1,5 @@ --# -*- coding: utf-8 -*- - """This module defines a datepicker widget""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range --from datetime import date --from datetime import datetime -+from datetime import date, datetime - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.exceptions import InvalidFields - from asciimatics.screen import Screen -@@ -32,7 +25,7 @@ class _DatePickerPopup(_TempPopup): - if year_range is None: - year_range = range(now.year - 50, now.year + 50) - self._days = ListBox(3, -- [("{:02}".format(x), x) for x in range(1, 32)], -+ [(f"{x:02}", x) for x in range(1, 32)], - centre=True, - validator=self._check_date) - self._months = ListBox(3, -@@ -41,13 +34,13 @@ class _DatePickerPopup(_TempPopup): - centre=True, - on_change=self._refresh_day) - self._years = ListBox(3, -- [("{:04}".format(x), x) for x in year_range], -+ [(f"{x:04}", x) for x in year_range], - centre=True, - on_change=self._refresh_day) - - # Construct the Frame - location = parent.get_location() -- super(_DatePickerPopup, self).__init__(parent.frame.screen, -+ super().__init__(parent.frame.screen, - parent, - location[0] - 1, location[1] - 2, - 13, 5) -@@ -102,7 +95,7 @@ class DatePicker(Widget): - - Also see the common keyword arguments in :py:obj:`.Widget`. - """ -- super(DatePicker, self).__init__(name, **kwargs) -+ super().__init__(name, **kwargs) - self._label = label - self._on_change = on_change - self._value = datetime.now().date() -Index: asciimatics-1.14.0/asciimatics/widgets/divider.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/divider.py -+++ asciimatics-1.14.0/asciimatics/widgets/divider.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module defines a divider between widgets""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from asciimatics.widgets.widget import Widget - - -@@ -21,16 +16,16 @@ class Divider(Widget): - :param line_char: Optional character to use for drawing the line. - """ - # Dividers have no value and so should have no name for look-ups either. -- super(Divider, self).__init__(None, tab_stop=False) -+ super().__init__(None, tab_stop=False) - self._draw_line = draw_line - self._required_height = height - self._line_char = line_char - - def register_frame(self, frame): - # Update line drawing character if needed once we have a canvas to query. -- super(Divider, self).register_frame(frame) -+ super().register_frame(frame) - if self._line_char is None: -- self._line_char = u"─" if self._frame.canvas.unicode_aware else "-" -+ self._line_char = "─" if self._frame.canvas.unicode_aware else "-" - - def process_event(self, event): - # Dividers have no user interactions -Index: asciimatics-1.14.0/asciimatics/widgets/dropdownlist.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/dropdownlist.py -+++ asciimatics-1.14.0/asciimatics/widgets/dropdownlist.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module defines a dropdown list widget""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.screen import Screen - from asciimatics.widgets.divider import Divider -@@ -40,7 +35,7 @@ class _DropdownPopup(_TempPopup): - else: - width = parent.width - # Construct the Frame -- super(_DropdownPopup, self).__init__(parent.frame.screen, -+ super().__init__(parent.frame.screen, - parent, - location[0], start_line, - width, height) -@@ -53,7 +48,7 @@ class _DropdownPopup(_TempPopup): - divider = Divider() - divider.disabled = True - self._list = ListBox(Widget.FILL_FRAME, -- [(" {}".format(i[0]), i[1]) for i in parent.options], -+ [(f" {i[0]}", i[1]) for i in parent.options], - add_scroll_bar=len(parent.options) > height - 4, - on_select=self.close, on_change=self._link) - layout.add_widget(self._list if reverse else self._field, 0) -@@ -96,7 +91,7 @@ class DropdownList(Widget): - - Also see the common keyword arguments in :py:obj:`.Widget`. - """ -- super(DropdownList, self).__init__(name, **kwargs) -+ super().__init__(name, **kwargs) - self._label = label - self._on_change = on_change - self._child = None -Index: asciimatics-1.14.0/asciimatics/widgets/filebrowser.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/filebrowser.py -+++ asciimatics-1.14.0/asciimatics/widgets/filebrowser.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module defines a file browser selection""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from re import compile as re_compile - import os - import unicodedata -@@ -31,7 +26,7 @@ class FileBrowser(MultiColumnListBox): - you must use a regex that matches to the end of the line - e.g. use ".*\.txt$" to find files ending - with ".txt". This ensures that you don't accidentally pick up files containing the filter. - """ -- super(FileBrowser, self).__init__( -+ super().__init__( - height, - [0, ">8", ">14"], - [], -@@ -55,7 +50,7 @@ class FileBrowser(MultiColumnListBox): - if not self._initialized: - self._populate_list(self._root) - self._initialized = True -- super(FileBrowser, self).update(frame_no) -+ super().update(frame_no) - - def _on_selection(self): - """ -@@ -118,16 +113,16 @@ class FileBrowser(MultiColumnListBox): - details = namedtuple("stat_type", "st_size st_mtime") - details.st_size = 0 - details.st_mtime = 0 -- name = "|-- {}".format(my_file) -+ name = f"|-- {my_file}" - tree = tree_files - if os.path.isdir(full_path): - tree = tree_dirs - if os.path.islink(full_path): - # Show links separately for directories - real_path = os.path.realpath(full_path) -- name = "|-+ {} -> {}".format(my_file, real_path) -+ name = f"|-+ {my_file} -> {real_path}" - else: -- name = "|-+ {}".format(my_file) -+ name = f"|-+ {my_file}" - elif self._file_filter and not self._file_filter.match(my_file): - # Skip files that don't match the filter (if present) - continue -@@ -141,11 +136,11 @@ class FileBrowser(MultiColumnListBox): - real_path = None - if real_path and os.path.exists(real_path): - details = os.stat(real_path) -- name = "|-- {} -> {}".format(my_file, real_path) -+ name = f"|-- {my_file} -> {real_path}" - else: - # Both broken directory and file links fall to this case. - # Actually using the files will cause a FileNotFound exception -- name = "|-- {} -> {}".format(my_file, real_path) -+ name = f"|-- {my_file} -> {real_path}" - - # Normalize names for MacOS and then add to the list. - tree.append(([unicodedata.normalize("NFC", name), -Index: asciimatics-1.14.0/asciimatics/widgets/frame.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/frame.py -+++ asciimatics-1.14.0/asciimatics/widgets/frame.py -@@ -1,10 +1,4 @@ --# -*- coding: utf-8 -*- - """This module defines a class to display widgets""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range - from copy import copy, deepcopy - from logging import getLogger - from wcwidth import wcswidth -@@ -152,7 +146,7 @@ class Frame(Effect): - receiving input events. - :param can_scroll: Whether a scrollbar should be available on the border, or not. - """ -- super(Frame, self).__init__(screen) -+ super().__init__(screen) - self._focus = 0 - self._max_height = 0 - self._layouts = [] -@@ -601,7 +595,7 @@ class Frame(Effect): - self._focus = len(self._layouts) - 1 - if self._focus >= len(self._layouts): - self._focus = 0 -- logger.debug("Trying tab to layout {}".format(self._focus)) -+ logger.debug(f"Trying tab to layout {self._focus}") - try: - if direction > 0: - self._layouts[self._focus].focus(force_first=True) -Index: asciimatics-1.14.0/asciimatics/widgets/label.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/label.py -+++ asciimatics-1.14.0/asciimatics/widgets/label.py -@@ -1,10 +1,4 @@ --# -*- coding: utf-8 -*- - """This mdoule implements a widget to give a text label""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import str - from asciimatics.widgets.widget import Widget - from asciimatics.widgets.utilities import _split_text - -@@ -26,7 +20,7 @@ class Label(Widget): - - """ - # Labels have no value and so should have no name for look-ups either. -- super(Label, self).__init__(name, tab_stop=False) -+ super().__init__(name, tab_stop=False) - - # Although this is a label, we don't want it to contribute to the layout - # tab calculations, so leave internal `_label` value as None. -Index: asciimatics-1.14.0/asciimatics/widgets/layout.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/layout.py -+++ asciimatics-1.14.0/asciimatics/widgets/layout.py -@@ -1,11 +1,4 @@ --# -*- coding: utf-8 -*- - """This module implements the displaying of widgets appropriately""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range --from builtins import object - from logging import getLogger - from wcwidth import wcswidth - from asciimatics.event import KeyboardEvent, MouseEvent -@@ -19,7 +12,7 @@ from asciimatics.widgets.widget import W - logger = getLogger(__name__) - - --class Layout(object): -+class Layout(): - """ - Widget layout handler. - -Index: asciimatics-1.14.0/asciimatics/widgets/listbox.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/listbox.py -+++ asciimatics-1.14.0/asciimatics/widgets/listbox.py -@@ -1,11 +1,4 @@ --# -*- coding: utf-8 -*- - """This module implements the listbox widget""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import str --from builtins import range - from asciimatics.strings import ColouredText - from asciimatics.widgets.utilities import _enforce_width - from asciimatics.widgets.baselistbox import _BaseListBox -@@ -35,7 +28,7 @@ class ListBox(_BaseListBox): - - options=[("First option", 1), ("Second option", 2)] - """ -- super(ListBox, self).__init__( -+ super().__init__( - height, options, label=label, name=name, parser=parser, on_change=on_change, - on_select=on_select, validator=validator) - self._centre = centre -Index: asciimatics-1.14.0/asciimatics/widgets/multicolumnlistbox.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/multicolumnlistbox.py -+++ asciimatics-1.14.0/asciimatics/widgets/multicolumnlistbox.py -@@ -1,13 +1,6 @@ --# -*- coding: utf-8 -*- - """This module implements the widget for a multiple column list box""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import str --from builtins import range - from re import match as re_match --from future.moves.itertools import zip_longest -+from itertools import zip_longest - from asciimatics.strings import ColouredText - from asciimatics.widgets.utilities import _enforce_width - from asciimatics.widgets.baselistbox import _BaseListBox -Index: asciimatics-1.14.0/asciimatics/widgets/popupdialog.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/popupdialog.py -+++ asciimatics-1.14.0/asciimatics/widgets/popupdialog.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module implements a Pop up dialog message box""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from inspect import isfunction - from functools import partial - from wcwidth import wcswidth -@@ -55,7 +50,7 @@ class PopUpDialog(Frame): - - # Construct the Frame - self._data = {"message": self._message} -- super(PopUpDialog, self).__init__( -+ super().__init__( - screen, height, width, self._data, has_shadow=has_shadow, is_modal=True) - - # Build up the message box -Index: asciimatics-1.14.0/asciimatics/widgets/popupmenu.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/popupmenu.py -+++ asciimatics-1.14.0/asciimatics/widgets/popupmenu.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module implements a pop up menu widget""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from collections import defaultdict - from functools import partial - from asciimatics.event import KeyboardEvent, MouseEvent -@@ -42,7 +37,7 @@ class PopupMenu(Frame): - y -= h - 1 - - # Construct the Frame -- super(PopupMenu, self).__init__( -+ super().__init__( - screen, h, w, x=x, y=y, has_border=False, can_scroll=False, is_modal=True, hover_focus=True) - - # Build the widget to display the time selection. -@@ -72,4 +67,4 @@ class PopupMenu(Frame): - event = None - if event is None: - self._destroy() -- return super(PopupMenu, self).process_event(event) -+ return super().process_event(event) -Index: asciimatics-1.14.0/asciimatics/widgets/radiobuttons.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/radiobuttons.py -+++ asciimatics-1.14.0/asciimatics/widgets/radiobuttons.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module implements the widget for radio buttons""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.screen import Screen - from asciimatics.widgets.widget import Widget -@@ -27,7 +22,7 @@ class RadioButtons(Widget): - - Also see the common keyword arguments in :py:obj:`.Widget`. - """ -- super(RadioButtons, self).__init__(name, **kwargs) -+ super().__init__(name, **kwargs) - self._options = options - self._label = label - self._selection = 0 -@@ -38,7 +33,7 @@ class RadioButtons(Widget): - self._draw_label() - - # Decide on check char -- check_char = u"•" if self._frame.canvas.unicode_aware else "X" -+ check_char = "•" if self._frame.canvas.unicode_aware else "X" - - # Render the list of radio buttons. - for i, (text, _) in enumerate(self._options): -@@ -46,7 +41,7 @@ class RadioButtons(Widget): - fg2, attr2, bg2 = self._pick_colours("field", self._has_focus and i == self._selection) - check = check_char if i == self._selection else " " - self._frame.canvas.print_at( -- "({}) ".format(check), -+ f"({check}) ", - self._x + self._offset, - self._y + i, - fg, attr, bg) -Index: asciimatics-1.14.0/asciimatics/widgets/scrollbar.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/scrollbar.py -+++ asciimatics-1.14.0/asciimatics/widgets/scrollbar.py -@@ -1,14 +1,6 @@ --# -*- coding: utf-8 -*- - """This module implements a scroll bar capability for widgets""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range --from builtins import object - -- --class _ScrollBar(object): -+class _ScrollBar(): - """ - Internal object to provide vertical scroll bars for widgets. - """ -@@ -48,8 +40,8 @@ class _ScrollBar(object): - Draw the scroll bar. - """ - # Sort out chars -- cursor = u"█" if self._canvas.unicode_aware else "O" -- back = u"░" if self._canvas.unicode_aware else "|" -+ cursor = "█" if self._canvas.unicode_aware else "O" -+ back = "░" if self._canvas.unicode_aware else "|" - - # Now draw... - try: -Index: asciimatics-1.14.0/asciimatics/widgets/temppopup.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/temppopup.py -+++ asciimatics-1.14.0/asciimatics/widgets/temppopup.py -@@ -1,9 +1,4 @@ --# -*- coding: utf-8 -*- - """This module implements a base class for popups""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from collections import defaultdict - from abc import abstractmethod - from asciimatics.event import KeyboardEvent, MouseEvent -@@ -27,7 +22,7 @@ class _TempPopup(Frame): - :param h: The height of the desired pop-up. - """ - # Construct the Frame -- super(_TempPopup, self).__init__( -+ super().__init__( - screen, h, w, x=x, y=y, has_border=True, can_scroll=False, is_modal=True) - - # Set up the new palette for this Frame -@@ -63,7 +58,7 @@ class _TempPopup(Frame): - except InvalidFields: - # Nothing to do as we've already prevented the Effect from being removed. - pass -- return super(_TempPopup, self).process_event(event) -+ return super().process_event(event) - - def close(self, cancelled=False): - """ -Index: asciimatics-1.14.0/asciimatics/widgets/text.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/text.py -+++ asciimatics-1.14.0/asciimatics/widgets/text.py -@@ -1,10 +1,4 @@ --# -*- coding: utf-8 -*- - """This widget implements a text based input field""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import chr - from re import match - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.screen import Screen -@@ -38,7 +32,7 @@ class Text(Widget): - - Also see the common keyword arguments in :py:obj:`.Widget`. - """ -- super(Text, self).__init__(name, **kwargs) -+ super().__init__(name, **kwargs) - self._label = label - self._column = 0 - self._start_column = 0 -@@ -50,7 +44,7 @@ class Text(Widget): - - def set_layout(self, x, y, offset, w, h): - # Do the usual layout work. then apply max length to resulting dimensions. -- super(Text, self).set_layout(x, y, offset, w, h) -+ super().set_layout(x, y, offset, w, h) - if self._max_length: - # Allow extra char for cursor, so contents don't scroll at required length - self._w = min(self._w, self._max_length + self._offset + 1) -Index: asciimatics-1.14.0/asciimatics/widgets/textbox.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/textbox.py -+++ asciimatics-1.14.0/asciimatics/widgets/textbox.py -@@ -1,11 +1,4 @@ --# -*- coding: utf-8 -*- - """This module implements a multi line editing text box""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import chr --from builtins import str - from copy import copy - from logging import getLogger - from asciimatics.event import KeyboardEvent, MouseEvent -@@ -44,7 +37,7 @@ class TextBox(Widget): - - Also see the common keyword arguments in :py:obj:`.Widget`. - """ -- super(TextBox, self).__init__(name, **kwargs) -+ super().__init__(name, **kwargs) - self._label = label - self._line = 0 - self._column = 0 -Index: asciimatics-1.14.0/asciimatics/widgets/timepicker.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/timepicker.py -+++ asciimatics-1.14.0/asciimatics/widgets/timepicker.py -@@ -1,11 +1,5 @@ --# -*- coding: utf-8 -*- - """This module implements a time picker widget""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from datetime import datetime --from builtins import range - - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.screen import Screen -@@ -27,15 +21,15 @@ class _TimePickerPopup(_TempPopup): - """ - # Construct the Frame - location = parent.get_location() -- super(_TimePickerPopup, self).__init__(parent.frame.screen, -+ super().__init__(parent.frame.screen, - parent, - location[0] - 1, location[1] - 2, - 10 if parent.include_seconds else 7, 5) - - # Build the widget to display the time selection. -- self._hours = ListBox(3, [("{:02}".format(x), x) for x in range(24)], centre=True) -- self._minutes = ListBox(3, [("{:02}".format(x), x) for x in range(60)], centre=True) -- self._seconds = ListBox(3, [("{:02}".format(x), x) for x in range(60)], centre=True) -+ self._hours = ListBox(3, [(f"{x:02}", x) for x in range(24)], centre=True) -+ self._minutes = ListBox(3, [(f"{x:02}", x) for x in range(60)], centre=True) -+ self._seconds = ListBox(3, [(f"{x:02}", x) for x in range(60)], centre=True) - if self._parent.include_seconds: - layout = Layout([2, 1, 2, 1, 2], fill_frame=True) - else: -@@ -77,7 +71,7 @@ class TimePicker(Widget): - - Also see the common keyword arguments in :py:obj:`.Widget`. - """ -- super(TimePicker, self).__init__(name, **kwargs) -+ super().__init__(name, **kwargs) - self._label = label - self._on_change = on_change - self._value = datetime.now().time() -Index: asciimatics-1.14.0/asciimatics/widgets/utilities.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/utilities.py -+++ asciimatics-1.14.0/asciimatics/widgets/utilities.py -@@ -1,18 +1,9 @@ --# -*- coding: utf-8 -*- - """This module defines commonly used pieces for widgets""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from logging import getLogger - from math import sqrt --from builtins import str - from collections import defaultdict - from wcwidth import wcswidth, wcwidth --try: -- from functools import lru_cache --except ImportError: -- from backports.functools_lru_cache import lru_cache -+from functools import lru_cache - from asciimatics.screen import Screen - - # Logging -Index: asciimatics-1.14.0/asciimatics/widgets/verticaldivider.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/verticaldivider.py -+++ asciimatics-1.14.0/asciimatics/widgets/verticaldivider.py -@@ -1,10 +1,4 @@ --# -*- coding: utf-8 -*- - """This module implements a vertical division between widgets""" --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import range - from asciimatics.widgets.widget import Widget - - -@@ -21,7 +15,7 @@ class VerticalDivider(Widget): - """ - :param height: The required height for this divider. - """ -- super(VerticalDivider, self).__init__(None, tab_stop=False) -+ super().__init__(None, tab_stop=False) - self._required_height = height - - def process_event(self, event): -@@ -29,7 +23,7 @@ class VerticalDivider(Widget): - - def update(self, frame_no): - (color, attr, background) = self._frame.palette["borders"] -- vert = u"│" if self._frame.canvas.unicode_aware else "|" -+ vert = "│" if self._frame.canvas.unicode_aware else "|" - for i in range(self._h): - self._frame.canvas.print_at(vert, self._x, self._y + i, color, attr, background) - -Index: asciimatics-1.14.0/asciimatics/widgets/widget.py -=================================================================== ---- asciimatics-1.14.0.orig/asciimatics/widgets/widget.py -+++ asciimatics-1.14.0/asciimatics/widgets/widget.py -@@ -1,17 +1,9 @@ --# -*- coding: utf-8 -*- - """ - This module allows you to create interactive text user interfaces. For more details see - http://asciimatics.readthedocs.io/en/latest/widgets.html - """ --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -- --from builtins import object - from abc import ABCMeta, abstractmethod, abstractproperty - --from future.utils import with_metaclass - from logging import getLogger - from wcwidth import wcswidth - from asciimatics.screen import Screen -@@ -21,7 +13,7 @@ from asciimatics.widgets.utilities impor - logger = getLogger(__name__) - - --class Widget(with_metaclass(ABCMeta, object)): -+class Widget(metaclass=ABCMeta): - """ - A Widget is a re-usable component that can be used to create a simple GUI. - """ -@@ -47,7 +39,7 @@ class Widget(with_metaclass(ABCMeta, obj - :param on_focus: Optional callback whenever this widget gets the focus. - :param on_blur: Optional callback whenever this widget loses the focus. - """ -- super(Widget, self).__init__() -+ super().__init__() - # Internal properties - self._name = name - self._label = None -Index: asciimatics-1.14.0/doc/source/troubleshooting.rst -=================================================================== ---- asciimatics-1.14.0.orig/doc/source/troubleshooting.rst -+++ asciimatics-1.14.0/doc/source/troubleshooting.rst -@@ -288,13 +288,6 @@ It's just not working at all - Some people have reported truly strange issues where things simply don't start up at all. - Symptoms vary wildly from blank screens to other applications or tests running instead. - --If you are hitting something like this, check that you haven't created a file called ``test.py`` --in your project. This is because the ``future`` package, which asciimatics uses for --compatibility with Python 2 and 3, imports the test package. If you happen to have a file called --``test.py`` in your project, this import could pick up your file instead of the built-in package. -- --Shout out to Andrew Penniman for spotting and solving this one! -- - It's too slow! - -------------- - When people say this, they either mean that asciimatics is using too much CPU, or that it is -Index: asciimatics-1.14.0/doc/source/widgets.rst -=================================================================== ---- asciimatics-1.14.0.orig/doc/source/widgets.rst -+++ asciimatics-1.14.0/doc/source/widgets.rst -@@ -91,7 +91,7 @@ basic classes: - - .. code-block:: python - -- class ContactModel(object): -+ class ContactModel(): - def __init__(self): - # Create a database in RAM - self._db = sqlite3.connect(':memory:') -Index: asciimatics-1.14.0/requirements/base.txt -=================================================================== ---- asciimatics-1.14.0.orig/requirements/base.txt -+++ asciimatics-1.14.0/requirements/base.txt -@@ -1,6 +1,3 @@ - wcwidth --mock - pyfiglet >= 0.7.2 --future - setuptools_scm --backports.functools_lru_cache ; python_version < "3.0" -Index: asciimatics-1.14.0/samples/256colour.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/256colour.py -+++ asciimatics-1.14.0/samples/256colour.py -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3 - --from __future__ import division - from asciimatics.effects import Print, Clock - from asciimatics.renderers import FigletText, Rainbow - from asciimatics.scene import Scene -Index: asciimatics-1.14.0/samples/basics.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/basics.py -+++ asciimatics-1.14.0/samples/basics.py -@@ -1,7 +1,5 @@ - #!/usr/bin/env python3 - --from __future__ import division --from builtins import range - import copy - import math - from asciimatics.effects import Cycle, Print, Stars -Index: asciimatics-1.14.0/samples/bg_colours.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/bg_colours.py -+++ asciimatics-1.14.0/samples/bg_colours.py -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3 - --from __future__ import division - from asciimatics.effects import Wipe, Print - from asciimatics.renderers import FigletText, SpeechBubble - from asciimatics.scene import Scene -Index: asciimatics-1.14.0/samples/cogs.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/cogs.py -+++ asciimatics-1.14.0/samples/cogs.py -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3 - --from __future__ import division - from asciimatics.effects import Cog, Print - from asciimatics.renderers import FigletText - from asciimatics.scene import Scene -Index: asciimatics-1.14.0/samples/contact_list.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/contact_list.py -+++ asciimatics-1.14.0/samples/contact_list.py -@@ -9,7 +9,7 @@ import sys - import sqlite3 - - --class ContactModel(object): -+class ContactModel(): - def __init__(self): - # Create a database in RAM. - self._db = sqlite3.connect(':memory:') -Index: asciimatics-1.14.0/samples/credits.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/credits.py -+++ asciimatics-1.14.0/samples/credits.py -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3 - --from __future__ import division - import sys - from pyfiglet import Figlet - -Index: asciimatics-1.14.0/samples/images.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/images.py -+++ asciimatics-1.14.0/samples/images.py -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3 - --from __future__ import division - from asciimatics.effects import BannerText, Print, Scroll - from asciimatics.renderers import ColourImageFile, FigletText, ImageFile - from asciimatics.scene import Scene -Index: asciimatics-1.14.0/samples/maps.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/maps.py -+++ asciimatics-1.14.0/samples/maps.py -@@ -1,8 +1,6 @@ - #!/usr/bin/env python3 - - # -*- coding: utf-8 -*- --from __future__ import division --from __future__ import print_function - import traceback - from math import pi, exp, atan, log, tan, sqrt - import sys -Index: asciimatics-1.14.0/samples/quick_model.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/quick_model.py -+++ asciimatics-1.14.0/samples/quick_model.py -@@ -8,7 +8,7 @@ from asciimatics.exceptions import Resiz - import sys - - --class ContactModel(object): -+class ContactModel(): - def __init__(self): - # Current contact when editing. - self.current_id = None -Index: asciimatics-1.14.0/samples/ray_casting.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/ray_casting.py -+++ asciimatics-1.14.0/samples/ray_casting.py -@@ -1,10 +1,6 @@ - #!/usr/bin/env python3 - - # -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - import sys - from math import sin, cos, pi, copysign, floor - from asciimatics.effects import Effect -@@ -43,7 +39,7 @@ XXXXXXXXXXXXXX X - IMAGE_HEIGHT = 64 - - --class Image(object): -+class Image(): - """ - Class to handle image stripe rendering. - """ -@@ -77,7 +73,7 @@ class Image(object): - pass - - --class Sprite(object): -+class Sprite(): - """ - Dynamically sized sprite. - """ -@@ -97,7 +93,7 @@ class Sprite(object): - self._state.screen, height, x, int(image_x * IMAGE_HEIGHT / height)) - - --class GameState(object): -+class GameState(): - """ - Persistent state for this application. - """ -Index: asciimatics-1.14.0/samples/simple.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/simple.py -+++ asciimatics-1.14.0/samples/simple.py -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3 - --from __future__ import division - from asciimatics.effects import Cycle, Stars - from asciimatics.renderers import FigletText - from asciimatics.scene import Scene -Index: asciimatics-1.14.0/samples/xmas.py -=================================================================== ---- asciimatics-1.14.0.orig/samples/xmas.py -+++ asciimatics-1.14.0/samples/xmas.py -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3 - --from __future__ import division - from asciimatics.effects import Cycle, Snow, Print - from asciimatics.renderers import FigletText, StaticRenderer - from asciimatics.scene import Scene -Index: asciimatics-1.14.0/tests/mock_objects.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/mock_objects.py -+++ asciimatics-1.14.0/tests/mock_objects.py -@@ -15,7 +15,7 @@ class MockEffect(Effect): - :param next_scene: The next scene to move to (if stop=False) - :param frame_rate: The frame rate for updates. - """ -- super(MockEffect, self).__init__(None, **kwargs) -+ super().__init__(None, **kwargs) - self.stop_called = False - self.reset_called = False - self.event_called = False -Index: asciimatics-1.14.0/tests/renderers/test_base.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/renderers/test_base.py -+++ asciimatics-1.14.0/tests/renderers/test_base.py -@@ -1,9 +1,3 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import str - import unittest - from asciimatics.renderers import StaticRenderer - from asciimatics.screen import Screen -Index: asciimatics-1.14.0/tests/renderers/test_charts.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/renderers/test_charts.py -+++ asciimatics-1.14.0/tests/renderers/test_charts.py -@@ -1,9 +1,3 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import str - import unittest - from asciimatics.constants import ASCII_LINE, SINGLE_LINE - from asciimatics.renderers import BarChart, VBarChart -Index: asciimatics-1.14.0/tests/renderers/test_images.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/renderers/test_images.py -+++ asciimatics-1.14.0/tests/renderers/test_images.py -@@ -1,8 +1,3 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - import unittest - import os - import sys -Index: asciimatics-1.14.0/tests/renderers/test_other.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/renderers/test_other.py -+++ asciimatics-1.14.0/tests/renderers/test_other.py -@@ -1,9 +1,3 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import str - import unittest - import os - import sys -@@ -24,9 +18,9 @@ class TestRendererOthers(unittest.TestCa - str(renderer), - " _ _ _ \n" + - "| |__ ___| | | ___ \n" + -- "| '_ \ / _ \ | |/ _ \ \n" + -+ "| '_ \\ / _ \\ | |/ _ \\ \n" + - "| | | | __/ | | (_) |\n" + -- "|_| |_|\___|_|_|\___/ \n" + -+ "|_| |_|\\___|_|_|\\___/ \n" + - " \n") - - def test_bubble(self): -@@ -61,9 +55,9 @@ class TestRendererOthers(unittest.TestCa - # Unicode rendering. - renderer = SpeechBubble("hello", uni=True) - self.assertEqual(str(renderer), -- u"╭───────╮\n" -- u"│ hello │\n" -- u"╰───────╯") -+ "╭───────╮\n" -+ "│ hello │\n" -+ "╰───────╯") - - # Multiline text rendering - text = "Hello\n" \ -Index: asciimatics-1.14.0/tests/renderers/test_players.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/renderers/test_players.py -+++ asciimatics-1.14.0/tests/renderers/test_players.py -@@ -1,9 +1,3 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals --from builtins import str - import unittest - import os - from asciimatics.renderers import AnsiArtPlayer, AsciinemaPlayer -Index: asciimatics-1.14.0/tests/test_effects.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/test_effects.py -+++ asciimatics-1.14.0/tests/test_effects.py -@@ -1,7 +1,6 @@ --from builtins import chr - import unittest - from datetime import datetime --from mock.mock import MagicMock, patch -+from unittest.mock import MagicMock, patch - from random import randint - import os - import sys -Index: asciimatics-1.14.0/tests/test_events.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/test_events.py -+++ asciimatics-1.14.0/tests/test_events.py -@@ -23,7 +23,7 @@ class TestEvents(unittest.TestCase): - self.assertEqual(event.x, x) - self.assertEqual(event.y, y) - self.assertEqual(event.buttons, buttons) -- self.assertIn("({}, {})".format(x, y), str(event)) -+ self.assertIn(f"({x}, {y})", str(event)) - self.assertIn(str(buttons), str(event)) - - -Index: asciimatics-1.14.0/tests/test_parsers.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/test_parsers.py -+++ asciimatics-1.14.0/tests/test_parsers.py -@@ -1,8 +1,3 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - import unittest - from asciimatics.parsers import AsciimaticsParser, AnsiTerminalParser, ControlCodeParser, Parser - import asciimatics.constants as constants -Index: asciimatics-1.14.0/tests/test_screen.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/test_screen.py -+++ asciimatics-1.14.0/tests/test_screen.py -@@ -1,18 +1,9 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals -- - import os --from mock import MagicMock - from random import randint - import unittest -+from unittest.mock import MagicMock - import sys - import time --from builtins import str --from builtins import chr --from builtins import bytes - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.exceptions import StopApplication, NextScene - try: -@@ -64,7 +55,7 @@ class TestScreen(unittest.TestCase): - try: - char, _, _, _ = canvas.get_from(x, y) - except Exception: -- raise RuntimeError("{} {}".format(x, y)) -+ raise RuntimeError(f"{x} {y}") - output += chr(char) - output += "\n" - self.assertEqual(output, expected) -@@ -593,7 +584,7 @@ class TestScreen(unittest.TestCase): - # we don't catch interrupts). Still a good basic check for - # input, though. - event = win32console.PyINPUT_RECORDType(win32console.KEY_EVENT) -- event.Char = u"\03" -+ event.Char = "\03" - event.KeyDown = 1 - event.RepeatCount = 1 - event.ControlKeyState = win32con.LEFT_CTRL_PRESSED -@@ -656,8 +647,8 @@ class TestScreen(unittest.TestCase): - event.VirtualKeyCode = ord(chr(char).upper()) - else: - # Lookup in mapping dicts -- reverse = dict((v, k) for k, v in -- screen._EXTRA_KEY_MAP.items()) -+ reverse = {v: k for k, v in -+ screen._EXTRA_KEY_MAP.items()} - if char in reverse: - event.VirtualKeyCode = reverse[char] - else: -@@ -665,8 +656,8 @@ class TestScreen(unittest.TestCase): - if char == Screen.KEY_BACK_TAB: - char = Screen.KEY_TAB - event.ControlKeyState = win32con.SHIFT_PRESSED -- reverse = dict((v, k) for k, v in -- screen._KEY_MAP.items()) -+ reverse = {v: k for k, v in -+ screen._KEY_MAP.items()} - event.VirtualKeyCode = reverse[char] - event.KeyDown = 1 - screen._stdin.WriteConsoleInput([event]) -@@ -680,8 +671,8 @@ class TestScreen(unittest.TestCase): - for c in reversed(bytes(chr(char).encode("utf-8"))): - curses.ungetch(c) - else: -- reverse = dict((v, k) for k, v in -- screen._KEY_MAP.items()) -+ reverse = {v: k for k, v in -+ screen._KEY_MAP.items()} - curses.ungetch(reverse[char]) - - @staticmethod -@@ -736,15 +727,15 @@ class TestScreen(unittest.TestCase): - self.assertIsNone(screen.get_key()) - - # Check that unicode input also works -- self._inject_key(screen, ord(u"├")) -+ self._inject_key(screen, ord("├")) - ch = screen.get_event() -- self.assertEqual(ch.key_code, ord(u"├")) -+ self.assertEqual(ch.key_code, ord("├")) - self.assertIsNone(screen.get_event()) - - # Check that unicode input colliding with curses KEY_MAP also works (code: 263) -- self._inject_key(screen, ord(u"ć")) -+ self._inject_key(screen, ord("ć")) - ch = screen.get_event() -- self.assertEqual(ch.key_code, ord(u"ć")) -+ self.assertEqual(ch.key_code, ord("ć")) - self.assertIsNone(screen.get_event()) - - Screen.wrapper(internal_checks, height=15, unicode_aware=True) -@@ -901,7 +892,7 @@ class TestScreen(unittest.TestCase): - canvas.reset() - canvas.print_at("你確", -1, 0) - canvas.print_at("你確", canvas.width - 1, 0) -- self.assert_line_equals(canvas, u" 確確 ") -+ self.assert_line_equals(canvas, " 確確 ") - - def test_cjk_glyphs_overwrite(self): - """ -@@ -919,7 +910,7 @@ class TestScreen(unittest.TestCase): - - # Half-glyph appears as an "x" to show error and then double-width glyphs are returned - # twice, reflecting their extra width. -- self.assert_line_equals(screen, u"x你你確確 ", y=1, length=6) -+ self.assert_line_equals(screen, "x你你確確 ", y=1, length=6) - - def test_save_signal_state(self): - """Tests that the signal state class works properly. -Index: asciimatics-1.14.0/tests/test_strings.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/test_strings.py -+++ asciimatics-1.14.0/tests/test_strings.py -@@ -1,8 +1,3 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from datetime import datetime - import time - import unittest -Index: asciimatics-1.14.0/tests/test_utilities.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/test_utilities.py -+++ asciimatics-1.14.0/tests/test_utilities.py -@@ -1,8 +1,3 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from datetime import datetime - import time - import unittest -Index: asciimatics-1.14.0/tests/test_widgets.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/test_widgets.py -+++ asciimatics-1.14.0/tests/test_widgets.py -@@ -1,17 +1,8 @@ --# -*- coding: utf-8 -*- --from __future__ import division --from __future__ import absolute_import --from __future__ import print_function --from __future__ import unicode_literals - from datetime import date, time - from time import sleep --from mock import patch --from builtins import ord --from builtins import chr --from builtins import str - import unittest - import sys --from mock.mock import MagicMock -+from unittest.mock import MagicMock, patch - from asciimatics.event import KeyboardEvent, MouseEvent - from asciimatics.exceptions import NextScene, StopApplication, InvalidFields - from asciimatics.scene import Scene -@@ -24,9 +15,9 @@ from asciimatics.parsers import Asciimat - from asciimatics.strings import ColouredText - - --class TestFrame(Frame): -+class _TestFrame(Frame): - def __init__(self, screen, has_border=True, can_scroll=True, reduce_cpu=False, label_height=1): -- super(TestFrame, self).__init__(screen, -+ super().__init__(screen, - screen.height, - screen.width, - name="Test Form", -@@ -118,9 +109,9 @@ class TestFrame(Frame): - raise StopApplication("User requested exit") - - --class TestFrame2(Frame): -+class _TestFrame2(Frame): - def __init__(self, screen, init_values): -- super(TestFrame2, self).__init__(screen, -+ super().__init__(screen, - screen.height, - screen.width, - data={"selected": "None"}, -@@ -177,17 +168,17 @@ class TestFrame2(Frame): - raise StopApplication("User pressed quit") - - --class TestFrame3(Frame): -+class _TestFrame3(Frame): - def __init__(self, screen): -- super(TestFrame3, self).__init__(screen, 10, 20, -+ super().__init__(screen, 10, 20, - name="Blank", - has_shadow=True) - self.fix() - - --class TestFrame4(Frame): -+class _TestFrame4(Frame): - def __init__(self, screen, file_filter=None): -- super(TestFrame4, self).__init__( -+ super().__init__( - screen, screen.height, screen.width, has_border=False, can_scroll=False, name="My Form") - - # State tracking for callbacks -@@ -213,9 +204,9 @@ class TestFrame4(Frame): - self.highlighted = self.file_list.value - - --class TestFrame5(Frame): -+class _TestFrame5(Frame): - def __init__(self, screen): -- super(TestFrame5, self).__init__( -+ super().__init__( - screen, screen.height, screen.width, has_border=True, name="My Form") - - # Simple full-page Widget -@@ -238,9 +229,9 @@ class TestFrame5(Frame): - self.changed = True - - --class TestFrame6(Frame): -+class _TestFrame6(Frame): - def __init__(self, screen): -- super(TestFrame6, self).__init__( -+ super().__init__( - screen, screen.height, screen.width, has_border=True, name="My Form") - - # Simple full-page Widget -@@ -296,7 +287,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - - # Should be empty on construction - self.assertEqual(form.data, {}) -@@ -323,7 +314,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check initial rendering -@@ -379,7 +370,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=True) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check initial rendering -@@ -435,7 +426,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas, has_border=False, can_scroll=False) -+ form = _TestFrame(canvas, has_border=False, can_scroll=False) - form.reset() - - # Check initial rendering -@@ -475,7 +466,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas, has_border=False, can_scroll=True) -+ form = _TestFrame(canvas, has_border=False, can_scroll=True) - form.reset() - - # Check initial rendering -@@ -499,7 +490,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - self.process_keys(form, - ["ABC\nDEF", "GHI", "jkl", "MN", " ", " ", "", " "], -@@ -531,7 +522,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check basic movement keys -@@ -603,7 +594,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check basic movement keys -@@ -646,7 +637,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check that save still works with no validation. -@@ -676,7 +667,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check basic selection keys -@@ -703,7 +694,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check basic selection keys - including limit checking -@@ -744,7 +735,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = MagicMock(spec=Scene) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.register_scene(scene) - form.reset() - -@@ -790,7 +781,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # If the Frame loses the focus it must not return a focussed widget. -@@ -808,7 +799,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # A Frame with a valid focus should return the widget in focus. -@@ -824,7 +815,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check default focus at start is first visible widget -@@ -901,7 +892,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = MagicMock(spec=Scene) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame2( -+ form = _TestFrame2( - canvas, [("One", 1), ("Two is now quite a bit longer than before", 2)]) - form.register_scene(scene) - form.reset() -@@ -990,7 +981,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = MagicMock(spec=Scene) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame2(canvas, [("One", 1), ("Two", 2)]) -+ form = _TestFrame2(canvas, [("One", 1), ("Two", 2)]) - form.register_scene(scene) - form.reset() - -@@ -1650,9 +1641,9 @@ class TestWidgets(unittest.TestCase): - [3, 5, 0], - [ - (["1", "2", "3"], 1), -- ([u"你", u"確", u"定"], 2), -+ (["你", "確", "定"], 2), - ], -- titles=[u"你確定嗎?", u"你確定嗎?", u"你確定嗎?"]) -+ titles=["你確定嗎?", "你確定嗎?", "你確定嗎?"]) - text = Text() - text_box = TextBox(3) - form.add_layout(layout) -@@ -1664,23 +1655,23 @@ class TestWidgets(unittest.TestCase): - form.reset() - - # Set some interesting values... -- text.value = u"你確定嗎? 你確定嗎? 你確定嗎?" -- text_box.value = [u"你確定嗎", u"?"] -+ text.value = "你確定嗎? 你確定嗎? 你確定嗎?" -+ text_box.value = ["你確定嗎", "?"] - - # Check that the CJK characters render correctly - no really this is correctly aligned! - form.update(0) - self.assert_canvas_equals( - canvas, -- u"你你 你你確確 你你確確定定嗎嗎?? \n" + -- u"1 2 3 \n" + -- u"你你 確確 定定 \n" + -- u" \n" + -- u"你你確確定定嗎嗎?? 你你確確定定嗎嗎?? 你你確確定定嗎嗎?? \n" + -- u"你你確確定定嗎嗎 \n" + -- u"?? \n" + -- u" \n" + -- u" \n" + -- u" \n") -+ "你你 你你確確 你你確確定定嗎嗎?? \n" + -+ "1 2 3 \n" + -+ "你你 確確 定定 \n" + -+ " \n" + -+ "你你確確定定嗎嗎?? 你你確確定定嗎嗎?? 你你確確定定嗎嗎?? \n" + -+ "你你確確定定嗎嗎 \n" + -+ "?? \n" + -+ " \n" + -+ " \n" + -+ " \n") - - # Check that mouse input takes into account the glyph width - self.process_mouse(form, [(5, 4, MouseEvent.LEFT_CLICK)]) -@@ -1688,14 +1679,14 @@ class TestWidgets(unittest.TestCase): - self.process_mouse(form, [(2, 4, MouseEvent.LEFT_CLICK)]) - self.process_keys(form, ["p"]) - form.save() -- self.assertEqual(text.value, u"你p確b定嗎? 你確定嗎? 你確定嗎?") -+ self.assertEqual(text.value, "你p確b定嗎? 你確定嗎? 你確定嗎?") - - self.process_mouse(form, [(2, 5, MouseEvent.LEFT_CLICK)]) - self.process_keys(form, ["p"]) - self.process_mouse(form, [(1, 6, MouseEvent.LEFT_CLICK)]) - self.process_keys(form, ["b"]) - form.save() -- self.assertEqual(text_box.value, [u"你p確定嗎", u"b?"]) -+ self.assertEqual(text_box.value, ["你p確定嗎", "b?"]) - - def test_shadow(self): - """ -@@ -1751,8 +1742,8 @@ class TestWidgets(unittest.TestCase): - self.assertEqual(scene2.effects[0]._buttons, ["Yes", "No"]) - - # Check that normal Frame data gets copied to the new Scene. -- frame = TestFrame(canvas) -- frame2 = TestFrame(canvas) -+ frame = _TestFrame(canvas) -+ frame2 = _TestFrame(canvas) - scene2 = Scene([frame2], 10) - frame.register_scene(scene) - frame2.register_scene(scene) -@@ -1770,7 +1761,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # With no special CPU consideration, and a cursor to animate, there -@@ -1792,7 +1783,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas, reduce_cpu=True) -+ form = _TestFrame(canvas, reduce_cpu=True) - form.reset() - - # In this mode, it shouldn't matter where we are on the Frame - all -@@ -1810,7 +1801,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas, reduce_cpu=True) -+ form = _TestFrame(canvas, reduce_cpu=True) - self.assertEqual(form.stop_frame, -1) - - def test_empty_frame(self): -@@ -1820,7 +1811,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) - scene = MagicMock(spec=Scene) -- form = TestFrame3(canvas) -+ form = _TestFrame3(canvas) - form.register_scene(scene) - form.reset() - -@@ -1844,7 +1835,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas) -+ form = _TestFrame(canvas) - form.reset() - - # Check initial rendering -@@ -1888,7 +1879,7 @@ class TestWidgets(unittest.TestCase): - """ - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame(canvas, label_height=2) -+ form = _TestFrame(canvas, label_height=2) - form.reset() - - # Check Label obeys required height -@@ -2004,7 +1995,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = MagicMock(spec=Scene) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame4(canvas) -+ form = _TestFrame4(canvas) - form.register_scene(scene) - form.reset() - -@@ -2038,7 +2029,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = MagicMock(spec=Scene) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame4(canvas) -+ form = _TestFrame4(canvas) - form.register_scene(scene) - form.reset() - -@@ -2088,7 +2079,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = MagicMock(spec=Scene) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame4(canvas) -+ form = _TestFrame4(canvas) - form.register_scene(scene) - form.reset() - -@@ -2181,7 +2172,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = MagicMock(spec=Scene) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame4(canvas, file_filter=r".*\.bmp$") -+ form = _TestFrame4(canvas, file_filter=r".*\.bmp$") - form.register_scene(scene) - form.reset() - -@@ -2219,7 +2210,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = Scene([], duration=-1) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame5(canvas) -+ form = _TestFrame5(canvas) - scene.add_effect(form) - scene.reset() - -@@ -2336,7 +2327,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = Scene([], duration=-1) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame5(canvas) -+ form = _TestFrame5(canvas) - scene.add_effect(form) - scene.reset() - -@@ -2566,7 +2557,7 @@ class TestWidgets(unittest.TestCase): - layout = Layout([100], fill_frame=True) - form.add_layout(layout) - layout.add_widget(Divider(draw_line=False, height=7)) -- dd_list = DropdownList([("Item {}".format(i), i) for i in range(10)]) -+ dd_list = DropdownList([(f"Item {i}", i) for i in range(10)]) - layout.add_widget(dd_list) - form.fix() - form.register_scene(scene) -@@ -2620,7 +2611,7 @@ class TestWidgets(unittest.TestCase): - layout = Layout([100], fill_frame=True) - form.add_layout(layout) - layout.add_widget(Divider(draw_line=False, height=7)) -- dd_list = DropdownList([("Item {}".format(i), i) for i in range(10)], fit=True) -+ dd_list = DropdownList([(f"Item {i}", i) for i in range(10)], fit=True) - layout.add_widget(dd_list) - form.fix() - form.register_scene(scene) -@@ -2692,7 +2683,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = Scene([], duration=-1) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame5(canvas) -+ form = _TestFrame5(canvas) - scene.add_effect(form) - scene.reset() - -@@ -3405,7 +3396,7 @@ class TestWidgets(unittest.TestCase): - screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) - scene = Scene([], duration=-1) - canvas = Canvas(screen, 10, 40, 0, 0) -- form = TestFrame6(canvas) -+ form = _TestFrame6(canvas) - scene.add_effect(form) - scene.reset() - -Index: asciimatics-1.14.0/tests/test_particles.py -=================================================================== ---- asciimatics-1.14.0.orig/tests/test_particles.py -+++ asciimatics-1.14.0/tests/test_particles.py -@@ -1,5 +1,5 @@ - import unittest --from mock.mock import MagicMock -+from unittest.mock import MagicMock - from asciimatics.particles import ShootScreen, DropScreen, Explosion, Rain, \ - StarFirework, PalmFirework, RingFirework, SerpentFirework - from asciimatics.screen import Screen, Canvas -Index: asciimatics-1.14.0/setup.py -=================================================================== ---- asciimatics-1.14.0.orig/setup.py -+++ asciimatics-1.14.0/setup.py -@@ -66,16 +66,9 @@ setup( - 'pyfiglet >= 0.7.2', - 'Pillow >= 2.7.0', - 'wcwidth', -- 'future', -- 'backports.functools_lru_cache;python_version<"3.0"', -+ 'curses' - ], - extras_require={ - ':sys_platform == "win32"': ['pywin32'], - }, -- setup_requires=['setuptools_scm'], -- tests_require=[ -- 'mock', -- 'nose', -- ], -- test_suite='nose.collector', - ) diff --git a/python-asciimatics.changes b/python-asciimatics.changes index 5ca71a6..e9bb704 100644 --- a/python-asciimatics.changes +++ b/python-asciimatics.changes @@ -1,3 +1,19 @@ +------------------------------------------------------------------- +Thu Oct 26 00:25:39 UTC 2023 - Steve Kowalik + +- Update to 1.15.0: + * Dropped support for Python 2, Python 3.9 or above is now required. + * Added support for ColouredText titles in MultiColumnLIstBox. + * Added gutter option to Layout. + * Added speed option to Sprite. + * Fixed bug where moving focus between Frames resulted in no current focus. + * Fixed internal state of RadioButton values to be consistent with selection. + * Fixed handling of zero width modifiers. + * Fixed image conversion to use modern PIL API and sort off-by-one height + error. + * Fixed parser bug returning list instead of colour tuple. +- Drop patch move-to-python3.patch, included upstream. + ------------------------------------------------------------------- Mon Sep 11 04:59:40 UTC 2023 - Steve Kowalik diff --git a/python-asciimatics.spec b/python-asciimatics.spec index dcc22cc..f3cd8ed 100644 --- a/python-asciimatics.spec +++ b/python-asciimatics.spec @@ -17,14 +17,13 @@ Name: python-asciimatics -Version: 1.14.0 +Version: 1.15.0 Release: 0 Summary: Package to replace curses and create ASCII animations License: Apache-2.0 URL: https://github.com/peterbrittain/asciimatics Source: https://files.pythonhosted.org/packages/source/a/asciimatics/asciimatics-%{version}.tar.gz -# PATCH-FIX-UPSTREAM Based on gh#peterbrittain/asciimatics#376 -Patch0: move-to-python3.patch +BuildRequires: %{python_module base >= 3.9} BuildRequires: %{python_module pip} BuildRequires: %{python_module setuptools_scm} BuildRequires: %{python_module wheel}