Skip to content

Commit

Permalink
Merge pull request #3 from Erotemic/dev/0.1.0
Browse files Browse the repository at this point in the history
Dev/0.1.0
  • Loading branch information
Erotemic committed Mar 4, 2019
2 parents 7a6bc9c + de18f55 commit e5cefd7
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 74 deletions.
81 changes: 81 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Python CircleCI 2.0 configuration file
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
# References:
# # how to setup multiple python versions
# https://stackoverflow.com/questions/948354/default-behavior-of-git-push-without-a-branch-specified
# https://github.com/adambrenecki/virtualfish/blob/aa3d6271bcb86ad27b6d24f96b5bd386d176f588/.circleci/config.yml
#
# # Multiple files for a checksum
# https://discuss.circleci.com/t/cant-checksum-multiple-files-with-slashes-in-the-file-path/20667/2
version: 2
workflows:
version: 2
test:
jobs:
- test-minimal-3.6
- test-minimal-3.5
- test-minimal-2.7

jobs:

# DEFINE minimal dependency install and tests
# define the "test-minimal-3.6" job and register it as a template
test-minimal-3.6: &test-minimal-template
docker:
- image: circleci/python:3.6.1
working_directory: ~/repo-test-minimal-3.6
steps:
- checkout
# <FAST DEPENDENCIES>
- restore_cache:
keys:
- v1-dependencies-{{ checksum "requirements/runtime.txt" }}-{{ checksum "requirements/tests.txt" }}
- v1-dependencies-

- run:
name: install dependencies
command: |
python -m venv venv || virtualenv venv # first command is python3 || second is python2
. venv/bin/activate
# The minimal test requirements
cat requirements/tests.txt > /tmp/_cci_minimal_deps_progiter.txt
cat requirements/runtime.txt >> /tmp/_cci_minimal_deps_progiter.txt
pip install -r /tmp/_cci_minimal_deps_progiter.txt
- save_cache:
paths:
- ./venv
key: v1-dependencies-{{ checksum "requirements/runtime.txt" }}-{{ checksum "requirements/tests.txt" }}
# </FAST DEPENDENCIES>

# run tests!
- run:
name: run tests
command: |
. venv/bin/activate
python run_tests.py
- store_artifacts:
path: test-reports
destination: test-reports


# Define tests fo the other python verisons using the "test3.6" template
# and indicating what needs to be modified.
test-minimal-3.5:
<<: *test-minimal-template
docker:
# All we need to do is change the base docker image so python is the
# version we want we can reuse everything else from the template
- image: circleci/python:3.5
working_directory: ~/repo-test-minimal-3.5


# < WARNING: SOON TO BE DEPRICATED >
test-minimal-2.7:
<<: *test-minimal-template
docker:
- image: circleci/python:2.7
working_directory: ~/repo-test-minimal-2.7
# < /WARNING: SOON TO BE DEPRICATED >
12 changes: 4 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,14 @@ python:
- "3.6"
before_install:
- pip install pip -U
- pip install pytest -U
- pip install pytest-cov -U
- pip install codecov -U
- pip install xdoctest -U
- pip install pygments -U
- pip install -r requirements.txt
- pip install -r requirements/tests.txt
- pip install -r requirements/runtime.txt
install:
- travis_retry pip install -e .
script:
#- travis_wait ./run_tests.py
- travis_wait ./run_tests.py
#- travis_wait python run_tests.py
- travis_wait pytest -p no:doctest --cov-config .coveragerc --cov-report html --xdoctest --cov=progiter progiter
#- travis_wait pytest -p no:doctest --cov-config .coveragerc --cov-report html --xdoctest --cov=progiter progiter
after_success:
#- coveralls || echo "Coveralls upload failed"
- codecov
Expand Down
3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ environment:
install:
# We need wheel installed to build wheels
- "%PYTHON%\\python.exe -m pip install wheel"
- "%PYTHON%\\python.exe -m pip install -r requirements.txt -U"
- "%PYTHON%\\python.exe -m pip install -r requirements/tests.txt -U"
- "%PYTHON%\\python.exe -m pip install -r requirements/runtime.txt -U"
- "%PYTHON%\\python.exe -m pip install -e ."

build: off
Expand Down
2 changes: 1 addition & 1 deletion progiter/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .progiter import (ProgIter,)

__version__ = '0.0.3'
__version__ = '0.1.0.dev0'
__all__ = [
'ProgIter',
]
83 changes: 42 additions & 41 deletions progiter/progiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,35 @@
You can divide the runtime overhead by two as many times as you want.
CommandLine:
python -m ubelt.progiter __doc__:0
python -m progiter.progiter __doc__:0
Example:
>>> # SCRIPT
>>> import ubelt as ub
>>> import progiter
>>> def is_prime(n):
... return n >= 2 and not any(n % i == 0 for i in range(2, n))
>>> for n in ub.ProgIter(range(1000000), verbose=1):
>>> for n in progiter.ProgIter(range(1000000), verbose=1):
>>> # do some work
>>> is_prime(n)
"""
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import sys
import time
import collections
import six
import numbers
from collections import OrderedDict
from datetime import timedelta
from math import log10, floor


__all__ = [
'ProgIter',
]

if sys.version_info.major == 2: # nocover
text_type = unicode
string_types = basestring,
default_timer = time.clock if sys.platform.startswith('win32') else time.time
else:
text_type = str
string_types = str,
default_timer = time.perf_counter

CLEAR_BEFORE = '\r'
Expand Down Expand Up @@ -151,16 +149,18 @@ def get_lock(cls):
def set_postfix(self, ordered_dict=None, refresh=True, **kwargs):
""" tqdm api compatibility. calls set_extra """
# Sort in alphabetical order to be more deterministic
postfix = OrderedDict([] if ordered_dict is None else ordered_dict)
postfix = collections.OrderedDict(
[] if ordered_dict is None else ordered_dict)
for key in sorted(kwargs.keys()):
postfix[key] = kwargs[key]
# Preprocess stats according to datatype
for key in postfix.keys():
import numbers
# Number: limit the length of the string
if isinstance(postfix[key], numbers.Number):
postfix[key] = '{0:2.3g}'.format(postfix[key])
# Else for any other type, try to get the string conversion
elif not isinstance(postfix[key], six.string_types):
elif not isinstance(postfix[key], string_types):
postfix[key] = str(postfix[key])
# Else if it's a string, don't need to preprocess anything
# Stitch together to get the final postfix
Expand Down Expand Up @@ -244,10 +244,10 @@ class ProgIter(_TQDMCompat, _BackwardsCompat):
Example:
>>> # doctest: +SKIP
>>> import ubelt as ub
>>> import progiter
>>> def is_prime(n):
... return n >= 2 and not any(n % i == 0 for i in range(2, n))
>>> for n in ub.ProgIter(range(100), verbose=1):
>>> for n in progiter.ProgIter(range(100), verbose=1):
>>> # do some work
>>> is_prime(n)
100/100... rate=... Hz, total=..., wall=... EST
Expand Down Expand Up @@ -325,9 +325,6 @@ def __call__(self, iterable):

def __enter__(self):
"""
CommandLine:
python -m ubelt.progiter ProgIter.__enter__
Example:
>>> # can be used as a context manager in iter mode
>>> n = 3
Expand All @@ -353,13 +350,12 @@ def set_extra(self, extra):
"""
specify a custom info appended to the end of the next message
TODO:
- [ ] extra is a bad name; come up with something better and rename
Example:
>>> import ubelt as ub
>>> prog = ub.ProgIter(range(100, 300, 100), show_times=False, verbose=3)
>>> import progiter
>>> prog = progiter.ProgIter(range(100, 300, 100), show_times=False, verbose=3)
>>> for n in prog:
>>> prog.set_extra('processesing num {}'.format(n))
0/2...
Expand Down Expand Up @@ -392,20 +388,20 @@ def step(self, inc=1):
inc (int): number of steps to increment (defaults to 1)
Example:
>>> import ubelt as ub
>>> import progiter
>>> n = 3
>>> prog = ub.ProgIter(desc='manual', total=n, verbose=3)
>>> prog = progiter.ProgIter(desc='manual', total=n, verbose=3)
>>> # Need to manually begin and end in this mode
>>> prog.begin()
>>> for _ in range(n):
... prog.step()
>>> prog.end()
Example:
>>> import ubelt as ub
>>> import progiter
>>> n = 3
>>> # can be used as a context manager in manual mode
>>> with ub.ProgIter(desc='manual', total=n, verbose=3) as prog:
>>> with progiter.ProgIter(desc='manual', total=n, verbose=3) as prog:
... for _ in range(n):
... prog.step()
"""
Expand Down Expand Up @@ -563,6 +559,7 @@ def _build_message_template(self):
>>> print(self._build_message_template().strip())
{desc} {iter_idx:4d}/?...{extra}
"""
from math import log10, floor
tzname = time.tzname[0]
length_unknown = self.total is None or self.total <= 0
if length_unknown:
Expand All @@ -574,14 +571,14 @@ def _build_message_template(self):
msg_body = [
('{desc}'),
(' {percent:03.2f}% of ' + str(self.chunksize) + 'x'),
('?' if length_unknown else six.text_type(self.total)),
('?' if length_unknown else text_type(self.total)),
('...'),
]
else:
msg_body = [
('{desc}'),
(' {iter_idx:' + str(n_chrs) + 'd}/'),
('?' if length_unknown else six.text_type(self.total)),
('?' if length_unknown else text_type(self.total)),
('...'),
]

Expand All @@ -608,9 +605,6 @@ def format_message(self):
builds a formatted progres message with the current values.
This contains the special characters needed to clear lines.
CommandLine:
python -m ubelt.progiter ProgIter.format_message
Example:
>>> self = ProgIter(clearline=False, show_times=False)
>>> print(repr(self.format_message()))
Expand All @@ -619,19 +613,31 @@ def format_message(self):
>>> self.step()
>>> print(repr(self.format_message()))
' 1/?... \n'
Example:
>>> self = ProgIter(chunksize=10, total=100, clearline=False,
>>> show_times=False, microseconds=True)
>>> # hack, microseconds=True for coverage, needs real test
>>> print(repr(self.format_message()))
' 0.00% of 10x100... \n'
>>> self.begin()
>>> self.update() # tqdm alternative to step
>>> print(repr(self.format_message()))
' 1.00% of 10x100... \n'
"""
from datetime import timedelta
if self._est_seconds_left is None:
eta = '?'
else:
if self._microseconds:
eta = six.text_type(timedelta(seconds=self._est_seconds_left))
eta = text_type(timedelta(seconds=self._est_seconds_left))
else:
eta = six.text_type(timedelta(seconds=int(self._est_seconds_left)))
eta = text_type(timedelta(seconds=int(self._est_seconds_left)))

if self._microseconds:
total = six.text_type(timedelta(seconds=self._total_seconds))
total = text_type(timedelta(seconds=self._total_seconds))
else:
total = six.text_type(timedelta(seconds=int(self._total_seconds)))
total = text_type(timedelta(seconds=int(self._total_seconds)))

# similar to tqdm.format_meter
if self.chunksize and self.total:
Expand Down Expand Up @@ -664,8 +670,8 @@ def ensure_newline(self):
Example:
>>> # Unsafe version may write your message on the wrong line
>>> import ubelt as ub
>>> prog = ub.ProgIter(range(4), show_times=False, verbose=1)
>>> import progiter
>>> prog = progiter.ProgIter(range(4), show_times=False, verbose=1)
>>> for n in prog:
... print('unsafe message')
0/4... unsafe message
Expand All @@ -676,7 +682,7 @@ def ensure_newline(self):
>>> # apparently the safe version does this too.
>>> print('---')
---
>>> prog = ub.ProgIter(range(4), show_times=False, verbose=1)
>>> prog = progiter.ProgIter(range(4), show_times=False, verbose=1)
>>> for n in prog:
... prog.ensure_newline()
... print('safe message')
Expand Down Expand Up @@ -713,10 +719,5 @@ def _write(self, msg):


if __name__ == '__main__':
r"""
CommandLine:
python -m ubelt.progiter
python -m ubelt.progiter all
"""
import xdoctest as xdoc
xdoc.doctest_module()
7 changes: 4 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
xdoctest
pytest
ubelt
xdoctest >= 0.7.0
pytest >= 3.3.1
pytest-cov
coverage >= 4.3.4
2 changes: 2 additions & 0 deletions requirements/docs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sphinx
-e git://github.com/snide/sphinx_rtd_theme.git#egg=sphinx_rtd_theme
Empty file added requirements/runtime.txt
Empty file.
4 changes: 4 additions & 0 deletions requirements/tests.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
xdoctest >= 0.7.0
pytest >= 3.3.1
pytest-cov
coverage >= 4.3.4
2 changes: 1 addition & 1 deletion run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
'--cov=' + package_name,
]
pytest_args = pytest_args + sys.argv[1:]
pytest.main(pytest_args)
sys.exit(pytest.main(pytest_args))

0 comments on commit e5cefd7

Please sign in to comment.