diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 02709dc..7b19e5d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,7 @@ jobs: timeout-minutes: 10 strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9] + python-version: ['3.7', '3.8', '3.9', '3.10'] steps: - uses: actions/checkout@v2 diff --git a/examples.py b/examples.py index 0c6948d..1c03383 100644 --- a/examples.py +++ b/examples.py @@ -1,12 +1,6 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import with_statement - import functools import random import sys @@ -187,7 +181,10 @@ def granular_progress_example(): progressbar.GranularBar(markers=" ⡀⡄⡆⡇⣇⣧⣷⣿", left='', right='|'), progressbar.GranularBar(markers=" .oO", left='', right=''), ] - for i in progressbar.progressbar(range(100), widgets=widgets): + for i in progressbar.progressbar(list(range(100)), widgets=widgets): + time.sleep(0.03) + + for i in progressbar.progressbar(iter(range(100)), widgets=widgets): time.sleep(0.03) diff --git a/progressbar/__about__.py b/progressbar/__about__.py index 35b1c9d..9847408 100644 --- a/progressbar/__about__.py +++ b/progressbar/__about__.py @@ -19,7 +19,7 @@ long running operations. '''.strip().split()) __email__ = 'wolph@wol.ph' -__version__ = '3.55.0' +__version__ = '4.0.0' __license__ = 'BSD' __copyright__ = 'Copyright 2015 Rick van Hattem (Wolph)' __url__ = 'https://github.com/WoLpH/python-progressbar' diff --git a/progressbar/__init__.py b/progressbar/__init__.py index f93ab86..33d7c71 100644 --- a/progressbar/__init__.py +++ b/progressbar/__init__.py @@ -1,52 +1,40 @@ from datetime import date -from .utils import ( - len_color, - streams -) -from .shortcuts import progressbar - -from .widgets import ( - Timer, - ETA, - AdaptiveETA, - AbsoluteETA, - DataSize, - FileTransferSpeed, - AdaptiveTransferSpeed, - AnimatedMarker, - Counter, - Percentage, - FormatLabel, - SimpleProgress, - Bar, - ReverseBar, - BouncingBar, - RotatingMarker, - VariableMixin, - MultiRangeBar, - MultiProgressBar, - GranularBar, - FormatLabelBar, - PercentageLabelBar, - Variable, - DynamicMessage, - FormatCustomText, - CurrentTime -) - -from .bar import ( - ProgressBar, - DataTransferBar, - NullBar, -) +from .__about__ import __author__ +from .__about__ import __version__ +from .bar import DataTransferBar +from .bar import NullBar +from .bar import ProgressBar from .base import UnknownLength - - -from .__about__ import ( - __author__, - __version__, -) +from .shortcuts import progressbar +from .utils import len_color +from .utils import streams +from .widgets import AbsoluteETA +from .widgets import AdaptiveETA +from .widgets import AdaptiveTransferSpeed +from .widgets import AnimatedMarker +from .widgets import Bar +from .widgets import BouncingBar +from .widgets import Counter +from .widgets import CurrentTime +from .widgets import DataSize +from .widgets import DynamicMessage +from .widgets import ETA +from .widgets import FileTransferSpeed +from .widgets import FormatCustomText +from .widgets import FormatLabel +from .widgets import FormatLabelBar +from .widgets import GranularBar +from .widgets import MultiProgressBar +from .widgets import MultiRangeBar +from .widgets import Percentage +from .widgets import PercentageLabelBar +from .widgets import ReverseBar +from .widgets import RotatingMarker +from .widgets import SimpleProgress +from .widgets import Timer +from .widgets import Variable +from .widgets import VariableMixin __date__ = str(date.today()) __all__ = [ diff --git a/progressbar/bar.py b/progressbar/bar.py index b5980e2..025471e 100644 --- a/progressbar/bar.py +++ b/progressbar/bar.py @@ -1,17 +1,17 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import unicode_literals -from __future__ import with_statement +from __future__ import annotations -import sys +import logging import math import os +import sys import time import timeit -import logging import warnings -from datetime import datetime from copy import deepcopy +from datetime import datetime + +from python_utils import types + try: # pragma: no cover from collections import abc except ImportError: # pragma: no cover @@ -19,14 +19,11 @@ from python_utils import converters -import six - from . import widgets from . import widgets as widgets_module # Avoid name collision from . import base from . import utils - logger = logging.getLogger(__name__) @@ -58,8 +55,10 @@ class ProgressBarBase(abc.Iterable, ProgressBarMixinBase): class DefaultFdMixin(ProgressBarMixinBase): - def __init__(self, fd=sys.stderr, is_terminal=None, line_breaks=None, - enable_colors=None, **kwargs): + def __init__(self, fd: types.IO = sys.stderr, + is_terminal: bool | None = None, + line_breaks: bool | None = None, + enable_colors: bool | None = None, **kwargs): if fd is sys.stdout: fd = utils.streams.original_stdout @@ -76,8 +75,8 @@ def __init__(self, fd=sys.stderr, is_terminal=None, line_breaks=None, # Check if it should overwrite the current line (suitable for # iteractive terminals) or write line breaks (suitable for log files) if line_breaks is None: - line_breaks = utils.env_flag('PROGRESSBAR_LINE_BREAKS', not - self.is_terminal) + line_breaks = utils.env_flag('PROGRESSBAR_LINE_BREAKS', + not self.is_terminal) self.line_breaks = line_breaks # Check if ANSI escape characters are enabled (suitable for iteractive @@ -122,7 +121,7 @@ def finish(self, *args, **kwargs): # pragma: no cover class ResizableMixin(ProgressBarMixinBase): - def __init__(self, term_width=None, **kwargs): + def __init__(self, term_width: int | None = None, **kwargs): ProgressBarMixinBase.__init__(self, **kwargs) self.signal_set = False @@ -156,7 +155,8 @@ def finish(self): # pragma: no cover class StdRedirectMixin(DefaultFdMixin): - def __init__(self, redirect_stderr=False, redirect_stdout=False, **kwargs): + def __init__(self, redirect_stderr: bool = False, + redirect_stdout: bool = False, **kwargs): DefaultFdMixin.__init__(self, **kwargs) self.redirect_stderr = redirect_stderr self.redirect_stdout = redirect_stdout @@ -179,7 +179,7 @@ def start(self, *args, **kwargs): utils.streams.start_capturing(self) DefaultFdMixin.start(self, *args, **kwargs) - def update(self, value=None): + def update(self, value: float = None): if not self.line_breaks and utils.streams.needs_clear(): self.fd.write('\r' + ' ' * self.term_width + '\r') @@ -197,7 +197,6 @@ def finish(self, end='\n'): class ProgressBar(StdRedirectMixin, ResizableMixin, ProgressBarBase): - '''The ProgressBar class which updates and prints the bar. Args: @@ -488,8 +487,8 @@ def data(self): # The seconds since the bar started total_seconds_elapsed=total_seconds_elapsed, # The seconds since the bar started modulo 60 - seconds_elapsed=(elapsed.seconds % 60) + - (elapsed.microseconds / 1000000.), + seconds_elapsed=(elapsed.seconds % 60) + + (elapsed.microseconds / 1000000.), # The minutes since the bar started modulo 60 minutes_elapsed=(elapsed.seconds / 60) % 60, # The hours since the bar started modulo 24 @@ -585,7 +584,7 @@ def _format_widgets(self): elif isinstance(widget, widgets.AutoWidthWidgetBase): result.append(widget) expanding.insert(0, index) - elif isinstance(widget, six.string_types): + elif isinstance(widget, str): result.append(widget) width -= self.custom_len(widget) else: @@ -795,6 +794,7 @@ class DataTransferBar(ProgressBar): This assumes that the values its given are numbers of bytes. ''' + def default_widgets(self): if self.max_value: return [ @@ -813,7 +813,6 @@ def default_widgets(self): class NullBar(ProgressBar): - ''' Progress bar that does absolutely nothing. Useful for single verbosity flags diff --git a/progressbar/base.py b/progressbar/base.py index a8c8e71..df278e5 100644 --- a/progressbar/base.py +++ b/progressbar/base.py @@ -1,7 +1,4 @@ # -*- mode: python; coding: utf-8 -*- -from __future__ import absolute_import -import six - class FalseMeta(type): def __bool__(self): # pragma: no cover @@ -13,9 +10,9 @@ def __cmp__(self, other): # pragma: no cover __nonzero__ = __bool__ -class UnknownLength(six.with_metaclass(FalseMeta, object)): +class UnknownLength(metaclass=FalseMeta): pass -class Undefined(six.with_metaclass(FalseMeta, object)): +class Undefined(metaclass=FalseMeta): pass diff --git a/progressbar/utils.py b/progressbar/utils.py index 258249f..b1be944 100644 --- a/progressbar/utils.py +++ b/progressbar/utils.py @@ -1,17 +1,22 @@ -from __future__ import absolute_import +from __future__ import annotations + import atexit +import datetime import io +import logging import os import re import sys -import logging -import datetime -from python_utils.time import timedelta_to_seconds, epoch, format_time + +from python_utils import types from python_utils.converters import scale_1024 from python_utils.terminal import get_terminal_size +from python_utils.time import epoch +from python_utils.time import format_time +from python_utils.time import timedelta_to_seconds -import six - +if types.TYPE_CHECKING: + from .bar import ProgressBar assert timedelta_to_seconds assert get_terminal_size @@ -19,7 +24,6 @@ assert scale_1024 assert epoch - ANSI_TERMS = ( '([xe]|bv)term', '(sco)?ansi', @@ -34,7 +38,8 @@ ANSI_TERM_RE = re.compile('^({})'.format('|'.join(ANSI_TERMS)), re.IGNORECASE) -def is_ansi_terminal(fd, is_terminal=None): # pragma: no cover +def is_ansi_terminal(fd: types.IO, is_terminal: bool | None = None) \ + -> bool: # pragma: no cover if is_terminal is None: # Jupyter Notebooks define this variable and support progress bars if 'JPY_PARENT_PID' in os.environ: @@ -66,7 +71,7 @@ def is_ansi_terminal(fd, is_terminal=None): # pragma: no cover return is_terminal -def is_terminal(fd, is_terminal=None): +def is_terminal(fd: types.IO, is_terminal: bool | None = None) -> bool: if is_terminal is None: # Full ansi support encompasses what we expect from a terminal is_terminal = is_ansi_terminal(True) or None @@ -86,7 +91,8 @@ def is_terminal(fd, is_terminal=None): return is_terminal -def deltas_to_seconds(*deltas, **kwargs): # default=ValueError): +def deltas_to_seconds(*deltas, + **kwargs) -> int | float | None: # default=ValueError): ''' Convert timedeltas and seconds as int to seconds as float while coalescing @@ -130,7 +136,7 @@ def deltas_to_seconds(*deltas, **kwargs): # default=ValueError): return default -def no_color(value): +def no_color(value: types.StringTypes) -> types.StringTypes: ''' Return the `value` without ANSI escape codes @@ -153,7 +159,7 @@ def no_color(value): return re.sub(pattern, replace, value) -def len_color(value): +def len_color(value: types.StringTypes) -> int: ''' Return the length of `value` without ANSI escape codes @@ -167,7 +173,7 @@ def len_color(value): return len(no_color(value)) -def env_flag(name, default=None): +def env_flag(name: str, default: bool | None = None) -> bool | None: ''' Accepts environt variables formatted as y/n, yes/no, 1/0, true/false, on/off, and returns it as a boolean @@ -185,17 +191,18 @@ def env_flag(name, default=None): class WrappingIO: - def __init__(self, target, capturing=False, listeners=set()): - self.buffer = six.StringIO() + def __init__(self, target: types.IO, capturing: bool = False, + listeners: types.Set[ProgressBar] = None) -> None: + self.buffer = io.StringIO() self.target = target self.capturing = capturing - self.listeners = listeners + self.listeners = listeners or set() self.needs_clear = False def isatty(self): # pragma: no cover return self.target.isatty() - def write(self, value): + def write(self, value: str) -> None: if self.capturing: self.buffer.write(value) if '\n' in value: # pragma: no branch @@ -207,10 +214,10 @@ def write(self, value): if '\n' in value: # pragma: no branch self.flush_target() - def flush(self): + def flush(self) -> None: self.buffer.flush() - def _flush(self): + def _flush(self) -> None: value = self.buffer.getvalue() if value: self.flush() @@ -222,12 +229,12 @@ def _flush(self): # when explicitly flushing, always flush the target as well self.flush_target() - def flush_target(self): # pragma: no cover + def flush_target(self) -> None: # pragma: no cover if not self.target.closed and getattr(self.target, 'flush'): self.target.flush() -class StreamWrapper(object): +class StreamWrapper: '''Wrap stdout and stderr globally''' def __init__(self): @@ -246,14 +253,14 @@ def __init__(self): if env_flag('WRAP_STDERR', default=False): # pragma: no cover self.wrap_stderr() - def start_capturing(self, bar=None): + def start_capturing(self, bar: ProgressBar | None = None) -> None: if bar: # pragma: no branch self.listeners.add(bar) self.capturing += 1 self.update_capturing() - def stop_capturing(self, bar=None): + def stop_capturing(self, bar: ProgressBar | None = None) -> None: if bar: # pragma: no branch try: self.listeners.remove(bar) @@ -263,7 +270,7 @@ def stop_capturing(self, bar=None): self.capturing -= 1 self.update_capturing() - def update_capturing(self): # pragma: no cover + def update_capturing(self) -> None: # pragma: no cover if isinstance(self.stdout, WrappingIO): self.stdout.capturing = self.capturing > 0 @@ -273,14 +280,14 @@ def update_capturing(self): # pragma: no cover if self.capturing <= 0: self.flush() - def wrap(self, stdout=False, stderr=False): + def wrap(self, stdout: bool = False, stderr: bool = False) -> None: if stdout: self.wrap_stdout() if stderr: self.wrap_stderr() - def wrap_stdout(self): + def wrap_stdout(self) -> types.IO: self.wrap_excepthook() if not self.wrapped_stdout: @@ -290,7 +297,7 @@ def wrap_stdout(self): return sys.stdout - def wrap_stderr(self): + def wrap_stderr(self) -> types.IO: self.wrap_excepthook() if not self.wrapped_stderr: @@ -300,44 +307,44 @@ def wrap_stderr(self): return sys.stderr - def unwrap_excepthook(self): + def unwrap_excepthook(self) -> None: if self.wrapped_excepthook: self.wrapped_excepthook -= 1 sys.excepthook = self.original_excepthook - def wrap_excepthook(self): + def wrap_excepthook(self) -> None: if not self.wrapped_excepthook: logger.debug('wrapping excepthook') self.wrapped_excepthook += 1 sys.excepthook = self.excepthook - def unwrap(self, stdout=False, stderr=False): + def unwrap(self, stdout: bool = False, stderr: bool = False) -> None: if stdout: self.unwrap_stdout() if stderr: self.unwrap_stderr() - def unwrap_stdout(self): + def unwrap_stdout(self) -> None: if self.wrapped_stdout > 1: self.wrapped_stdout -= 1 else: sys.stdout = self.original_stdout self.wrapped_stdout = 0 - def unwrap_stderr(self): + def unwrap_stderr(self) -> None: if self.wrapped_stderr > 1: self.wrapped_stderr -= 1 else: sys.stderr = self.original_stderr self.wrapped_stderr = 0 - def needs_clear(self): # pragma: no cover + def needs_clear(self) -> bool: # pragma: no cover stdout_needs_clear = getattr(self.stdout, 'needs_clear', False) stderr_needs_clear = getattr(self.stderr, 'needs_clear', False) return stderr_needs_clear or stdout_needs_clear - def flush(self): + def flush(self) -> None: if self.wrapped_stdout: # pragma: no branch try: self.stdout._flush() @@ -368,12 +375,14 @@ class AttributeDict(dict): >>> attrs = AttributeDict(spam=123) # Reading + >>> attrs['spam'] 123 >>> attrs.spam 123 # Read after update using attribute + >>> attrs.spam = 456 >>> attrs['spam'] 456 @@ -381,6 +390,7 @@ class AttributeDict(dict): 456 # Read after update using dict access + >>> attrs['spam'] = 123 >>> attrs['spam'] 123 @@ -388,6 +398,7 @@ class AttributeDict(dict): 123 # Read after update using dict access + >>> del attrs.spam >>> attrs['spam'] Traceback (most recent call last): @@ -402,16 +413,17 @@ class AttributeDict(dict): ... AttributeError: No such attribute: spam ''' - def __getattr__(self, name): + + def __getattr__(self, name: str) -> int: if name in self: return self[name] else: raise AttributeError("No such attribute: " + name) - def __setattr__(self, name, value): + def __setattr__(self, name: str, value: int) -> None: self[name] = value - def __delattr__(self, name): + def __delattr__(self, name: str) -> None: if name in self: del self[name] else: diff --git a/progressbar/widgets.py b/progressbar/widgets.py index e9c03ca..9ffb68a 100644 --- a/progressbar/widgets.py +++ b/progressbar/widgets.py @@ -1,30 +1,26 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import with_statement - import abc -import sys -import pprint import datetime import functools +import pprint +import sys from python_utils import converters - -import six +from python_utils import types from . import base from . import utils +if types.TYPE_CHECKING: + from .bar import ProgressBar + MAX_DATE = datetime.date.max MAX_TIME = datetime.time.max MAX_DATETIME = datetime.datetime.max def string_or_lambda(input_): - if isinstance(input_, six.string_types): + if isinstance(input_, str): def render_input(progress, data, width): return input_ % data @@ -50,7 +46,7 @@ def create_wrapper(wrapper): elif not wrapper: return - if isinstance(wrapper, six.string_types): + if isinstance(wrapper, str): assert '{}' in wrapper, 'Expected string with {} for formatting' else: raise RuntimeError('Pass either a begin/end string as a tuple or a' @@ -84,7 +80,7 @@ def _marker(progress, data, width): else: return marker - if isinstance(marker, six.string_types): + if isinstance(marker, str): marker = converters.to_unicode(marker) assert utils.len_color(marker) == 1, \ 'Markers are required to be 1 char' @@ -160,7 +156,7 @@ def __init__(self, min_width=None, max_width=None, **kwargs): self.min_width = min_width self.max_width = max_width - def check_size(self, progress): + def check_size(self, progress: 'ProgressBar'): if self.min_width and self.min_width > progress.term_width: return False elif self.max_width and self.max_width < progress.term_width: @@ -255,7 +251,7 @@ class FormatLabel(FormatWidgetMixin, WidgetBase): 'value': ('value', None), } - def __init__(self, format, **kwargs): + def __init__(self, format: str, **kwargs): FormatWidgetMixin.__init__(self, format=format, **kwargs) WidgetBase.__init__(self, **kwargs) @@ -811,7 +807,7 @@ class VariableMixin(object): '''Mixin to display a custom user variable ''' def __init__(self, name, **kwargs): - if not isinstance(name, six.string_types): + if not isinstance(name, str): raise TypeError('Variable(): argument must be a string') if len(name.split()) > 1: raise ValueError('Variable(): argument must be single word') @@ -980,6 +976,7 @@ def __call__(self, progress, data, width): class FormatLabelBar(FormatLabel, Bar): '''A bar which has a formatted label in the center.''' + def __init__(self, format, **kwargs): FormatLabel.__init__(self, format, **kwargs) Bar.__init__(self, **kwargs) @@ -997,6 +994,7 @@ def __call__(self, progress, data, width, format=None): class PercentageLabelBar(Percentage, FormatLabelBar): '''A bar which displays the current percentage in the center.''' + # %3d adds an extra space that makes it look off-center # %2d keeps the label somewhat consistently in-place def __init__(self, format='%(percentage)2d%%', na='N/A%%', **kwargs): @@ -1070,4 +1068,3 @@ def current_datetime(self): def current_time(self): return self.current_datetime().time() - diff --git a/setup.py b/setup.py index d546263..f72abd0 100644 --- a/setup.py +++ b/setup.py @@ -4,55 +4,16 @@ import os import sys -from setuptools.command.test import test as TestCommand - -try: - from setuptools import setup, find_packages -except ImportError: - from distutils.core import setup, find_packages - - -# Not all systems use utf8 encoding by default, this works around that issue -if sys.version_info > (3,): - from functools import partial - open = partial(open, encoding='utf8') - +from setuptools import setup, find_packages # To prevent importing about and thereby breaking the coverage info we use this # exec hack about = {} -with open("progressbar/__about__.py") as fp: +with open('progressbar/__about__.py', encoding='utf8') as fp: exec(fp.read(), about) -class PyTest(TestCommand): - user_options = [('pytest-args=', 'a', 'Arguments to pass to pytest')] - - def initialize_options(self): - TestCommand.initialize_options(self) - self.pytest_args = '' - - def run_tests(self): - import shlex - # import here, cause outside the eggs aren't loaded - import pytest - errno = pytest.main(shlex.split(self.pytest_args)) - sys.exit(errno) - - install_reqs = [] -tests_require = [ - 'flake8>=3.7.7', - 'pytest>=4.6.9', - 'pytest-cov>=2.6.1', - 'freezegun>=0.3.11', - 'sphinx>=1.8.5', -] - -if sys.version_info < (2, 7): - tests_require += ['unittest2'] - - if sys.argv[-1] == 'info': for k, v in about.items(): print('%s: %s' % (k, v)) @@ -65,7 +26,6 @@ def run_tests(self): readme = \ 'See http://pypi.python.org/pypi/%(__package_name__)s/' % about - if __name__ == '__main__': setup( name='progressbar2', @@ -80,32 +40,33 @@ def run_tests(self): long_description=readme, include_package_data=True, install_requires=[ - 'python-utils>=2.3.0', - 'six', + 'python-utils>=3.0.0', ], - tests_require=tests_require, setup_requires=['setuptools'], zip_safe=False, - cmdclass={'test': PyTest}, extras_require={ 'docs': [ - 'sphinx>=1.7.4', + 'sphinx>=1.8.5', + ], + 'tests': [ + 'flake8>=3.7.7', + 'pytest>=4.6.9', + 'pytest-cov>=2.6.1', + 'pytest-mypy', + 'freezegun>=0.3.11', + 'sphinx>=1.8.5', ], - 'tests': tests_require, }, + python_requires='>=3.7.0', classifiers=[ 'Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Natural Language :: English', - "Programming Language :: Python :: 2", - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: Implementation :: PyPy', ], ) diff --git a/tests/test_flush.py b/tests/test_flush.py index 7f4317e..69dc4e3 100644 --- a/tests/test_flush.py +++ b/tests/test_flush.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import time import progressbar diff --git a/tests/test_stream.py b/tests/test_stream.py index 235f174..6dcfcf7 100644 --- a/tests/test_stream.py +++ b/tests/test_stream.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import io import sys import pytest diff --git a/tests/test_terminal.py b/tests/test_terminal.py index f55f3df..997bb0d 100644 --- a/tests/test_terminal.py +++ b/tests/test_terminal.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import sys import time import signal diff --git a/tox.ini b/tox.ini index 9af9ca8..99d982d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,16 +1,15 @@ [tox] -envlist = py27, py33, py34, py35, py36, py37, py38, pypy, flake8, docs +envlist = py37, py38, py39, py310, pypy3, flake8, docs skip_missing_interpreters = True [testenv] basepython = - py27: python2.7 - py34: python3.4 - py35: python3.5 py36: python3.6 py37: python3.7 py38: python3.8 - pypy: pypy + py39: python3.9 + py310: python3.10 + pypy3: pypy3 deps = -r{toxinidir}/tests/requirements.txt commands = py.test --basetemp="{envtmpdir}" --confcutdir=.. {posargs} @@ -18,7 +17,7 @@ changedir = tests [testenv:flake8] changedir = -basepython = python2.7 +basepython = python3 deps = flake8 commands = flake8 {toxinidir}/progressbar {toxinidir}/tests {toxinidir}/examples.py @@ -39,7 +38,7 @@ commands = sphinx-build -W -b html -d docs/_build/doctrees docs docs/_build/html {posargs} [flake8] -ignore = W391, W504, E741 +ignore = W391, W504, E741, W503, E131 exclude = docs, progressbar/six.py