Add mypy checks
Add the mypy stubs and the mypy configuration to be able to run mypy on qtile, and make the various changes to qtile to get the mypy checks to run successfully. Add the mypy check to Travis.master
parent
cf696ae80d
commit
ec6a6ba893
|
@ -38,3 +38,4 @@ debian/*debhelper
|
|||
.tox/
|
||||
.cache/
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
|
|
|
@ -28,6 +28,8 @@ matrix:
|
|||
env: TOXENV=pep8
|
||||
- python: 2.7
|
||||
env: TOXENV=pep8
|
||||
- python: 3.6
|
||||
env: TOXENV=mypy
|
||||
|
||||
allow_failures:
|
||||
- python: nightly
|
||||
|
|
|
@ -21,16 +21,6 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import six
|
||||
|
||||
moves = [
|
||||
six.MovedAttribute("getoutput", "commands", "subprocess"),
|
||||
six.MovedModule("asyncio", "trollius", "asyncio"),
|
||||
]
|
||||
|
||||
for m in moves:
|
||||
six.add_move(m)
|
||||
|
||||
# Keep supporting the deprecated misspelled subpackage "extention"
|
||||
# TODO: Remove in the future
|
||||
from . import extension as extention # noqa
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# Copyright (c) 2018 Sean Vig
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
import six
|
||||
|
||||
if six.PY2:
|
||||
import trollius as asyncio
|
||||
else:
|
||||
import asyncio # noqa: F401
|
|
@ -18,9 +18,14 @@
|
|||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
try:
|
||||
from typing import Dict # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class Configurable(object):
|
||||
global_defaults = {}
|
||||
global_defaults = {} # type: Dict
|
||||
|
||||
def __init__(self, **config):
|
||||
self._variable_defaults = {}
|
||||
|
|
|
@ -22,11 +22,16 @@ import shlex
|
|||
from subprocess import Popen, PIPE
|
||||
from .. import configurable
|
||||
|
||||
try:
|
||||
from typing import Any, List, Tuple # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class _Extension(configurable.Configurable):
|
||||
"""Base Extension class"""
|
||||
|
||||
installed_extensions = []
|
||||
installed_extensions = [] # type: List
|
||||
|
||||
defaults = [
|
||||
("font", "sans", "defines the font name to be used"),
|
||||
|
@ -68,7 +73,7 @@ class RunCommand(_Extension):
|
|||
# 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)
|
||||
|
|
|
@ -33,8 +33,14 @@
|
|||
from .log_utils import logger
|
||||
from . import utils
|
||||
|
||||
subscriptions = {}
|
||||
SKIPLOG = set()
|
||||
try:
|
||||
from typing import Dict, Set # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
subscriptions = {} # type: Dict
|
||||
SKIPLOG = set() # type: Set
|
||||
qtile = None
|
||||
|
||||
|
||||
|
|
|
@ -31,8 +31,7 @@ import struct
|
|||
import fcntl
|
||||
import json
|
||||
|
||||
from six.moves import asyncio
|
||||
|
||||
from .asyncio_compat import asyncio
|
||||
from .log_utils import logger
|
||||
|
||||
HDRLEN = 4
|
||||
|
|
|
@ -25,6 +25,11 @@ from abc import ABCMeta, abstractmethod
|
|||
|
||||
from .. import command, configurable
|
||||
|
||||
try:
|
||||
from typing import Any, List, Tuple # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
@six.add_metaclass(ABCMeta)
|
||||
class Layout(command.CommandObject, configurable.Configurable):
|
||||
|
@ -38,7 +43,7 @@ class Layout(command.CommandObject, configurable.Configurable):
|
|||
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
|
||||
|
|
|
@ -41,8 +41,7 @@ import xcffib.xproto
|
|||
import six
|
||||
import warnings
|
||||
|
||||
from six.moves import asyncio
|
||||
|
||||
from .asyncio_compat import asyncio
|
||||
from .config import Drag, Click, Screen, Match, Rule
|
||||
from .config import ScratchPad as ScratchPadConfig
|
||||
from .group import _Group
|
||||
|
|
|
@ -28,6 +28,11 @@ from libqtile.config import Key, Screen, Group, Drag, Click
|
|||
from libqtile.command import lazy
|
||||
from libqtile import layout, bar, widget
|
||||
|
||||
try:
|
||||
from typing import List # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
mod = "mod4"
|
||||
|
||||
keys = [
|
||||
|
@ -110,7 +115,7 @@ mouse = [
|
|||
]
|
||||
|
||||
dgroups_key_binder = None
|
||||
dgroups_app_rules = []
|
||||
dgroups_app_rules = [] # type: List
|
||||
main = None
|
||||
follow_mouse_focus = True
|
||||
bring_front_click = False
|
||||
|
|
|
@ -23,6 +23,13 @@
|
|||
from ..utils import safe_import as safe_import_
|
||||
from .import_error import make_error
|
||||
|
||||
from .clock import Clock # noqa: F401
|
||||
from .groupbox import AGroupBox, GroupBox # noqa: F401
|
||||
from .prompt import Prompt # noqa: F401
|
||||
from .systray import Systray # noqa: F401
|
||||
from .textbox import TextBox # noqa: F401
|
||||
from .windowname import WindowName # noqa: F401
|
||||
|
||||
|
||||
def safe_import(module_name, class_name):
|
||||
safe_import_((".widget", module_name), class_name, globals(),
|
||||
|
@ -31,25 +38,19 @@ def safe_import(module_name, class_name):
|
|||
|
||||
safe_import("backlight", "Backlight")
|
||||
safe_import("battery", ["Battery", "BatteryIcon"])
|
||||
safe_import("clock", "Clock")
|
||||
safe_import("currentlayout", ["CurrentLayout", "CurrentLayoutIcon"])
|
||||
safe_import("currentscreen", "CurrentScreen")
|
||||
safe_import("debuginfo", "DebugInfo")
|
||||
safe_import("graph", ["CPUGraph", "MemoryGraph", "SwapGraph", "NetGraph",
|
||||
"HDDGraph", "HDDBusyGraph"])
|
||||
safe_import("groupbox", ["AGroupBox", "GroupBox"])
|
||||
safe_import("maildir", "Maildir")
|
||||
safe_import("notify", "Notify")
|
||||
safe_import("prompt", "Prompt")
|
||||
safe_import("sensors", "ThermalSensor")
|
||||
safe_import("sep", "Sep")
|
||||
safe_import("she", "She")
|
||||
safe_import("spacer", "Spacer")
|
||||
safe_import("systray", "Systray")
|
||||
safe_import("textbox", "TextBox")
|
||||
safe_import("generic_poll_text", ["GenPollText", "GenPollUrl"])
|
||||
safe_import("volume", "Volume")
|
||||
safe_import("windowname", "WindowName")
|
||||
safe_import("windowtabs", "WindowTabs")
|
||||
safe_import("keyboardlayout", "KeyboardLayout")
|
||||
safe_import("df", "DF")
|
||||
|
|
|
@ -24,13 +24,18 @@
|
|||
import os
|
||||
from . import base
|
||||
|
||||
try:
|
||||
from typing import Dict # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
BACKLIGHT_DIR = '/sys/class/backlight'
|
||||
|
||||
|
||||
class Backlight(base.InLoopPollText):
|
||||
"""A simple widget to show the current brightness of a monitor"""
|
||||
|
||||
filenames = {}
|
||||
filenames = {} # type: Dict
|
||||
|
||||
orientations = base.ORIENTATION_HORIZONTAL
|
||||
|
||||
|
|
|
@ -36,6 +36,11 @@ import subprocess
|
|||
import threading
|
||||
import warnings
|
||||
|
||||
try:
|
||||
from typing import Any, List, Tuple # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
# Each widget class must define which bar orientation(s) it supports by setting
|
||||
# these bits in an 'orientations' class attribute. Simply having the attribute
|
||||
|
@ -94,7 +99,7 @@ class _Widget(command.CommandObject, configurable.Configurable):
|
|||
orientations = ORIENTATION_BOTH
|
||||
offsetx = None
|
||||
offsety = None
|
||||
defaults = [("background", None, "Widget background color")]
|
||||
defaults = [("background", None, "Widget background color")] # type: List[Tuple[str, Any, str]]
|
||||
|
||||
def __init__(self, length, **config):
|
||||
"""
|
||||
|
@ -292,7 +297,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
|
||||
|
@ -311,10 +316,6 @@ class _TextBox(_Widget):
|
|||
if self.layout:
|
||||
self.layout.text = value
|
||||
|
||||
@property
|
||||
def font(self):
|
||||
return self._font
|
||||
|
||||
@property
|
||||
def foreground(self):
|
||||
return self._foreground
|
||||
|
@ -325,6 +326,10 @@ class _TextBox(_Widget):
|
|||
if self.layout:
|
||||
self.layout.colour = fg
|
||||
|
||||
@property
|
||||
def font(self):
|
||||
return self._font
|
||||
|
||||
@font.setter
|
||||
def font(self, value):
|
||||
self._font = value
|
||||
|
@ -413,7 +418,7 @@ class InLoopPollText(_TextBox):
|
|||
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)
|
||||
|
@ -494,7 +499,7 @@ class ThreadPoolText(_TextBox):
|
|||
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(ThreadPoolText, self).__init__(text, width=bar.CALCULATED,
|
||||
|
@ -556,7 +561,7 @@ class PaddingMixin(object):
|
|||
("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')
|
||||
|
@ -574,7 +579,7 @@ class MarginMixin(object):
|
|||
("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')
|
||||
|
|
|
@ -37,6 +37,11 @@ from libqtile import bar
|
|||
from libqtile.log_utils import logger
|
||||
from . import base
|
||||
|
||||
try:
|
||||
from typing import Dict # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
BAT_DIR = '/sys/class/power_supply'
|
||||
CHARGED = 'Full'
|
||||
CHARGING = 'Charging'
|
||||
|
@ -57,18 +62,19 @@ def default_icon_path():
|
|||
return os.path.join(root, 'resources', 'battery-icons')
|
||||
|
||||
|
||||
def _get_battery_name():
|
||||
bats = [f for f in os.listdir(BAT_DIR) if f.startswith('BAT')]
|
||||
|
||||
if bats:
|
||||
return bats[0]
|
||||
else:
|
||||
return 'BAT0'
|
||||
|
||||
|
||||
class _Battery(base._TextBox):
|
||||
"""Base battery class"""
|
||||
|
||||
filenames = {}
|
||||
|
||||
def _get_battery_name():
|
||||
bats = [f for f in os.listdir(BAT_DIR) if f.startswith('BAT')]
|
||||
|
||||
if bats:
|
||||
return bats[0]
|
||||
else:
|
||||
return 'BAT0'
|
||||
filenames = {} # type: Dict
|
||||
|
||||
defaults = [
|
||||
('battery_name', _get_battery_name(), 'ACPI name of a battery, usually BAT0'),
|
||||
|
|
|
@ -27,6 +27,8 @@ from . import base
|
|||
from .generic_poll_text import GenPollUrl
|
||||
import locale
|
||||
|
||||
_DEFAULT_CURRENCY = str(locale.localeconv()['int_curr_symbol'])
|
||||
|
||||
|
||||
class BitcoinTicker(GenPollUrl):
|
||||
"""
|
||||
|
@ -46,7 +48,7 @@ class BitcoinTicker(GenPollUrl):
|
|||
orientations = base.ORIENTATION_HORIZONTAL
|
||||
|
||||
defaults = [
|
||||
('currency', locale.localeconv()['int_curr_symbol'].strip(),
|
||||
('currency', _DEFAULT_CURRENCY.strip(),
|
||||
'The currency the value that bitcoin is displayed in'),
|
||||
]
|
||||
|
||||
|
|
|
@ -35,12 +35,17 @@ import itertools
|
|||
from .. import bar, hook
|
||||
from . import base
|
||||
|
||||
try:
|
||||
from typing import Any, List, Tuple # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class _GroupBase(base._TextBox, base.PaddingMixin, base.MarginMixin):
|
||||
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)
|
||||
|
|
|
@ -48,8 +48,8 @@ try:
|
|||
except ImportError:
|
||||
import iwlib
|
||||
|
||||
def get_status(interface):
|
||||
interface = iwlib.get_iwconfig(interface)
|
||||
def get_status(interface_name):
|
||||
interface = iwlib.get_iwconfig(interface_name)
|
||||
if 'stats' not in interface:
|
||||
return None, None
|
||||
quality = interface['stats']['quality']
|
||||
|
|
|
@ -155,7 +155,7 @@ def _float_setter(attr):
|
|||
|
||||
|
||||
class _Window(command.CommandObject):
|
||||
_windowMask = None # override in child class
|
||||
_windowMask = 0 # override in child class
|
||||
|
||||
def __init__(self, window, qtile):
|
||||
self.window, self.qtile = window, qtile
|
||||
|
@ -214,14 +214,22 @@ class _Window(command.CommandObject):
|
|||
|
||||
x = property(fset=_geometry_setter("x"), fget=_geometry_getter("x"))
|
||||
y = property(fset=_geometry_setter("y"), fget=_geometry_getter("y"))
|
||||
width = property(
|
||||
fset=_geometry_setter("width"),
|
||||
fget=_geometry_getter("width")
|
||||
)
|
||||
height = property(
|
||||
fset=_geometry_setter("height"),
|
||||
fget=_geometry_getter("height")
|
||||
)
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
return _geometry_getter("width")(self)
|
||||
|
||||
@width.setter
|
||||
def width(self, value):
|
||||
_geometry_setter("width")(self, value)
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return _geometry_getter("height")(self)
|
||||
|
||||
@height.setter
|
||||
def height(self, value):
|
||||
_geometry_setter("height")(self, value)
|
||||
|
||||
float_x = property(
|
||||
fset=_float_setter("x"),
|
||||
|
@ -582,7 +590,7 @@ class _Window(command.CommandObject):
|
|||
self.qtile.root.set_property("_NET_ACTIVE_WINDOW", self.window.wid)
|
||||
hook.fire("client_focus", self)
|
||||
|
||||
def _items(self, name, sel):
|
||||
def _items(self, name):
|
||||
return None
|
||||
|
||||
def _select(self, name, sel):
|
||||
|
|
16
setup.cfg
16
setup.cfg
|
@ -6,3 +6,19 @@ max-line-length = 120
|
|||
python_files = test_*.py
|
||||
testpaths = test
|
||||
addopts = --verbose
|
||||
|
||||
[check-manifest]
|
||||
ignore =
|
||||
stubs**
|
||||
|
||||
[mypy]
|
||||
mypy_path = stubs
|
||||
python_version = 2.7
|
||||
[mypy-libqtile/_ffi_*]
|
||||
ignore_errors = True
|
||||
[mypy-trollius]
|
||||
ignore_missing_imports = True
|
||||
[mypy-libqtile._ffi_pango]
|
||||
ignore_missing_imports = True
|
||||
[mypy-libqtile._ffi_xcursors]
|
||||
ignore_missing_imports = True
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
from tempfile import TemporaryDirectory as _TemporaryDirectory
|
||||
|
||||
class TemporaryDirectory(_TemporaryDirectory): ...
|
|
@ -0,0 +1 @@
|
|||
ffi = ...
|
|
@ -0,0 +1,9 @@
|
|||
from typing import List
|
||||
|
||||
__version_info__ = ... # type: List
|
||||
|
||||
class FFI:
|
||||
def cdef(self, csource, override=False, packed=False): ...
|
||||
def compile(self, tmpdir=".", verbose=0, target=None, debug=None): ...
|
||||
def include(self, ffi_to_include): ...
|
||||
def set_source(self, module_name, source, source_extension=".c", **kwargs): ...
|
|
@ -0,0 +1,9 @@
|
|||
def init_pair(n, f, b): ...
|
||||
|
||||
A_BOLD = ...
|
||||
|
||||
A_REVERSE = ...
|
||||
|
||||
COLOR_GREEN = ...
|
||||
|
||||
COLOR_BLACK = ...
|
|
@ -0,0 +1 @@
|
|||
def DBusGMainLoop(set_as_default=False): ...
|
|
@ -0,0 +1,7 @@
|
|||
class BusName: ...
|
||||
|
||||
class Object: ...
|
||||
|
||||
def method(dbus_interface, in_signature=None, out_signature=None): ...
|
||||
|
||||
def signal(dbus_interface, signature=None): ...
|
|
@ -0,0 +1 @@
|
|||
class IPKernelApp: ...
|
|
@ -0,0 +1 @@
|
|||
class Kernel: ...
|
|
@ -0,0 +1 @@
|
|||
def get_iwconfig(interface): ...
|
|
@ -0,0 +1 @@
|
|||
def install_kernel_spec(source_dir, kernel_name=None, user=False, replace=False, prefix=None): ...
|
|
@ -0,0 +1 @@
|
|||
class Maildir: ...
|
|
@ -0,0 +1,5 @@
|
|||
class MPDClient: ...
|
||||
|
||||
class ConnectionError: ...
|
||||
|
||||
class CommandError: ...
|
|
@ -0,0 +1,3 @@
|
|||
def require(*requirements): ...
|
||||
|
||||
class DistributionNotFound(Exception): ...
|
|
@ -0,0 +1,3 @@
|
|||
class Wireless: ...
|
||||
|
||||
class Iwstats: ...
|
|
@ -0,0 +1 @@
|
|||
def setproctitle(title): ...
|
|
@ -0,0 +1 @@
|
|||
class Snapshot: ...
|
|
@ -0,0 +1 @@
|
|||
ffi = ...
|
|
@ -0,0 +1,6 @@
|
|||
class SelectionEvent: ...
|
||||
|
||||
class SelectionEventMask:
|
||||
SetSelectionOwner = ... # type: int
|
||||
SelectionWindowDestroy = ... # type: int
|
||||
SelectionClientClose = ... # type: int
|
|
@ -0,0 +1,29 @@
|
|||
class ClientMessageEvent: ...
|
||||
|
||||
class ClientMessageData: ...
|
||||
|
||||
class ConfigWindow: ...
|
||||
|
||||
class CW: ...
|
||||
|
||||
class EventMask:
|
||||
KeyPress = ... # type: int
|
||||
ButtonPress = ... # type: int
|
||||
ButtonRelease = ... # type: int
|
||||
EnterWindow = ... # type: int
|
||||
Exposure = ... # type: int
|
||||
StructureNotify = ... # type: int
|
||||
FocusChange = ... # type: int
|
||||
PropertyChange = ... # type: int
|
||||
|
||||
class SetMode: ...
|
||||
|
||||
class StackMode: ...
|
||||
|
||||
class WindowClass: ...
|
||||
|
||||
class AccessError: ...
|
||||
|
||||
class DrawableError: ...
|
||||
|
||||
class WindowError: ...
|
|
@ -0,0 +1 @@
|
|||
def getIconPath(iconname): ...
|
|
@ -0,0 +1 @@
|
|||
def parseString(string, parser=None): ...
|
5
tox.ini
5
tox.ini
|
@ -12,6 +12,7 @@ envlist =
|
|||
py-nightly
|
||||
docs,
|
||||
pep8,
|
||||
mypy,
|
||||
packaging
|
||||
|
||||
[testenv]
|
||||
|
@ -47,6 +48,10 @@ commands =
|
|||
deps = flake8
|
||||
commands = flake8 {toxinidir}/libqtile {toxinidir}/bin/
|
||||
|
||||
[testenv:mypy]
|
||||
deps = mypy
|
||||
commands = mypy -p libqtile
|
||||
|
||||
[testenv:docs]
|
||||
deps = -r{toxinidir}/docs/requirements.txt
|
||||
commands = sphinx-build -W -b html -d {envtmpdir}/doctrees docs docs/_build/html
|
||||
|
|
Loading…
Reference in New Issue