1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Update progress to 1.5

This commit is contained in:
Quentin Pradet 2019-03-07 09:46:13 +04:00
parent ac9010e87c
commit c86460d1a4
No known key found for this signature in database
GPG key ID: E328ACB1EC7E57C2
6 changed files with 74 additions and 34 deletions

1
news/progress.vendor Normal file
View file

@ -0,0 +1 @@
Update progress to 1.5

View file

@ -12,31 +12,49 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import division from __future__ import division, print_function
from collections import deque from collections import deque
from datetime import timedelta from datetime import timedelta
from math import ceil from math import ceil
from sys import stderr from sys import stderr
from time import time try:
from time import monotonic
except ImportError:
from time import time as monotonic
__version__ = '1.4' __version__ = '1.5'
HIDE_CURSOR = '\x1b[?25l'
SHOW_CURSOR = '\x1b[?25h'
class Infinite(object): class Infinite(object):
file = stderr file = stderr
sma_window = 10 # Simple Moving Average window sma_window = 10 # Simple Moving Average window
check_tty = True
hide_cursor = True
def __init__(self, *args, **kwargs): def __init__(self, message='', **kwargs):
self.index = 0 self.index = 0
self.start_ts = time() self.start_ts = monotonic()
self.avg = 0 self.avg = 0
self._avg_update_ts = self.start_ts
self._ts = self.start_ts self._ts = self.start_ts
self._xput = deque(maxlen=self.sma_window) self._xput = deque(maxlen=self.sma_window)
for key, val in kwargs.items(): for key, val in kwargs.items():
setattr(self, key, val) setattr(self, key, val)
self._width = 0
self.message = message
if self.file and self.is_tty():
if self.hide_cursor:
print(HIDE_CURSOR, end='', file=self.file)
print(self.message, end='', file=self.file)
self.file.flush()
def __getitem__(self, key): def __getitem__(self, key):
if key.startswith('_'): if key.startswith('_'):
return None return None
@ -44,7 +62,7 @@ class Infinite(object):
@property @property
def elapsed(self): def elapsed(self):
return int(time() - self.start_ts) return int(monotonic() - self.start_ts)
@property @property
def elapsed_td(self): def elapsed_td(self):
@ -52,8 +70,14 @@ class Infinite(object):
def update_avg(self, n, dt): def update_avg(self, n, dt):
if n > 0: if n > 0:
xput_len = len(self._xput)
self._xput.append(dt / n) self._xput.append(dt / n)
self.avg = sum(self._xput) / len(self._xput) now = monotonic()
# update when we're still filling _xput, then after every second
if (xput_len < self.sma_window or
now - self._avg_update_ts > 1):
self.avg = sum(self._xput) / len(self._xput)
self._avg_update_ts = now
def update(self): def update(self):
pass pass
@ -61,11 +85,34 @@ class Infinite(object):
def start(self): def start(self):
pass pass
def clearln(self):
if self.file and self.is_tty():
print('\r\x1b[K', end='', file=self.file)
def write(self, s):
if self.file and self.is_tty():
line = self.message + s.ljust(self._width)
print('\r' + line, end='', file=self.file)
self._width = max(self._width, len(s))
self.file.flush()
def writeln(self, line):
if self.file and self.is_tty():
self.clearln()
print(line, end='', file=self.file)
self.file.flush()
def finish(self): def finish(self):
pass if self.file and self.is_tty():
print(file=self.file)
if self.hide_cursor:
print(SHOW_CURSOR, end='', file=self.file)
def is_tty(self):
return self.file.isatty() if self.check_tty else True
def next(self, n=1): def next(self, n=1):
now = time() now = monotonic()
dt = now - self._ts dt = now - self._ts
self.update_avg(n, dt) self.update_avg(n, dt)
self._ts = now self._ts = now
@ -73,12 +120,17 @@ class Infinite(object):
self.update() self.update()
def iter(self, it): def iter(self, it):
try: with self:
for x in it: for x in it:
yield x yield x
self.next() self.next()
finally:
self.finish() def __enter__(self):
self.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.finish()
class Progress(Infinite): class Progress(Infinite):
@ -119,9 +171,7 @@ class Progress(Infinite):
except TypeError: except TypeError:
pass pass
try: with self:
for x in it: for x in it:
yield x yield x
self.next() self.next()
finally:
self.finish()

View file

@ -19,18 +19,15 @@ from __future__ import unicode_literals
import sys import sys
from . import Progress from . import Progress
from .helpers import WritelnMixin
class Bar(WritelnMixin, Progress): class Bar(Progress):
width = 32 width = 32
message = ''
suffix = '%(index)d/%(max)d' suffix = '%(index)d/%(max)d'
bar_prefix = ' |' bar_prefix = ' |'
bar_suffix = '| ' bar_suffix = '| '
empty_fill = ' ' empty_fill = ' '
fill = '#' fill = '#'
hide_cursor = True
def update(self): def update(self):
filled_length = int(self.width * self.progress) filled_length = int(self.width * self.progress)

View file

@ -16,27 +16,20 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from . import Infinite, Progress from . import Infinite, Progress
from .helpers import WriteMixin
class Counter(WriteMixin, Infinite): class Counter(Infinite):
message = ''
hide_cursor = True
def update(self): def update(self):
self.write(str(self.index)) self.write(str(self.index))
class Countdown(WriteMixin, Progress): class Countdown(Progress):
hide_cursor = True
def update(self): def update(self):
self.write(str(self.remaining)) self.write(str(self.remaining))
class Stack(WriteMixin, Progress): class Stack(Progress):
phases = (' ', '', '', '', '', '', '', '', '') phases = (' ', '', '', '', '', '', '', '', '')
hide_cursor = True
def update(self): def update(self):
nphases = len(self.phases) nphases = len(self.phases)

View file

@ -16,11 +16,9 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from . import Infinite from . import Infinite
from .helpers import WriteMixin
class Spinner(WriteMixin, Infinite): class Spinner(Infinite):
message = ''
phases = ('-', '\\', '|', '/') phases = ('-', '\\', '|', '/')
hide_cursor = True hide_cursor = True
@ -40,5 +38,6 @@ class MoonSpinner(Spinner):
class LineSpinner(Spinner): class LineSpinner(Spinner):
phases = ['', '', '', '', '', ''] phases = ['', '', '', '', '', '']
class PixelSpinner(Spinner): class PixelSpinner(Spinner):
phases = ['','', '', '', '', '', '', ''] phases = ['', '', '', '', '', '', '', '']

View file

@ -9,7 +9,7 @@ lockfile==0.12.2
msgpack==0.5.6 msgpack==0.5.6
packaging==19.0 packaging==19.0
pep517==0.5.0 pep517==0.5.0
progress==1.4 progress==1.5
pyparsing==2.3.1 pyparsing==2.3.1
pytoml==0.1.20 pytoml==0.1.20
requests==2.21.0 requests==2.21.0