Re-enable Python 3.5 support

Change the type annotations to a Python 3.5 supported syntax.  This is
currently all that is needed to be Python 3.5 compatible.  If there are
more substantive changes that we want to make in the future that are
Python 3.5 incompatible, we can look at those going forward.

Fixes: #1292
master
Sean Vig 2019-03-16 15:16:45 -04:00
parent 749dfc9bc6
commit 72f35e2c21
15 changed files with 75 additions and 62 deletions

View File

@ -4,16 +4,22 @@ language: python
matrix:
include:
- python: 3.5
env: TOXENV=py35
- python: 3.6
env: TOXENV=py36
- python: 3.7
env: TOXENV=py37
- python: pypy3.5-6.0
env: TOXENV=pypy3
- python: nightly
env: TOXENV=py-nightly
- python: 3.7
env: TOXENV=packaging
- python: 3.7
env: TOXENV=docs
- python: 3.5
env: TOXENV=pep8
- python: 3.7
env: TOXENV=pep8
- python: 3.7
@ -42,7 +48,7 @@ install:
- if [[ $TOXENV == py* ]]; then pip install coveralls; fi
script:
- travis_wait 30 tox
- tox
notifications:
email: false

View File

@ -18,11 +18,11 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from typing import Dict
from typing import Dict # noqa: F401
class Configurable:
global_defaults: Dict = {}
global_defaults = {} # type: Dict
def __init__(self, **config):
self._variable_defaults = {}

View File

@ -24,7 +24,7 @@
# SOFTWARE.
import os
import sys
import typing
from typing import List # noqa: F401
from .core import base
from . import config
@ -54,8 +54,6 @@ class Config:
"bring_front_click",
"wmname",
]
keys: typing.List[config.Key]
mouse: typing.List[config.Mouse]
def __init__(self, **settings):
"""Create a Config() object from settings
@ -63,6 +61,9 @@ class Config:
Only attributes found in Config.settings_keys will be added to object.
config attribute precedence is 1.) **settings 2.) self 3.) default_config
"""
self.keys = [] # type: List[config.Key]
self.mouse = [] # type: List[config.Mouse]
from .resources import default_config
default = vars(default_config)
for key in self.settings_keys:
@ -95,7 +96,7 @@ class Config:
"Create a Config() object from the python file located at path."
try:
sys.path.insert(0, os.path.dirname(path))
config = __import__(os.path.basename(path)[:-3])
config = __import__(os.path.basename(path)[:-3]) # noqa: F811
except Exception:
import traceback
from .log_utils import logger

View File

@ -35,7 +35,6 @@ import xcffib.xinerama
import xcffib.xproto
import time
import warnings
import tracemalloc
from ..config import Drag, Click, Screen, Match, Rule
from ..config import ScratchPad as ScratchPadConfig
@ -1854,6 +1853,8 @@ class Qtile(command.CommandObject):
Running tracemalloc is required for qtile-top
"""
import tracemalloc
if not tracemalloc.is_tracing():
tracemalloc.start()
else:
@ -1861,6 +1862,8 @@ class Qtile(command.CommandObject):
def cmd_tracemalloc_dump(self):
"""Dump tracemalloc snapshot"""
import tracemalloc
if not tracemalloc.is_tracing():
return [False, "Trace not started"]
cache_directory = get_cache_dir()

View File

@ -22,13 +22,13 @@ import shlex
from subprocess import Popen, PIPE
from .. import configurable
from typing import Any, List, Tuple
from typing import Any, List, Tuple # noqa: F401
class _Extension(configurable.Configurable):
"""Base Extension class"""
installed_extensions: List = []
installed_extensions = [] # type: List
defaults = [
("font", "sans", "defines the font name to be used"),
@ -64,13 +64,13 @@ class RunCommand(_Extension):
Also consider simply using lazy.spawn() or writing a
`client <http://docs.qtile.org/en/latest/manual/commands/scripting.html>`_.
"""
defaults: List[Tuple[str, Any, str]] = [
defaults = [
# NOTE: Do not use a list as a default value, since it would be shared
# among all the objects inheriting this class, and if one of them
# modified it, all the other objects would see the modified list;
# use a string or a tuple instead, which are immutable
("command", None, "the command to be launched (string or list with arguments)"),
]
] # type: List[Tuple[str, Any, str]]
def __init__(self, **config):
_Extension.__init__(self, **config)

View File

@ -33,11 +33,11 @@
from .log_utils import logger
from . import utils
from typing import Dict, Set
from typing import Dict, Set # noqa: F401
subscriptions: Dict = {}
SKIPLOG: Set = set()
subscriptions = {} # type: Dict
SKIPLOG = set() # type: Set
qtile = None

View File

@ -24,7 +24,7 @@ from abc import ABCMeta, abstractmethod
from .. import command, configurable
from typing import Any, List, Tuple
from typing import Any, List, Tuple # noqa: F401
class Layout(command.CommandObject, configurable.Configurable, metaclass=ABCMeta):
@ -33,12 +33,12 @@ class Layout(command.CommandObject, configurable.Configurable, metaclass=ABCMeta
def _name(cls):
return cls.__class__.__name__.lower()
defaults: List[Tuple[str, Any, str]] = [(
defaults = [(
"name",
None,
"The name of this layout"
" (usually the class' name in lowercase, e.g. 'max')"
)]
)] # type: List[Tuple[str, Any, str]]
def __init__(self, **config):
# name is a little odd; we can't resolve it until the class is defined

View File

@ -28,7 +28,7 @@ from libqtile.config import Key, Screen, Group, Drag, Click
from libqtile.command import lazy
from libqtile import layout, bar, widget
from typing import List
from typing import List # noqa: F401
mod = "mod4"
@ -112,7 +112,7 @@ mouse = [
]
dgroups_key_binder = None
dgroups_app_rules: List = []
dgroups_app_rules = [] # type: List
main = None
follow_mouse_focus = True
bring_front_click = False

View File

@ -25,7 +25,7 @@ import os
import shlex
from . import base
from typing import Dict
from typing import Dict # noqa: F401
BACKLIGHT_DIR = '/sys/class/backlight'
@ -33,7 +33,7 @@ BACKLIGHT_DIR = '/sys/class/backlight'
class Backlight(base.InLoopPollText):
"""A simple widget to show the current brightness of a monitor"""
filenames: Dict = {}
filenames = {} # type: Dict
orientations = base.ORIENTATION_HORIZONTAL

View File

@ -35,7 +35,7 @@ import subprocess
import threading
import warnings
from typing import Any, List, Tuple
from typing import Any, List, Tuple # noqa: F401
# Each widget class must define which bar orientation(s) it supports by setting
@ -95,7 +95,7 @@ class _Widget(command.CommandObject, configurable.Configurable):
orientations = ORIENTATION_BOTH
offsetx = None
offsety = None
defaults: List[Tuple[str, Any, str]] = [("background", None, "Widget background color")]
defaults = [("background", None, "Widget background color")] # type: List[Tuple[str, Any, str]]
def __init__(self, length, **config):
"""
@ -281,7 +281,7 @@ class _TextBox(_Widget):
Base class for widgets that are just boxes containing text.
"""
orientations = ORIENTATION_HORIZONTAL
defaults: List[Tuple[str, Any, str]] = [
defaults = [
("font", "sans", "Default font"),
("fontsize", None, "Font size. Calculated if None."),
("padding", None, "Padding. Calculated if None."),
@ -292,7 +292,7 @@ class _TextBox(_Widget):
"font shadow color, default is None(no shadow)"
),
("markup", False, "Whether or not to use pango markup"),
]
] # type: List[Tuple[str, Any, str]]
def __init__(self, text=" ", width=bar.CALCULATED, **config):
self.layout = None
@ -410,10 +410,10 @@ class InLoopPollText(_TextBox):
('fast' here means that this runs /in/ the event loop, so don't block! If
you want to run something nontrivial, use ThreadedPollWidget.) """
defaults: List[Tuple[str, Any, str]] = [
defaults = [
("update_interval", 600, "Update interval in seconds, if none, the "
"widget updates whenever the event loop is idle."),
]
] # type: List[Tuple[str, Any, str]]
def __init__(self, **config):
_TextBox.__init__(self, 'N/A', width=bar.CALCULATED, **config)
@ -491,10 +491,10 @@ class ThreadPoolText(_TextBox):
param: text - Initial text to display.
"""
defaults: List[Tuple[str, Any, str]] = [
defaults = [
("update_interval", None, "Update interval in seconds, if none, the "
"widget updates whenever it's done'."),
]
] # type: List[Tuple[str, Any, str]]
def __init__(self, text, **config):
super().__init__(text, width=bar.CALCULATED, **config)
@ -551,11 +551,11 @@ class PaddingMixin:
self.add_defaults(base.PaddingMixin.defaults)
"""
defaults: List[Tuple[str, Any, str]] = [
defaults = [
("padding", 3, "Padding inside the box"),
("padding_x", None, "X Padding. Overrides 'padding' if set"),
("padding_y", None, "Y Padding. Overrides 'padding' if set"),
]
] # type: List[Tuple[str, Any, str]]
padding_x = configurable.ExtraFallback('padding_x', 'padding')
padding_y = configurable.ExtraFallback('padding_y', 'padding')
@ -569,11 +569,11 @@ class MarginMixin:
self.add_defaults(base.MarginMixin.defaults)
"""
defaults: List[Tuple[str, Any, str]] = [
defaults = [
("margin", 3, "Margin inside the box"),
("margin_x", None, "X Margin. Overrides 'margin' if set"),
("margin_y", None, "Y Margin. Overrides 'margin' if set"),
]
] # type: List[Tuple[str, Any, str]]
margin_x = configurable.ExtraFallback('margin_x', 'margin')
margin_y = configurable.ExtraFallback('margin_y', 'margin')

View File

@ -34,34 +34,35 @@ import platform
import re
from abc import ABC, abstractclassmethod
from enum import Enum, auto, unique
from enum import Enum, unique
from pathlib import Path
from subprocess import check_output, CalledProcessError
from typing import Any, List, NamedTuple, Optional, Tuple
from typing import Any, List, NamedTuple, Optional, Tuple # noqa: F401
from libqtile import bar
from libqtile.log_utils import logger
from libqtile.images import Img
from libqtile.images import Img # noqa: F401
from . import base
from .. import images, configurable
from typing import Dict
from typing import Dict # noqa: F401
@unique
class BatteryState(Enum):
CHARGING = auto()
DISCHARGING = auto()
FULL = auto()
EMPTY = auto()
UNKNOWN = auto()
CHARGING = 1
DISCHARGING = 2
FULL = 3
EMPTY = 4
UNKNOWN = 5
class BatteryStatus(NamedTuple):
state: BatteryState
percent: float
power: float
time: int
BatteryStatus = NamedTuple("BatteryStatus", [
("state", BatteryState),
("percent", float),
("power", float),
("time", int),
])
class _Battery(ABC):
@ -188,7 +189,7 @@ class _LinuxBattery(_Battery, configurable.Configurable):
)
]
filenames: Dict = {}
filenames = {} # type: Dict
BAT_DIR = '/sys/class/power_supply'
@ -341,7 +342,7 @@ class Battery(base.ThreadedPollText):
try:
status = self._battery.update_status()
except RuntimeError as e:
return f'Error: {e}'
return 'Error: {}'.format(e)
return self.build_string(status)
@ -405,11 +406,11 @@ class BatteryIcon(base._TextBox):
"""Battery life indicator widget."""
orientations = base.ORIENTATION_HORIZONTAL
defaults: List[Tuple[str, Any, str]] = [
defaults = [
('battery', 0, 'Which battery should be monitored'),
('update_delay', 60, 'Seconds between status updates'),
('theme_path', default_icon_path(), 'Path of the icons'),
]
] # type: List[Tuple[str, Any, str]]
icon_names = (
'battery-missing',
@ -432,7 +433,7 @@ class BatteryIcon(base._TextBox):
if self.theme_path:
self.length_type = bar.STATIC
self.length = 0
self.surfaces: Dict[str, Img] = {}
self.surfaces = {} # type: Dict[str, Img]
self.current_icon = 'battery-missing'
self._battery = self._load_battery(**config)

View File

@ -16,7 +16,7 @@ except ImportError:
def xmlparse(body):
raise Exception("no xmltodict library")
from typing import Any, List, Tuple
from typing import Any, List, Tuple # noqa: F401
class GenPollText(base.ThreadedPollText):
@ -39,7 +39,7 @@ class GenPollText(base.ThreadedPollText):
class GenPollUrl(base.ThreadedPollText):
"""A generic text widget that polls an url and parses it using parse function"""
orientations = base.ORIENTATION_HORIZONTAL
defaults: List[Tuple[str, Any, str]] = [
defaults = [
('url', None, 'Url'),
('data', None, 'Post Data'),
('parse', None, 'Parse Function'),
@ -47,7 +47,7 @@ class GenPollUrl(base.ThreadedPollText):
('user_agent', 'Qtile', 'Set the user agent'),
('headers', {}, 'Extra Headers'),
('xml', False, 'Is XML?'),
]
] # type: List[Tuple[str, Any, str]]
def __init__(self, **config):
base.ThreadedPollText.__init__(self, **config)

View File

@ -35,14 +35,14 @@ import itertools
from .. import bar, hook
from . import base
from typing import Any, List, Tuple
from typing import Any, List, Tuple # noqa: F401
class _GroupBase(base._TextBox, base.PaddingMixin, base.MarginMixin):
defaults: List[Tuple[str, Any, str]] = [
defaults = [
("borderwidth", 3, "Current group border width"),
("center_aligned", False, "center-aligned group box"),
]
] # type: List[Tuple[str, Any, str]]
def __init__(self, **config):
base._TextBox.__init__(self, width=bar.CALCULATED, **config)

View File

@ -20,7 +20,7 @@
from libqtile.log_utils import logger
from . import base
from typing import List
from typing import List # noqa: F401
class Net(base.ThreadedPollText):
@ -54,7 +54,7 @@ class Net(base.ThreadedPollText):
return b, letter
def get_stats(self):
lines: List[str] = []
lines = [] # type: List[str]
with open('/proc/net/dev', 'r') as f:
lines = f.readlines()[2:]
interfaces = {}

View File

@ -23,9 +23,11 @@ classifiers =
Operating System :: POSIX :: BSD :: FreeBSD
Operating System :: POSIX :: Linux
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
Topic :: Desktop Environment :: Window Managers
project_urls =
Documentation = http://docs.qtile.org/
@ -103,7 +105,7 @@ ignore =
[mypy]
mypy_path = stubs
python_version = 3.6
python_version = 3.5
[mypy-_cffi_backend]
ignore_missing_imports = True
[mypy-cairocffi._ffi]