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', )