Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
devel:languages:python:backports
python-pytimeparse2
pytimeparse2-1.7.1.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pytimeparse2-1.7.1.obscpio of Package python-pytimeparse2
07070100000000000081A4000000000000000000000001645D608F000000F5000000000000000000000000000000000000001F00000000pytimeparse2-1.7.1/.coveragerc[run] source = pytimeparse2 tests parallel = True concurrency = thread multiprocessing omit = *.tox/* *setup.py [report] fail_under = 100 show_missing = True exclude_lines = pragma: no cover nocv MemoryError 07070100000001000041ED000000000000000000000002645D608F00000000000000000000000000000000000000000000001B00000000pytimeparse2-1.7.1/.github07070100000002000041ED000000000000000000000002645D608F00000000000000000000000000000000000000000000002500000000pytimeparse2-1.7.1/.github/workflows07070100000003000081A4000000000000000000000001645D608F00000274000000000000000000000000000000000000002F00000000pytimeparse2-1.7.1/.github/workflows/check.ymlname: Python package on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-20.04 strategy: max-parallel: 4 matrix: python-version: ['3.6.15', 3.7, 3.8, 3.9, '3.10', '3.11'] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install tox tox-gh-actions - name: Test with tox run: tox 07070100000004000081A4000000000000000000000001645D608F0000006B000000000000000000000000000000000000001E00000000pytimeparse2-1.7.1/.gitignore*.pyc *~ *.c .DS_Store /.coverage /MANIFEST /build/ /dist/ *.egg-info/ venv .tox .mypy_cache .idea .vscode 07070100000005000081A4000000000000000000000001645D608F00000054000000000000000000000000000000000000001900000000pytimeparse2-1.7.1/.pep8[flake8] ignore = exclude = /.tox/* max-line-length = 120 import-order-style = pep8 07070100000006000081A4000000000000000000000001645D608F0000043A000000000000000000000000000000000000001F00000000pytimeparse2-1.7.1/LICENSE.rstThe MIT License (MIT) Copyright (c) 2021 Sergey Klyuykov 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. 07070100000007000081A4000000000000000000000001645D608F00000039000000000000000000000000000000000000001F00000000pytimeparse2-1.7.1/MANIFEST.ininclude LICENSE.rst include README.rst include setup.cfg 07070100000008000081A4000000000000000000000001645D608F00000C1F000000000000000000000000000000000000001E00000000pytimeparse2-1.7.1/README.rstpytimeparse2: time expression parser ===================================== .. image:: https://github.com/onegreyonewhite/pytimeparse2/actions/workflows/check.yml/badge.svg?branch=master :target: https://github.com/onegreyonewhite/pytimeparse2/actions :alt: Pipeline status .. image:: https://badge.fury.io/py/pytimeparse2.svg :target: https://badge.fury.io/py/pytimeparse2 This is a `pytimeparse <https://github.com/wroberts/pytimeparse>`_ based project with the aim of optimizing functionality and providing stable support. Copyright (c) 2021 Sergey Klyuykov <onegreyonewhite@mail.ru> Licensed under the MIT License (see source file ``pytimeparse2.py`` for details). A small Python library to parse various kinds of time expressions, inspired by `this StackOverflow question <http://stackoverflow.com/questions/4628122/how-to-construct-a-timedelta-object-from-a-simple-string>`_. The single function ``pytimeparse2.parse`` defined in the library parses time expressions like the following: - ``32m`` - ``2h32m`` - ``3d2h32m`` - ``1w3d2h32m`` - ``1w 3d 2h 32m`` - ``1 w 3 d 2 h 32 m`` - ``4:13`` - ``4:13:02`` - ``4:13:02.266`` - ``2:04:13:02.266`` - ``2 days, 4:13:02`` (``uptime`` format) - ``2 days, 4:13:02.266`` - ``5hr34m56s`` - ``5 hours, 34 minutes, 56 seconds`` - ``5 hrs, 34 mins, 56 secs`` - ``2 days, 5 hours, 34 minutes, 56 seconds`` - ``1.2 m`` - ``1.2 min`` - ``1.2 mins`` - ``1.2 minute`` - ``1.2 minutes`` - ``172 hours`` - ``172 hr`` - ``172 h`` - ``172 hrs`` - ``172 hour`` - ``1.24 days`` - ``5 d`` - ``5 day`` - ``5 days`` - ``5.6 wk`` - ``5.6 week`` - ``5.6 weeks`` It returns the time as a number of seconds (an integer value if possible, otherwise a floating-point number):: >>> from pytimeparse import parse >>> parse('1.2 minutes') 72 For months and years, the library does not consider complications such as leap- years and leap-seconds. Instead, it assumes "30 days for a month" and "365 days for a year" as the basis for calculations with those units. - ``2 mo`` - ``2 months`` - ``3y`` - ``3 years`` - ``1y2mo3w4d5h6m7s8ms`` For better capability with dates, use keyword ``as_timedelta=True`` which mark for function returns value as ``datetime.timedelta`` or ``dateutil.relitivedelta.relativedelta`` (if installed):: >>> from pytimeparse import parse >>> parse('24h', as_timedelta=True) relativedelta(days=+1) You can also forced disable dateutil support by calling ``disable_dateutil()`` before ``parse(...)``. For returning support call ``enable_dateutil()``. Notes ----- A number of seconds can be converted back into a string using the ``datetime`` module in the standard library, as noted in `this other StackOverflow question <http://stackoverflow.com/questions/538666/python-format-timedelta-to-string>`_:: >>> from pytimeparse import parse >>> import datetime >>> parse('1 day, 14:20:16') 138016 >>> str(datetime.timedelta(seconds=138016)) '1 day, 14:20:16' Future work ----------- 1. Speed up with Cython for some python versions. 2. Use github actions for testing and releasing. 07070100000009000081ED000000000000000000000001645D608F00000184000000000000000000000000000000000000002200000000pytimeparse2-1.7.1/autorelease.sh#!/usr/bin/env bash CURRENT_VERSION=$(python3 setup.py --version | tr -d '\n') TAG=$(git tag -l $CURRENT_VERSION) if [ -z "${TAG}" ]; then echo "Creating new tag ${CURRENT_VERSION}."; git tag $CURRENT_VERSION > /dev/null 2>&1; git push origin $CURRENT_VERSION > /dev/null 2>&1; else echo "Current release ${CURRENT_VERSION} already exists. Update version to release." fi 0707010000000A000081A4000000000000000000000001645D608F00002357000000000000000000000000000000000000002300000000pytimeparse2-1.7.1/pytimeparse2.py#!/usr/bin/env python # -*- coding: utf-8 -*- """ (c) Sergey Klyuykov <onegreyonewhite@mail.ru> 3 Nov 2021 Implements a single function, `parse`, which can parse various kinds of time expressions. """ # MIT LICENSE # # 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. __version__ = '1.7.1' import typing import re from datetime import timedelta try: from dateutil.relativedelta import relativedelta HAS_RELITIVE_TIMEDELTA = True except ImportError: # pragma: no cover HAS_RELITIVE_TIMEDELTA = False relativedelta = None # type: ignore SIGN = r'(?P<sign>[+|-]|\+)?' YEARS = r'(?P<years>[\d.]+)\s*(?:ys?|yrs?.?|years?)' MONTHS = r'(?P<months>[\d.]+)\s*(?:mos?.?|mths?.?|months?)' WEEKS = r'(?P<weeks>[\d.]+)\s*(?:w|wks?|weeks?)' DAYS = r'(?P<days>[\d.]+)\s*(?:d|dys?|days?)' HOURS = r'(?P<hours>[\d.]+)\s*(?:h|hrs?|hours?)' MINS = r'(?P<minutes>[\d.]+)\s*(?:m|(mins?)|(minutes?))' SECS = r'(?P<seconds>[\d.]+)\s*(?:s|secs?|seconds?)' MILLIS = r'(?P<milliseconds>[\d.]+)\s*(?:ms|msecs?|millis|milliseconds?)' SEPARATORS = r'[,/]' SECCLOCK = r':(?P<seconds>\d{2}(?:\.\d+)?)' MINCLOCK = r'(?P<minutes>\d{1,2}):(?P<seconds>\d{2}(?:\.\d+)?)' HOURCLOCK = r'(?P<hours>\d+):(?P<minutes>\d{2}):(?P<seconds>\d{2}(?:\.\d+)?)' DAYCLOCK = (r'(?P<days>\d+):(?P<hours>\d{2}):' r'(?P<minutes>\d{2}):(?P<seconds>\d{2}(?:\.\d+)?)') MULTIPLIERS = { 'years': 60 * 60 * 24 * 365, 'months': 60 * 60 * 24 * 30, 'weeks': 60 * 60 * 24 * 7, 'days': 60 * 60 * 24, 'hours': 60 * 60, 'minutes': 60, 'seconds': 1, 'milliseconds': 1e-3, } def OPT(x): return r'(?:{x})?'.format(x=x) def OPTSEP(x): return r'(?:{x}\s*(?:{SEPARATORS}\s*)?)?'.format(x=x, SEPARATORS=SEPARATORS) TIMEFORMATS = [ (rf'{OPTSEP(YEARS)}\s*' rf'{OPTSEP(MONTHS)}\s*' rf'{OPTSEP(WEEKS)}\s*' rf'{OPTSEP(DAYS)}\s*' rf'{OPTSEP(HOURS)}\s*' rf'{OPTSEP(MINS)}\s*' rf'{OPT(SECS)}\s*' rf'{OPT(MILLIS)}'), rf'{OPTSEP(WEEKS)}\s*{OPTSEP(DAYS)}\s*{OPTSEP(HOURS)}\s*{OPTSEP(MINS)}\s*{OPT(SECS)}\s*{OPT(MILLIS)}', rf'{MINCLOCK}', rf'{OPTSEP(WEEKS)}\s*{OPTSEP(DAYS)}\s*{HOURCLOCK}', rf'{DAYCLOCK}', rf'{SECCLOCK}', rf'{YEARS}', rf'{MONTHS}', ] COMPILED_SIGN = re.compile(r'\s*' + SIGN + r'\s*(?P<unsigned>.*)$') COMPILED_TIMEFORMATS = [ re.compile(r'\s*' + timefmt + r'\s*$', re.I) for timefmt in TIMEFORMATS ] def _all_digits(mdict, delta_class): if HAS_RELITIVE_TIMEDELTA and issubclass(delta_class, relativedelta): if 'milliseconds' in mdict: mdict['microseconds'] = float(mdict.pop('milliseconds') or 0) * 1000 return delta_class(**{k: float(v) for k, v in mdict.items() if v}).normalized() delta = delta_class(**{ key: float(mdict.pop(key) or 0) for key in mdict.copy() if key in ('hours', 'minutes', 'days', 'milliseconds') }) for time_type, value in mdict.items(): if not value: continue if value.isdigit(): delta += delta_class(seconds=MULTIPLIERS[time_type] * int(value, 10)) elif value.replace('.', '', 1).isdigit(): delta += delta_class(seconds=MULTIPLIERS[time_type] * float(value)) return delta def _interpret_as_minutes(sval, mdict): """ Times like "1:22" are ambiguous; do they represent minutes and seconds or hours and minutes? By default, parse assumes the latter. Call this function after parsing out a dictionary to change that assumption. >>> import pprint >>> pprint.pprint(_interpret_as_minutes('1:24', {'seconds': '24', 'minutes': '1'})) {'hours': '1', 'minutes': '24'} """ if sval.count(':') == 1 and '.' not in sval and (('hours' not in mdict) or (mdict['hours'] is None)) and ( ('days' not in mdict) or (mdict['days'] is None)) and (('weeks' not in mdict) or (mdict['weeks'] is None)) \ and (('months' not in mdict) or (mdict['months'] is None)) \ and (('years' not in mdict) or (mdict['years'] is None)): mdict['hours'] = mdict['minutes'] mdict['minutes'] = mdict['seconds'] mdict.pop('seconds') return mdict def _normilized_relativedelta(value: typing.Optional[timedelta]) -> typing.Optional[timedelta]: if relativedelta is not None and isinstance(value, relativedelta): return value.normalized() return value def _parse( sval: typing.Union[str, int, float], granularity: str = 'seconds', delta_class: typing.Type[timedelta] = timedelta ) -> typing.Optional[timedelta]: if isinstance(sval, (int, float)): return _normilized_relativedelta(delta_class(seconds=float(sval))) if sval.replace('.', '', 1).replace('-', '', 1).replace('+', '', 1).isdigit(): return _normilized_relativedelta(delta_class(seconds=float(sval))) match = COMPILED_SIGN.match(sval) sign = -1 if match.groupdict()['sign'] == '-' else 1 # type: ignore sval = match.groupdict()['unsigned'] # type: ignore for timefmt in COMPILED_TIMEFORMATS: match = timefmt.match(sval) if not (match and match.group(0).strip()): continue mdict = match.groupdict() if granularity == 'minutes': mdict = _interpret_as_minutes(sval, mdict) return sign * _all_digits(mdict, delta_class) return timedelta(seconds=float(sval)) * sign def enable_dateutil(): global HAS_RELITIVE_TIMEDELTA assert relativedelta is not None, 'Module python-dateutil should be installed before.' HAS_RELITIVE_TIMEDELTA = True def disable_dateutil(): global HAS_RELITIVE_TIMEDELTA HAS_RELITIVE_TIMEDELTA = False def parse( sval: typing.Union[str, int, float], granularity: str = 'seconds', raise_exception: bool = False, as_timedelta: bool = False, ) -> typing.Optional[typing.Union[int, float, timedelta, typing.NoReturn]]: """ Parse a time expression, returning it as a number of seconds. If possible, the return value will be an `int`; if this is not possible, the return will be a `float`. Returns `None` if a time expression cannot be parsed from the given string. Arguments: - `sval`: the string value to parse - `granularity`: minimal type of digits after last colon (default is ``seconds``) - `raise_exception`: raise exception on parsing errors (default is ``False``) - `as_timedelta`: return ``datetime.timedelta`` object instead of ``int`` (default is ``False``) >>> parse('1:24') 84 >>> parse(':22') 22 >>> parse('1 minute, 24 secs') 84 >>> parse('1m24s') 84 >>> parse('1.2 minutes') 72 >>> parse('1.2 seconds') 1.2 Time expressions can be signed. >>> parse('- 1 minute') -60 >>> parse('+ 1 minute') 60 If granularity is specified as ``minutes``, then ambiguous digits following a colon will be interpreted as minutes; otherwise they are considered seconds. >>> parse('1:30') 90 >>> parse('1:30', granularity='minutes') 5400 If ``as_timedelta`` is specified as ``True``, then return timedelta object. >>> parse('24h', as_timedelta=True) relativedelta(days=+1) >>> parse('48:00', as_timedelta=True, granularity='minutes') relativedelta(days=+2) If ``raise_exception`` is specified as ``True``, then exception will raised on failed parsing. >>> parse(':1.1.1', raise_exception=True) Traceback (most recent call last): ... ValueError: could not convert string to float: ':1.1.1' """ try: value = _parse(sval, granularity, relativedelta if HAS_RELITIVE_TIMEDELTA and as_timedelta else timedelta) if not as_timedelta and value is not None: new_value = value.total_seconds() if new_value.is_integer(): return int(new_value) else: return new_value return value except Exception: if raise_exception: raise return None 0707010000000B000081A4000000000000000000000001645D608F0000051B000000000000000000000000000000000000001D00000000pytimeparse2-1.7.1/setup.cfg[metadata] name = pytimeparse2 version = attr: pytimeparse2.__version__ description = Time expression parser. long_description = file: README.rst long_description_content_type = text/x-rst license = MIT author = Sergey Klyuykov author_email = onegreyonewhite@mail.ru url = https://github.com/onegreyonewhite/pytimeparse2 keywords = parsing, time, timeparsing, text classifiers = Development Status :: 5 - Production/Stable Intended Audience :: Developers License :: OSI Approved :: MIT License Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only 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 :: 3.11 Programming Language :: Python :: Implementation :: CPython Topic :: Software Development :: Libraries Topic :: Software Development :: Libraries :: Python Modules Topic :: Text Processing Topic :: Utilities [options] zip_safe = False include_package_data = True python_requires = >=3.6 [options.extras_require] dateutil = python-dateutil~=2.8.2 [build_sphinx] project = 'pytimeparse2' [aliases] 0707010000000C000081A4000000000000000000000001645D608F00003870000000000000000000000000000000000000001C00000000pytimeparse2-1.7.1/setup.py#!/usr/bin/env python # -*- coding: utf-8 -*- """ setup.py (c) Sergey Klyuykov 3 Nov 2021 distutils setup script for pytimeparse2. """ # Compilation block ######################################################################################## import re import os import sys import subprocess import fnmatch import codecs import gzip import shutil # allow setup.py to be run from any path os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) from setuptools import find_packages, setup, errors, Command from setuptools.extension import Extension from setuptools.command.sdist import sdist as _sdist from setuptools.command.build_py import build_py as build_py_orig from setuptools.command.install_lib import install_lib as _install_lib try: from Cython.Build import cythonize, build_ext as _build_ext except ImportError: has_cython = False else: has_cython = True try: from sphinx.setup_command import BuildDoc import sphinx # noqa: F401 has_sphinx = True except ImportError: has_sphinx = False ignored_keys = ['-h', '--help', '--version'] is_help = any([a for a in ignored_keys if a in sys.argv]) is_develop = 'develop' in sys.argv is_build = (any([a for a in ['compile', 'bdist_wheel', 'bdist'] if a in sys.argv]) or is_develop) and not is_help def get_discription(file_path='README.rst', folder=os.getcwd()): with codecs.open("{}/{}".format(folder, file_path), 'r', encoding='utf-8') as readme: return readme.read() def load_requirements(file_name, folder=os.getcwd()): with codecs.open(os.path.join(folder, file_name), 'r', encoding='utf-8')as req_file: return req_file.read().strip().split('\n') def get_file_ext(ext): file_types = [".py", ".pyx", ".c", '.cpp'] if has_cython else [".c", '.cpp', ".py"] for ftype in file_types: fname = ext.replace(".", "/") + ftype if os.path.exists(fname): return fname return None def listfiles(folder): if not isinstance(folder, (list, tuple)): folder = [folder] folder = filter(lambda p: os.path.isdir(p), folder) for one_folder in folder: for root, folders, files in os.walk(one_folder): for filename in folders + files: yield os.path.join(root, filename) def clear_old_extentions(extensions_list, packages): for filename in listfiles(packages): _filename, _f_ext = os.path.splitext(filename) if os.path.isdir(_filename) or _f_ext not in ['.c', '.cpp']: continue has_py = ( os.path.exists('{}.py'.format(_filename)) or os.path.exists('{}.pyx'.format(_filename)) ) if has_py and filename.replace('/', '.').replace(_f_ext, '') in extensions_list: print('Removing old extention [{}].'.format(filename)) os.remove(filename) def make_extention(module_name, files, extra_compile_args, main_include_dir=os.path.join(os.getcwd(), 'include')): include_dirs = list(filter( lambda f: bool(f) and os.path.exists(f) and os.path.isdir(f), [os.path.join(module_name.split('.')[0], 'include'), main_include_dir] )) return Extension( module_name, files, extra_compile_args=extra_compile_args, include_dirs=include_dirs ) def make_extensions(extensions_list, packages): if not isinstance(extensions_list, list): raise Exception("Extension list should be `list`.") if not is_help: clear_old_extentions(extensions_list, packages) extensions_dict = {} for ext in extensions_list: files = [] module_name = ext if isinstance(ext, (list, tuple)): module_name = ext[0] for file_module in ext[1]: file_name = get_file_ext(file_module) files += [file_name] if file_name else [] else: file_name = get_file_ext(ext) files += [file_name] if file_name else [] if files: extensions_dict[module_name] = files extra_compile_args = [ '-g0', '-ggdb1', "-fno-strict-aliasing", "-ffast-math", "-fno-var-tracking-assignments", "-pipe", "-std=c99", '-Werror=sign-compare', ] if 'compile' in sys.argv: extra_compile_args.append("-DBUILD_FROM_SOURCE") ext_modules = list( make_extention(m, f, extra_compile_args) for m, f in extensions_dict.items() ) ext_count = len(ext_modules) nthreads = ext_count if ext_count < 10 else 10 language_level = 3 if is_help: pass elif has_cython and ('compile' in sys.argv or 'bdist_wheel' in sys.argv or 'build_ext' in sys.argv): cy_kwargs = dict( nthreads=nthreads, force=True, language_level=language_level, compiler_directives=dict( linetrace='CYTHON_TRACE_NOGIL' in sys.argv, profile=True, c_string_type='str', c_string_encoding='utf8' ), ) return cythonize(ext_modules, **cy_kwargs), extensions_dict return ext_modules, extensions_dict def minify_js_file(js_file, jsmin_func): return jsmin_func(js_file, quote_chars="'\"`") def minify_css_file(css_file, cssmin_func): return cssmin_func(css_file) def minify_static_files(base_dir, files, exclude=None): exclude = exclude or [] patterns = dict() try: from jsmin import jsmin as jsmin_func patterns['*.js'] = (minify_js_file, jsmin_func) except: pass try: from csscompressor import compress as csscompressor_func patterns['*.css'] = (minify_css_file, csscompressor_func) except: pass regex_exclude = [re.compile(r, re.MULTILINE) for r in exclude] for fnext, funcs in patterns.items(): for fext_file in filter(lambda f: fnmatch.fnmatch(f, fnext), files): if fnmatch.fnmatch(fext_file, '*.min.*'): continue fext_file = os.path.join(base_dir, fext_file) if os.path.exists(fext_file): if not any(filter(lambda fp: bool(fp.search(fext_file)), regex_exclude)): func, subfunc = funcs with codecs.open(fext_file, 'r', encoding='utf-8') as static_file_fd: minified = func(static_file_fd.read(), subfunc) with codecs.open(fext_file, 'w', encoding='utf-8') as static_file_fd: static_file_fd.write(minified) print('Minfied file {fext_file}.'.format(fext_file=fext_file)) with open(fext_file, 'rb') as f_in: with gzip.open("{}.gz".format(fext_file), 'wb') as f_out: shutil.copyfileobj(f_in, f_out) print('Compressed file {fext_file}.'.format(fext_file=fext_file)) def compile_py_func(fullname, compile_file_func): if compile_file_func(fullname, ddir=os.path.dirname(fullname), legacy=True, optimize=0): os.remove(fullname) def compile_python_sources(base_dir, files, exclude=None): exclude = exclude or [] patterns = dict() try: from compileall import compile_file patterns['*.py'] = (compile_py_func, compile_file) except: pass regex_exclude = [re.compile(r, re.MULTILINE) for r in exclude] for fnext, funcs in patterns.items(): for fext_file in filter(lambda f: fnmatch.fnmatch(f, fnext), files): fext_file = os.path.join(base_dir, fext_file) if os.path.exists(fext_file): if not any(filter(lambda fp: bool(fp.search(fext_file)), regex_exclude)): func, subfunc = funcs funcs[0](fext_file, funcs[1]) print('Compiled {fext_file}.'.format(fext_file=fext_file)) class _Compile(_sdist): extensions_dict = dict() static_exclude = [] def __filter_files(self, files): for _files in self.extensions_dict.values(): for file in _files: if file in files: files.remove(file) return files def make_release_tree(self, base_dir, files): if has_cython: files = self.__filter_files(files) _sdist.make_release_tree(self, base_dir, files) minify_static_files(base_dir, files, self.static_exclude) def run(self): return _sdist.run(self) class GithubRelease(Command): ''' Make release on github via githubrelease ''' description = 'Make release on github via githubrelease' user_options = [ ('body=', 'b', 'Body message.'), ('assets=', 'a', 'Release assets patterns.'), ('repo=', 'r', 'Repository for release.'), ('release=', 'R', 'Release version.'), ('dry-run=', 'd', 'Dry run.'), ('publish=', 'p', 'Publish release or just create draft.'), ] def initialize_options(self): self.body = None or os.getenv('CI_COMMIT_DESCRIPTION', None) self.assets = None self.repo = None self.dry_run = False self.publish = False self.release = None or self.distribution.metadata.version def finalize_options(self): if self.repo is None: raise Exception("Parameter --repo is missing") if self.release is None: raise Exception("Parameter --release is missing") self._gh_args = (self.repo, self.release) self._gh_kwargs = dict( publish=self.publish, name=self.release, dry_run=self.dry_run ) if self.assets: assets = self.assets.format(release=self.release) assets = list(filter(bool, assets.split('\n'))) self._gh_kwargs['asset_pattern'] = assets if self.body: self._gh_kwargs['body'] = self.body def run(self): from github_release import gh_release_create gh_release_create(*self._gh_args, **self._gh_kwargs) class build_py(build_py_orig): exclude = [] compile_extentions_types = ['.py', '.pyx'] wheel_extentions_types = ['.c', '.cpp'] + compile_extentions_types def _filter_modules(self, module_tuple): pkg, mod, file = module_tuple try: file_name, file_ext = os.path.splitext(file) module_name = file_name.replace('/', '.') except: return True if 'bdist_wheel' in sys.argv: exclude_list = self.wheel_extentions_types elif 'compile' in sys.argv: exclude_list = self.compile_extentions_types else: return True if module_name in self.exclude and file_ext in exclude_list: return False return True def find_package_modules(self, package, package_dir): modules = build_py_orig.find_package_modules(self, package, package_dir) return list(filter(self._filter_modules, modules)) class install_lib(_install_lib): exclude = [] static_exclude = [] compile_exclude = [] def _filter_files_with_ext(self, filename): _filename, _fext = os.path.splitext(filename) if _fext in build_py.wheel_extentions_types: return True return False def install(self): result = _install_lib.install(self) files = list(listfiles(self.install_dir)) so_extentions = list(filter(lambda f: fnmatch.fnmatch(f, '*.so'), files)) for source in filter(self._filter_files_with_ext, files): _source_name, _source_ext = os.path.splitext(source) if any(filter(lambda f: fnmatch.fnmatch(f, _source_name+"*.so"), so_extentions)): print('Removing extention sources [{}].'.format(source)) os.remove(source) minify_static_files('', files, self.static_exclude) if os.getenv('BUILD_COMPILE', '') == 'true': compile_python_sources('', files, self.compile_exclude) return result def get_compile_command(extensions_dict=None): extensions_dict = extensions_dict or dict() compile_class = _Compile compile_class.extensions_dict = extensions_dict return compile_class def make_setup(**opts): if 'packages' not in opts: opts['packages'] = find_packages() ext_modules_list = opts.pop('ext_modules_list', []) ext_mod, ext_mod_dict = make_extensions(ext_modules_list, opts['packages']) opts['ext_modules'] = opts.get('ext_modules', []) + ext_mod cmdclass = opts.get('cmdclass', dict()) static_exclude = opts.pop('static_exclude_min', []) if 'compile' not in cmdclass: compile_class = get_compile_command(ext_mod_dict) compile_class.static_exclude = static_exclude cmdclass.update({"compile": get_compile_command(ext_mod_dict)}) if has_cython: build_py.exclude = ext_modules_list install_lib.static_exclude = static_exclude install_lib.compile_exclude = opts.pop('compile_modules_exclude', []) cmdclass.update({ 'build_ext': _build_ext, 'build_py': build_py, 'install_lib': install_lib }) if has_sphinx and 'build_sphinx' not in cmdclass: cmdclass['build_sphinx'] = BuildDoc cmdclass['githubrelease'] = GithubRelease opts['cmdclass'] = cmdclass webpack_path = os.path.join(os.getcwd(), 'webpack.config.js') if os.path.exists(webpack_path) and is_build and os.environ.get('DONT_YARN', "") != 'true': try: subprocess.check_call(['yarn', 'install', '--pure-lockfile', '--mutex network'], stdout=sys.stdout, stderr=sys.stderr) subprocess.check_call(['yarn', 'devBuild' if is_develop else 'build'], stdout=sys.stdout, stderr=sys.stderr) except Exception as err: raise errors.CompileError(str(err)) setup(**opts) ######################################################################################## # end block ext_list = [] if 'develop' in sys.argv: ext_list = [] kwargs = dict( name='pytimeparse2', py_modules=['pytimeparse2'], ext_modules_list=ext_list, install_requires=[], project_urls={ "Issue Tracker": "https://github.com/onegreyonewhite/pytimeparse2/-/issues", "Source Code": "https://github.com/onegreyonewhite/pytimeparse2.git", "Releases": "https://pypi.org/project/pytimeparse2/#history", }, ) make_setup(**kwargs) 0707010000000D000081A4000000000000000000000001645D608F0000A46A000000000000000000000000000000000000001C00000000pytimeparse2-1.7.1/tests.py#!/usr/bin/env python # -*- coding: utf-8 -*- """ (c) Sergey Klyuykov <onegreyonewhite@mail.ru> 3 Nov 2021 Unit tests for the `parse` function. """ from __future__ import absolute_import import datetime import doctest import re import pytimeparse2 as timeparse import unittest from dateutil.relativedelta import relativedelta class TestParsing(unittest.TestCase): """ Unit tests for basic regex mat """ def test_mins(self): """Test parsing minutes.""" self.assertEqual(re.match(timeparse.MINS, '32m').groupdict(), {'minutes': '32'}) self.assertEqual(re.match(timeparse.MINS, '32min').groupdict(), {'minutes': '32'}) self.assertEqual(re.match(timeparse.MINS, '32mins').groupdict(), {'minutes': '32'}) self.assertEqual(re.match(timeparse.MINS, '32minute').groupdict(), {'minutes': '32'}) self.assertEqual(re.match(timeparse.MINS, '32minutes').groupdict(), {'minutes': '32'}) self.assertEqual(re.match(timeparse.MINS, '32mins').groupdict(), {'minutes': '32'}) self.assertEqual(re.match(timeparse.MINS, '32min').groupdict(), {'minutes': '32'}) def test_hrs(self): """Test parsing hours.""" self.assertEqual(re.match(timeparse.HOURS, '32h').groupdict(), {'hours': '32'}) self.assertEqual(re.match(timeparse.HOURS, '32hr').groupdict(), {'hours': '32'}) self.assertEqual(re.match(timeparse.HOURS, '32hrs').groupdict(), {'hours': '32'}) self.assertEqual(re.match(timeparse.HOURS, '32hour').groupdict(), {'hours': '32'}) self.assertEqual(re.match(timeparse.HOURS, '32hours').groupdict(), {'hours': '32'}) self.assertEqual(re.match(timeparse.HOURS, '32 hours').groupdict(), {'hours': '32'}) self.assertEqual(re.match(timeparse.HOURS, '32 h').groupdict(), {'hours': '32'}) def test_months(self): """Test parsing months.""" self.assertEqual(re.match(timeparse.MONTHS, '32mo').groupdict(), {'months': '32'}) self.assertEqual(re.match(timeparse.MONTHS, '32mon').groupdict(), {'months': '32'}) self.assertEqual(re.match(timeparse.MONTHS, '32month').groupdict(), {'months': '32'}) self.assertEqual(re.match(timeparse.MONTHS, '32months').groupdict(), {'months': '32'}) self.assertEqual(re.match(timeparse.MONTHS, '32 mo').groupdict(), {'months': '32'}) self.assertEqual(re.match(timeparse.MONTHS, '32 months').groupdict(), {'months': '32'}) self.assertEqual(re.match(timeparse.MONTHS, '32mos').groupdict(), {'months': '32'}) self.assertEqual(re.match(timeparse.MONTHS, '32mths').groupdict(), {'months': '32'}) self.assertEqual(re.match(timeparse.MONTHS, '2.3mo').groupdict(), {'months': '2.3'}) self.assertEqual(re.match(timeparse.MONTHS, '2.5mo').groupdict(), {'months': '2.5'}) def test_years(self): """Test parsing years.""" self.assertEqual(re.match(timeparse.YEARS, '32y').groupdict(), {'years': '32'}) self.assertEqual(re.match(timeparse.YEARS, '32ys').groupdict(), {'years': '32'}) self.assertEqual(re.match(timeparse.YEARS, '32yrs').groupdict(), {'years': '32'}) self.assertEqual(re.match(timeparse.YEARS, '32year').groupdict(), {'years': '32'}) self.assertEqual(re.match(timeparse.YEARS, '32years').groupdict(), {'years': '32'}) self.assertEqual(re.match(timeparse.YEARS, '32 y').groupdict(), {'years': '32'}) self.assertEqual(re.match(timeparse.YEARS, '32 years').groupdict(), {'years': '32'}) self.assertEqual(re.match(timeparse.YEARS, '2.3y').groupdict(), {'years': '2.3'}) self.assertEqual(re.match(timeparse.YEARS, '2.5y').groupdict(), {'years': '2.5'}) def test_time(self): """Test parsing time expression.""" self.assertGreater( set(re.match(timeparse.TIMEFORMATS[0] + r'\s*$', '16h32m64s ').groupdict().items()), set([('hours', '16'), ('minutes', '32'), ('seconds', '64')])) class TestNumberOutput(unittest.TestCase): """ Unit tests to ensure that numerical outputs are correct """ def test_timeparse_multipliers(self): """Test parsing time unit multipliers.""" self.assertEqual(timeparse.parse('32 min'), 1920) self.assertEqual(timeparse.parse('1 min'), 60) self.assertEqual(timeparse.parse('1 hours'), 3600) self.assertEqual(timeparse.parse('1 day'), 86400) self.assertEqual(timeparse.parse('1 sec'), 1) def test_timeparse_signs(self): """Test parsing time signs.""" self.assertEqual(timeparse.parse('+32 m 1 s'), 1921) self.assertEqual(timeparse.parse('+ 32 m 1 s'), 1921) self.assertEqual(timeparse.parse('-32 m 1 s'), -1921) self.assertEqual(timeparse.parse('- 32 m 1 s'), -1921) self.assertIsNone(timeparse.parse('32 m - 1 s')) self.assertIsNone(timeparse.parse('32 m + 1 s')) def test_timeparse_1(self): """timeparse test case 1.""" self.assertEqual(timeparse.parse('32m'), 1920) self.assertEqual(timeparse.parse('+32m'), 1920) self.assertEqual(timeparse.parse('-32m'), -1920) def test_timeparse_2(self): """timeparse test case 2.""" self.assertEqual(timeparse.parse('2h32m'), 9120) self.assertEqual(timeparse.parse('+2h32m'), 9120) self.assertEqual(timeparse.parse('-2h32m'), -9120) def test_timeparse_3(self): """timeparse test case 3.""" self.assertEqual(timeparse.parse('3d2h32m'), 268320) self.assertEqual(timeparse.parse('+3d2h32m'), 268320) self.assertEqual(timeparse.parse('-3d2h32m'), -268320) def test_timeparse_4(self): """timeparse test case 4.""" self.assertEqual(timeparse.parse('1w3d2h32m'), 873120) self.assertEqual(timeparse.parse('+1w3d2h32m'), 873120) self.assertEqual(timeparse.parse('-1w3d2h32m'), -873120) def test_timeparse_5(self): """timeparse test case 5.""" self.assertEqual(timeparse.parse('1w 3d 2h 32m'), 873120) self.assertEqual(timeparse.parse('+1w 3d 2h 32m'), 873120) self.assertEqual(timeparse.parse('-1w 3d 2h 32m'), -873120) def test_timeparse_6(self): """timeparse test case 6.""" self.assertEqual(timeparse.parse('1 w 3 d 2 h 32 m'), 873120) self.assertEqual(timeparse.parse('+1 w 3 d 2 h 32 m'), 873120) self.assertEqual(timeparse.parse('-1 w 3 d 2 h 32 m'), -873120) def test_timeparse_7(self): """timeparse test case 7.""" self.assertEqual(timeparse.parse('4:13'), 253) self.assertEqual(timeparse.parse('+4:13'), 253) self.assertEqual(timeparse.parse('-4:13'), -253) def test_timeparse_bare_seconds(self): """timeparse test bare seconds, without minutes.""" self.assertEqual(timeparse.parse(':13'), 13) self.assertEqual(timeparse.parse('+:13'), 13) self.assertEqual(timeparse.parse('-:13'), -13) def test_timeparse_8(self): """timeparse test case 8.""" self.assertEqual(timeparse.parse('4:13:02'), 15182) self.assertEqual(timeparse.parse('+4:13:02'), 15182) self.assertEqual(timeparse.parse('-4:13:02'), -15182) def test_timeparse_9(self): """timeparse test case 9.""" self.assertAlmostEqual(timeparse.parse('4:13:02.266'), 15182.266) self.assertAlmostEqual(timeparse.parse('+4:13:02.266'), 15182.266) self.assertAlmostEqual(timeparse.parse('-4:13:02.266'), -15182.266) def test_timeparse_10(self): """timeparse test case 10.""" self.assertAlmostEqual(timeparse.parse('2:04:13:02.266'), 187982.266) self.assertAlmostEqual(timeparse.parse('+2:04:13:02.266'), 187982.266) self.assertAlmostEqual(timeparse.parse('-2:04:13:02.266'), -187982.266) def test_timeparse_granularity_1(self): """Check that minute-level granularity applies correctly.""" self.assertEqual(timeparse.parse('4:32', granularity='minutes'), 272*60) self.assertEqual(timeparse.parse('+4:32', granularity='minutes'), 272*60) self.assertEqual(timeparse.parse('-4:32', granularity='minutes'), -272*60) def test_timeparse_granularity_2(self): """Check that minute-level granularity does not apply inappropriately.""" self.assertEqual(timeparse.parse('4:32:02', granularity='minutes'), 272*60+2) self.assertEqual(timeparse.parse('+4:32:02', granularity='minutes'), 272*60+2) self.assertEqual(timeparse.parse('-4:32:02', granularity='minutes'), -(272*60+2)) def test_timeparse_granularity_3(self): """Check that minute-level granularity does not apply inappropriately.""" self.assertAlmostEqual(timeparse.parse('7:02.223', granularity='minutes'), 7*60 + 2.223) self.assertAlmostEqual(timeparse.parse('+7:02.223', granularity='minutes'), 7*60 + 2.223) self.assertAlmostEqual(timeparse.parse('-7:02.223', granularity='minutes'), -(7*60 + 2.223)) def test_timeparse_granularity_4(self): """Check that minute-level granularity does not apply inappropriately.""" self.assertEqual(timeparse.parse('0:02', granularity='seconds'), 2) self.assertEqual(timeparse.parse('+0:02', granularity='seconds'), 2) self.assertEqual(timeparse.parse('-0:02', granularity='seconds'), -2) def test_timeparse_unparsed(self): """Check that unparsed values tries to converts into int(). """ self.assertEqual(timeparse.parse(100), 100) self.assertEqual(timeparse.parse(-18.333), -18.333) self.assertEqual(timeparse.parse('99.1'), 99.1) self.assertEqual(timeparse.parse('-99.1'), -99.1) def test_timeparse_11(self): """timeparse test case 11.""" # uptime format self.assertEqual(timeparse.parse('2 days, 4:13:02'), 187982) self.assertEqual(timeparse.parse('+2 days, 4:13:02'), 187982) self.assertEqual(timeparse.parse('-2 days, 4:13:02'), -187982) def test_timeparse_12(self): """timeparse test case 12.""" self.assertAlmostEqual(timeparse.parse('2 days, 4:13:02.266'), 187982.266) self.assertAlmostEqual(timeparse.parse('+2 days, 4:13:02.266'), 187982.266) self.assertAlmostEqual(timeparse.parse('-2 days, 4:13:02.266'), -187982.266) def test_timeparse_13(self): """timeparse test case 13.""" self.assertEqual(timeparse.parse('5hr34m56s'), 20096) self.assertEqual(timeparse.parse('+5hr34m56s'), 20096) self.assertEqual(timeparse.parse('-5hr34m56s'), -20096) def test_timeparse_14(self): """timeparse test case 14.""" self.assertEqual(timeparse.parse('5 hours, 34 minutes, 56 seconds'), 20096) self.assertEqual(timeparse.parse('+5 hours, 34 minutes, 56 seconds'), 20096) self.assertEqual(timeparse.parse('-5 hours, 34 minutes, 56 seconds'), -20096) def test_timeparse_15(self): """timeparse test case 15.""" self.assertEqual(timeparse.parse('5 hrs, 34 mins, 56 secs'), 20096) self.assertEqual(timeparse.parse('+5 hrs, 34 mins, 56 secs'), 20096) self.assertEqual(timeparse.parse('-5 hrs, 34 mins, 56 secs'), -20096) def test_timeparse_16(self): """timeparse test case 16.""" self.assertEqual( timeparse.parse('2 days, 5 hours, 34 minutes, 56 seconds'), 192896) self.assertEqual( timeparse.parse('+2 days, 5 hours, 34 minutes, 56 seconds'), 192896) self.assertEqual( timeparse.parse('-2 days, 5 hours, 34 minutes, 56 seconds'), -192896) def test_timeparse_16b(self): """timeparse test case 16b.""" self.assertAlmostEqual(timeparse.parse('1.75 s'), 1.75) self.assertAlmostEqual(timeparse.parse('+1.75 s'), 1.75) self.assertAlmostEqual(timeparse.parse('-1.75 s'), -1.75) def test_timeparse_16c(self): """timeparse test case 16c.""" self.assertAlmostEqual(timeparse.parse('1.75 sec'), 1.75) self.assertAlmostEqual(timeparse.parse('+1.75 sec'), 1.75) self.assertAlmostEqual(timeparse.parse('-1.75 sec'), -1.75) def test_timeparse_16d(self): """timeparse test case 16d.""" self.assertAlmostEqual(timeparse.parse('1.75 secs'), 1.75) self.assertAlmostEqual(timeparse.parse('+1.75 secs'), 1.75) self.assertAlmostEqual(timeparse.parse('-1.75 secs'), -1.75) def test_timeparse_16e(self): """timeparse test case 16e.""" self.assertAlmostEqual(timeparse.parse('1.75 second'), 1.75) self.assertAlmostEqual(timeparse.parse('+1.75 second'), 1.75) self.assertAlmostEqual(timeparse.parse('-1.75 second'), -1.75) def test_timeparse_16f(self): """timeparse test case 16f.""" self.assertAlmostEqual(timeparse.parse('1.75 seconds'), 1.75) self.assertAlmostEqual(timeparse.parse('+1.75 seconds'), 1.75) self.assertAlmostEqual(timeparse.parse('-1.75 seconds'), -1.75) def test_timeparse_17(self): """timeparse test case 17.""" self.assertEqual(timeparse.parse('1.2 m'), 72) self.assertEqual(timeparse.parse('+1.2 m'), 72) self.assertEqual(timeparse.parse('-1.2 m'), -72) def test_timeparse_18(self): """timeparse test case 18.""" self.assertEqual(timeparse.parse('1.2 min'), 72) self.assertEqual(timeparse.parse('+1.2 min'), 72) self.assertEqual(timeparse.parse('-1.2 min'), -72) def test_timeparse_19(self): """timeparse test case 19.""" self.assertEqual(timeparse.parse('1.2 mins'), 72) self.assertEqual(timeparse.parse('+1.2 mins'), 72) self.assertEqual(timeparse.parse('-1.2 mins'), -72) def test_timeparse_20(self): """timeparse test case 20.""" self.assertEqual(timeparse.parse('1.2 minute'), 72) self.assertEqual(timeparse.parse('+1.2 minute'), 72) self.assertEqual(timeparse.parse('-1.2 minute'), -72) def test_timeparse_21(self): """timeparse test case 21.""" self.assertEqual(timeparse.parse('1.2 minutes'), 72) self.assertEqual(timeparse.parse('+1.2 minutes'), 72) self.assertEqual(timeparse.parse('-1.2 minutes'), -72) def test_timeparse_22(self): """timeparse test case 22.""" self.assertEqual(timeparse.parse('172 hours'), 619200) self.assertEqual(timeparse.parse('+172 hours'), 619200) self.assertEqual(timeparse.parse('-172 hours'), -619200) def test_timeparse_23(self): """timeparse test case 23.""" self.assertEqual(timeparse.parse('172 hr'), 619200) self.assertEqual(timeparse.parse('+172 hr'), 619200) self.assertEqual(timeparse.parse('-172 hr'), -619200) def test_timeparse_24(self): """timeparse test case 24.""" self.assertEqual(timeparse.parse('172 h'), 619200) self.assertEqual(timeparse.parse('+172 h'), 619200) self.assertEqual(timeparse.parse('-172 h'), -619200) def test_timeparse_25(self): """timeparse test case 25.""" self.assertEqual(timeparse.parse('172 hrs'), 619200) self.assertEqual(timeparse.parse('+172 hrs'), 619200) self.assertEqual(timeparse.parse('-172 hrs'), -619200) def test_timeparse_26(self): """timeparse test case 26.""" self.assertEqual(timeparse.parse('172 hour'), 619200) self.assertEqual(timeparse.parse('+172 hour'), 619200) self.assertEqual(timeparse.parse('-172 hour'), -619200) def test_timeparse_27(self): """timeparse test case 27.""" self.assertEqual(timeparse.parse('1.24 days'), 107136) self.assertEqual(timeparse.parse('+1.24 days'), 107136) self.assertEqual(timeparse.parse('-1.24 days'), -107136) def test_timeparse_28(self): """timeparse test case 28.""" self.assertEqual(timeparse.parse('5 d'), 432000) self.assertEqual(timeparse.parse('+5 d'), 432000) self.assertEqual(timeparse.parse('-5 d'), -432000) def test_timeparse_29(self): """timeparse test case 29.""" self.assertEqual(timeparse.parse('5 day'), 432000) self.assertEqual(timeparse.parse('+5 day'), 432000) self.assertEqual(timeparse.parse('-5 day'), -432000) def test_timeparse_30(self): """timeparse test case 30.""" self.assertEqual(timeparse.parse('5 days'), 432000) self.assertEqual(timeparse.parse('+5 days'), 432000) self.assertEqual(timeparse.parse('-5 days'), -432000) def test_timeparse_31(self): """timeparse test case 31.""" self.assertEqual(timeparse.parse('5.6 wk'), 3386880) self.assertEqual(timeparse.parse('+5.6 wk'), 3386880) self.assertEqual(timeparse.parse('-5.6 wk'), -3386880) def test_timeparse_32(self): """timeparse test case 32.""" self.assertEqual(timeparse.parse('5.6 week'), 3386880) self.assertEqual(timeparse.parse('+5.6 week'), 3386880) self.assertEqual(timeparse.parse('-5.6 week'), -3386880) def test_timeparse_33(self): """timeparse test case 33.""" self.assertEqual(timeparse.parse('5.6 weeks'), 3386880) self.assertEqual(timeparse.parse('+5.6 weeks'), 3386880) self.assertEqual(timeparse.parse('-5.6 weeks'), -3386880) def test_milliseconds(self): self.assertEqual(timeparse.parse('3 ms'), 0.003) self.assertEqual(timeparse.parse('3 millis'), 0.003) self.assertEqual(timeparse.parse('3 msecs'), 0.003) self.assertEqual(timeparse.parse('3 milliseconds'), 0.003) def test_plain_numbers(self): self.assertEqual(timeparse.parse('10'), 10) self.assertEqual(timeparse.parse('10.1'), 10.1) self.assertEqual(timeparse.parse('-10'), -10) self.assertEqual(timeparse.parse('-10.1'), -10.1) def test_combined(self): self.assertEqual(timeparse.parse('1y2mo3w4d5h6m7s8ms'), 38898367.008) class TestRelativeDeltaOutput(unittest.TestCase): """ Unit tests to ensure that numerical outputs are correct """ def test_timeparse_multipliers(self): """Test parsing time unit multipliers.""" self.assertEqual(timeparse.parse('32 min', as_timedelta=True), relativedelta(minutes=32)) self.assertEqual(timeparse.parse('1 min', as_timedelta=True), relativedelta(minutes=1)) self.assertEqual(timeparse.parse('1 hours', as_timedelta=True), relativedelta(hours=1)) self.assertEqual(timeparse.parse('1 day', as_timedelta=True), relativedelta(days=1)) self.assertEqual(timeparse.parse('1 sec', as_timedelta=True), relativedelta(seconds=1)) def test_timeparse_signs(self): """Test parsing time signs.""" self.assertEqual(timeparse.parse('+32 m 1 s', as_timedelta=True), relativedelta(minutes=32, seconds=1)) self.assertEqual(timeparse.parse('+ 32 m 1 s', as_timedelta=True), relativedelta(minutes=32, seconds=1)) self.assertEqual(timeparse.parse('-32 m 1 s', as_timedelta=True), -relativedelta(minutes=32, seconds=1)) self.assertEqual(timeparse.parse('- 32 m 1 s', as_timedelta=True), -relativedelta(minutes=32, seconds=1)) self.assertIsNone(timeparse.parse('32 m - 1 s', as_timedelta=True)) self.assertIsNone(timeparse.parse('32 m + 1 s', as_timedelta=True)) def test_timeparse_1(self): """timeparse test case 1.""" self.assertEqual(timeparse.parse('32m', as_timedelta=True), relativedelta(minutes=32)) self.assertEqual(timeparse.parse('+32m', as_timedelta=True), relativedelta(minutes=32)) self.assertEqual(timeparse.parse('-32m', as_timedelta=True), -relativedelta(minutes=32)) def test_timeparse_2(self): """timeparse test case 2.""" self.assertEqual(timeparse.parse('2h32m', as_timedelta=True), relativedelta(hours=2, minutes=32)) self.assertEqual(timeparse.parse('+2h32m', as_timedelta=True), relativedelta(hours=2, minutes=32)) self.assertEqual(timeparse.parse('-2h32m', as_timedelta=True), -relativedelta(hours=2, minutes=32)) def test_timeparse_3(self): """timeparse test case 3.""" self.assertEqual(timeparse.parse('3d2h32m', as_timedelta=True), relativedelta(days=3, hours=2, minutes=32)) self.assertEqual(timeparse.parse('+3d2h32m', as_timedelta=True), relativedelta(days=3, hours=2, minutes=32)) self.assertEqual(timeparse.parse('-3d2h32m', as_timedelta=True), -relativedelta(days=3, hours=2, minutes=32)) def test_timeparse_4(self): """timeparse test case 4.""" self.assertEqual(timeparse.parse('1w3d2h32m', as_timedelta=True), relativedelta(weeks=1, days=3, hours=2, minutes=32)) self.assertEqual(timeparse.parse('+1w3d2h32m', as_timedelta=True), relativedelta(weeks=1, days=3, hours=2, minutes=32)) self.assertEqual(timeparse.parse('-1w3d2h32m', as_timedelta=True), -relativedelta(weeks=1, days=3, hours=2, minutes=32)) def test_timeparse_5(self): """timeparse test case 5.""" self.assertEqual(timeparse.parse('1w 3d 2h 32m', as_timedelta=True), relativedelta(weeks=1, days=3, hours=2, minutes=32)) self.assertEqual(timeparse.parse('+1w 3d 2h 32m', as_timedelta=True), relativedelta(weeks=1, days=3, hours=2, minutes=32)) self.assertEqual(timeparse.parse('-1w 3d 2h 32m', as_timedelta=True), -relativedelta(weeks=1, days=3, hours=2, minutes=32)) def test_timeparse_6(self): """timeparse test case 6.""" self.assertEqual(timeparse.parse('1 w 3 d 2 h 32 m', as_timedelta=True), relativedelta(weeks=1, days=3, hours=2, minutes=32)) self.assertEqual(timeparse.parse('+1 w 3 d 2 h 32 m', as_timedelta=True), relativedelta(weeks=1, days=3, hours=2, minutes=32)) self.assertEqual(timeparse.parse('-1 w 3 d 2 h 32 m', as_timedelta=True), -relativedelta(weeks=1, days=3, hours=2, minutes=32)) def test_timeparse_7(self): """timeparse test case 7.""" self.assertEqual(timeparse.parse('4:13', as_timedelta=True), relativedelta(minutes=4, seconds=13)) self.assertEqual(timeparse.parse('+4:13', as_timedelta=True), relativedelta(minutes=4, seconds=13)) self.assertEqual(timeparse.parse('-4:13', as_timedelta=True), -relativedelta(minutes=4, seconds=13)) def test_timeparse_bare_seconds(self): """timeparse test bare seconds, without minutes.""" self.assertEqual(timeparse.parse(':13', as_timedelta=True), relativedelta(seconds=13)) self.assertEqual(timeparse.parse('+:13', as_timedelta=True), relativedelta(seconds=13)) self.assertEqual(timeparse.parse('-:13', as_timedelta=True), -relativedelta(seconds=13)) def test_timeparse_8(self): """timeparse test case 8.""" self.assertEqual(timeparse.parse('4:13:02', as_timedelta=True), relativedelta(hours=4, minutes=13, seconds=2)) self.assertEqual(timeparse.parse('+4:13:02', as_timedelta=True), relativedelta(hours=4, minutes=13, seconds=2)) self.assertEqual(timeparse.parse('-4:13:02', as_timedelta=True), -relativedelta(hours=4, minutes=13, seconds=2)) def test_timeparse_9(self): """timeparse test case 9.""" self.assertEqual(timeparse.parse('4:13:02.266', as_timedelta=True), relativedelta(hours=4, minutes=13, seconds=2, microseconds=266*1000)) self.assertEqual(timeparse.parse('+4:13:02.266', as_timedelta=True), relativedelta(hours=4, minutes=13, seconds=2, microseconds=266*1000)) self.assertEqual(timeparse.parse('-4:13:02.266', as_timedelta=True), -relativedelta(hours=4, minutes=13, seconds=2, microseconds=266*1000)) def test_timeparse_10(self): """timeparse test case 10.""" self.assertEqual(timeparse.parse('2:04:13:02.266', as_timedelta=True), relativedelta(days=2, hours=4, minutes=13, seconds=2, microseconds=266*1000)) self.assertEqual(timeparse.parse('+2:04:13:02.266', as_timedelta=True), relativedelta(days=2, hours=4, minutes=13, seconds=2, microseconds=266*1000)) self.assertEqual(timeparse.parse('-2:04:13:02.266', as_timedelta=True), -relativedelta(days=2, hours=4, minutes=13, seconds=2, microseconds=266*1000)) def test_timeparse_granularity_1(self): """Check that minute-level granularity applies correctly.""" self.assertEqual(timeparse.parse('4:32', granularity='minutes', as_timedelta=True), relativedelta(hours=4, minutes=32)) self.assertEqual(timeparse.parse('+4:32', granularity='minutes', as_timedelta=True), relativedelta(hours=4, minutes=32)) self.assertEqual(timeparse.parse('-4:32', granularity='minutes', as_timedelta=True), -relativedelta(hours=4, minutes=32)) def test_timeparse_granularity_2(self): """Check that minute-level granularity does not apply inappropriately.""" self.assertEqual(timeparse.parse('4:32:02', granularity='minutes', as_timedelta=True), relativedelta(hours=4, minutes=32, seconds=2)) self.assertEqual(timeparse.parse('+4:32:02', granularity='minutes', as_timedelta=True), relativedelta(hours=4, minutes=32, seconds=2)) self.assertEqual(timeparse.parse('-4:32:02', granularity='minutes', as_timedelta=True), -relativedelta(hours=4, minutes=32, seconds=2)) def test_timeparse_granularity_3(self): """Check that minute-level granularity does not apply inappropriately.""" self.assertEqual(timeparse.parse('7:02.223', granularity='minutes', as_timedelta=True), relativedelta(minutes=7, seconds=2, microseconds=1000*223)) self.assertEqual(timeparse.parse('+7:02.223', granularity='minutes', as_timedelta=True), relativedelta(minutes=7, seconds=2, microseconds=1000*223)) self.assertEqual(timeparse.parse('-7:02.223', granularity='minutes', as_timedelta=True), -relativedelta(minutes=7, seconds=2, microseconds=1000*223)) def test_timeparse_granularity_4(self): """Check that minute-level granularity does not apply inappropriately.""" self.assertEqual(timeparse.parse('0:02', granularity='seconds', as_timedelta=True), relativedelta(seconds=2)) self.assertEqual(timeparse.parse('+0:02', granularity='seconds', as_timedelta=True), relativedelta(seconds=2)) self.assertEqual(timeparse.parse('-0:02', granularity='seconds', as_timedelta=True), -relativedelta(seconds=2)) def test_timeparse_unparsed(self): """Check that unparsed values tries to converts into int(). """ self.assertEqual(timeparse.parse(100, as_timedelta=True), relativedelta(seconds=100)) self.assertEqual(timeparse.parse(-18.333, as_timedelta=True), -relativedelta(seconds=18, microseconds=333*1000)) self.assertEqual(timeparse.parse('99.1', as_timedelta=True), relativedelta(seconds=99, microseconds=100*1000)) self.assertEqual(timeparse.parse('-99.1', as_timedelta=True), -relativedelta(seconds=99, microseconds=100*1000)) def test_timeparse_11(self): """timeparse test case 11.""" # uptime format self.assertEqual(timeparse.parse('2 days, 4:13:02', as_timedelta=True), relativedelta(days=2, hours=4, minutes=13, seconds=2)) self.assertEqual(timeparse.parse('+2 days, 4:13:02', as_timedelta=True), relativedelta(days=2, hours=4, minutes=13, seconds=2)) self.assertEqual(timeparse.parse('-2 days, 4:13:02', as_timedelta=True), -relativedelta(days=2, hours=4, minutes=13, seconds=2)) def test_timeparse_12(self): """timeparse test case 12.""" self.assertEqual(timeparse.parse('2 days, 4:13:02.266', as_timedelta=True), relativedelta(days=2, hours=4, minutes=13, seconds=2, microseconds=1000*266)) self.assertEqual(timeparse.parse('+2 days, 4:13:02.266', as_timedelta=True), relativedelta(days=2, hours=4, minutes=13, seconds=2, microseconds=1000*266)) self.assertEqual(timeparse.parse('-2 days, 4:13:02.266', as_timedelta=True), -relativedelta(days=2, hours=4, minutes=13, seconds=2, microseconds=1000*266)) def test_timeparse_13(self): """timeparse test case 13.""" self.assertEqual(timeparse.parse('5hr34m56s', as_timedelta=True), relativedelta(hours=5, minutes=34, seconds=56)) self.assertEqual(timeparse.parse('+5hr34m56s', as_timedelta=True), relativedelta(hours=5, minutes=34, seconds=56)) self.assertEqual(timeparse.parse('-5hr34m56s', as_timedelta=True), -relativedelta(hours=5, minutes=34, seconds=56)) def test_timeparse_14(self): """timeparse test case 14.""" self.assertEqual(timeparse.parse('5 hours, 34 minutes, 56 seconds', as_timedelta=True), relativedelta(hours=5, minutes=34, seconds=56)) self.assertEqual(timeparse.parse('+5 hours, 34 minutes, 56 seconds', as_timedelta=True), relativedelta(hours=5, minutes=34, seconds=56)) self.assertEqual(timeparse.parse('-5 hours, 34 minutes, 56 seconds', as_timedelta=True), -relativedelta(hours=5, minutes=34, seconds=56)) def test_timeparse_15(self): """timeparse test case 15.""" self.assertEqual(timeparse.parse('5 hrs, 34 mins, 56 secs', as_timedelta=True), relativedelta(hours=5, minutes=34, seconds=56)) self.assertEqual(timeparse.parse('+5 hrs, 34 mins, 56 secs', as_timedelta=True), relativedelta(hours=5, minutes=34, seconds=56)) self.assertEqual(timeparse.parse('-5 hrs, 34 mins, 56 secs', as_timedelta=True), -relativedelta(hours=5, minutes=34, seconds=56)) def test_timeparse_16(self): """timeparse test case 16.""" self.assertEqual(timeparse.parse('2 days, 5 hours, 34 minutes, 56 seconds', as_timedelta=True), relativedelta(days=2, hours=5, minutes=34, seconds=56)) self.assertEqual(timeparse.parse('+2 days, 5 hours, 34 minutes, 56 seconds', as_timedelta=True), relativedelta(days=2, hours=5, minutes=34, seconds=56)) self.assertEqual(timeparse.parse('-2 days, 5 hours, 34 minutes, 56 seconds', as_timedelta=True), -relativedelta(days=2, hours=5, minutes=34, seconds=56)) def test_timeparse_16b(self): """timeparse test case 16b.""" self.assertEqual(timeparse.parse('1.75 s', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('+1.75 s', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('-1.75 s', as_timedelta=True), -relativedelta(seconds=1, microseconds=75*10000)) def test_timeparse_16c(self): """timeparse test case 16c.""" self.assertEqual(timeparse.parse('1.75 sec', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('+1.75 sec', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('-1.75 sec', as_timedelta=True), -relativedelta(seconds=1, microseconds=75*10000)) def test_timeparse_16d(self): """timeparse test case 16d.""" self.assertEqual(timeparse.parse('1.75 secs', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('+1.75 secs', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('-1.75 secs', as_timedelta=True), -relativedelta(seconds=1, microseconds=75*10000)) def test_timeparse_16e(self): """timeparse test case 16e.""" self.assertEqual(timeparse.parse('1.75 second', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('+1.75 second', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('-1.75 second', as_timedelta=True), -relativedelta(seconds=1, microseconds=75*10000)) def test_timeparse_16f(self): """timeparse test case 16f.""" self.assertEqual(timeparse.parse('1.75 seconds', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('+1.75 seconds', as_timedelta=True), relativedelta(seconds=1, microseconds=75*10000)) self.assertEqual(timeparse.parse('-1.75 seconds', as_timedelta=True), -relativedelta(seconds=1, microseconds=75*10000)) def test_timeparse_17(self): """timeparse test case 17.""" self.assertEqual(timeparse.parse('1.2 m', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('+1.2 m', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('-1.2 m', as_timedelta=True), -relativedelta(minutes=1, seconds=12)) def test_timeparse_18(self): """timeparse test case 18.""" self.assertEqual(timeparse.parse('1.2 min', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('+1.2 min', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('-1.2 min', as_timedelta=True), -relativedelta(minutes=1, seconds=12)) def test_timeparse_19(self): """timeparse test case 19.""" self.assertEqual(timeparse.parse('1.2 mins', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('+1.2 mins', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('-1.2 mins', as_timedelta=True), -relativedelta(minutes=1, seconds=12)) def test_timeparse_20(self): """timeparse test case 20.""" self.assertEqual(timeparse.parse('1.2 minute', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('+1.2 minute', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('-1.2 minute', as_timedelta=True), -relativedelta(minutes=1, seconds=12)) def test_timeparse_21(self): """timeparse test case 21.""" self.assertEqual(timeparse.parse('1.2 minutes', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('+1.2 minutes', as_timedelta=True), relativedelta(minutes=1, seconds=12)) self.assertEqual(timeparse.parse('-1.2 minutes', as_timedelta=True), -relativedelta(minutes=1, seconds=12)) def test_timeparse_22(self): """timeparse test case 22.""" self.assertEqual(timeparse.parse('172 hours', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('+172 hours', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('-172 hours', as_timedelta=True), -relativedelta(hours=172)) def test_timeparse_23(self): """timeparse test case 23.""" self.assertEqual(timeparse.parse('172 hr', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('+172 hr', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('-172 hr', as_timedelta=True), -relativedelta(hours=172)) def test_timeparse_24(self): """timeparse test case 24.""" self.assertEqual(timeparse.parse('172 h', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('+172 h', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('-172 h', as_timedelta=True), -relativedelta(hours=172)) def test_timeparse_25(self): """timeparse test case 25.""" self.assertEqual(timeparse.parse('172 hrs', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('+172 hrs', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('-172 hrs', as_timedelta=True), -relativedelta(hours=172)) def test_timeparse_26(self): """timeparse test case 26.""" self.assertEqual(timeparse.parse('172 hour', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('+172 hour', as_timedelta=True), relativedelta(hours=172)) self.assertEqual(timeparse.parse('-172 hour', as_timedelta=True), -relativedelta(hours=172)) def test_timeparse_27(self): """timeparse test case 27.""" self.assertEqual(timeparse.parse('1.24 days', as_timedelta=True), relativedelta(days=1, hours=5, minutes=45, seconds=36)) self.assertEqual(timeparse.parse('+1.24 days', as_timedelta=True), relativedelta(days=1, hours=5, minutes=45, seconds=36)) self.assertEqual(timeparse.parse('-1.24 days', as_timedelta=True), -relativedelta(days=1, hours=5, minutes=45, seconds=36)) def test_timeparse_28(self): """timeparse test case 28.""" self.assertEqual(timeparse.parse('5 d', as_timedelta=True), relativedelta(days=5)) self.assertEqual(timeparse.parse('+5 d', as_timedelta=True), relativedelta(days=5)) self.assertEqual(timeparse.parse('-5 d', as_timedelta=True), -relativedelta(days=5)) def test_timeparse_29(self): """timeparse test case 29.""" self.assertEqual(timeparse.parse('5 day', as_timedelta=True), relativedelta(days=5)) self.assertEqual(timeparse.parse('+5 day', as_timedelta=True), relativedelta(days=5)) self.assertEqual(timeparse.parse('-5 day', as_timedelta=True), -relativedelta(days=5)) def test_timeparse_30(self): """timeparse test case 30.""" self.assertEqual(timeparse.parse('5 days', as_timedelta=True), relativedelta(days=5)) self.assertEqual(timeparse.parse('+5 days', as_timedelta=True), relativedelta(days=5)) self.assertEqual(timeparse.parse('-5 days', as_timedelta=True), -relativedelta(days=5)) def test_timeparse_31(self): """timeparse test case 31.""" self.assertEqual(timeparse.parse('5.6 wk', as_timedelta=True), relativedelta(days=39, hours=4, minutes=48)) self.assertEqual(timeparse.parse('+5.6 wk', as_timedelta=True), relativedelta(days=39, hours=4, minutes=48)) self.assertEqual(timeparse.parse('-5.6 wk', as_timedelta=True), -relativedelta(days=39, hours=4, minutes=48)) def test_timeparse_32(self): """timeparse test case 32.""" self.assertEqual(timeparse.parse('5.6 week', as_timedelta=True), relativedelta(days=39, hours=4, minutes=48)) self.assertEqual(timeparse.parse('+5.6 week', as_timedelta=True), relativedelta(days=39, hours=4, minutes=48)) self.assertEqual(timeparse.parse('-5.6 week', as_timedelta=True), -relativedelta(days=39, hours=4, minutes=48)) def test_timeparse_33(self): """timeparse test case 33.""" self.assertEqual(timeparse.parse('5.6 weeks', as_timedelta=True), relativedelta(days=39, hours=4, minutes=48)) self.assertEqual(timeparse.parse('+5.6 weeks', as_timedelta=True), relativedelta(days=39, hours=4, minutes=48)) self.assertEqual(timeparse.parse('-5.6 weeks', as_timedelta=True), -relativedelta(days=39, hours=4, minutes=48)) def test_milliseconds(self): self.assertEqual(timeparse.parse('3 ms', as_timedelta=True), relativedelta(microseconds=3000)) self.assertEqual(timeparse.parse('3 millis', as_timedelta=True), relativedelta(microseconds=3000)) self.assertEqual(timeparse.parse('3 msecs', as_timedelta=True), relativedelta(microseconds=3000)) self.assertEqual(timeparse.parse('3 milliseconds', as_timedelta=True), relativedelta(microseconds=3000)) def test_plain_numbers(self): self.assertEqual(timeparse.parse('10', as_timedelta=True), relativedelta(seconds=10)) self.assertEqual(timeparse.parse('10.1', as_timedelta=True), relativedelta(seconds=10, microseconds=100000)) self.assertEqual(timeparse.parse('-10', as_timedelta=True), -relativedelta(seconds=10)) self.assertEqual(timeparse.parse('-10.1', as_timedelta=True), -relativedelta(seconds=10, microseconds=100000)) def test_combined(self): self.assertEqual(timeparse.parse('1y2mo3w4d5h6m7s8ms', as_timedelta=True), relativedelta(years=1, months=2, weeks=3, days=4, hours=5, minutes=6, seconds=7, microseconds=8000)) class MiscTests(unittest.TestCase): """ Miscellaneous unit tests for the `timeparse` module. """ def test_strange(self): self.assertIsNone(timeparse.parse('1.1.1:22')) def test_doctest(self): """Run timeparse doctests.""" self.assertTrue(doctest.testmod(timeparse, raise_on_error=True)) def test_disable_dateutil(self): self.assertNotIsInstance(timeparse.parse('10:10', as_timedelta=True), datetime.timedelta) timeparse.disable_dateutil() self.assertIsInstance(timeparse.parse('10:10', as_timedelta=True), datetime.timedelta) timeparse.enable_dateutil() self.assertNotIsInstance(timeparse.parse('10:10', as_timedelta=True), datetime.timedelta) if __name__ == '__main__': unittest.main('tests') 0707010000000E000081A4000000000000000000000001645D608F000006CC000000000000000000000000000000000000001B00000000pytimeparse2-1.7.1/tox.ini[tox] envlist = flake,mypy,py36-coverage,py3{7,8,9,10,11}-install skipsdist = True [gh-actions] python = 3.6: flake,mypy,py36-coverage 3.7: py37-install 3.8: py38-install 3.9: py39-install 3.10: py310-install 3.11: py311-install [testenv] setenv = CCACHE_DIR = {envdir}/.ccache passenv = CC allowlist_externals = rm ls ln bash pwd cd find xargs commands = pwd pip uninstall pytimeparse2 -y install: rm -rfv {envdir}/dist/ install: python {toxinidir}/setup.py bdist_wheel --dist-dir {envdir}/dist/ install: bash -c "pip install -U {envdir}/dist/$(ls {envdir}/dist)[dateutil]" coverage: python setup.py install_egg_info coverage: pip install -U -e .[dateutil] install: bash -c "cd {envdir} && python {toxinidir}/tests.py -vv --failfast" coverage: coverage debug sys coverage: coverage erase coverage: coverage run tests.py -vv --failfast {posargs} coverage: coverage combine coverage: coverage report rm -rf .eggs build pytimeparse2.egg-info {envdir}/dist install: pip uninstall pytimeparse2 -y deps = coverage: coverage~=5.1 mock==3.0.5 [testenv:flake] basepython = python3.6 deps = flake8 commands = flake8 --config=.pep8 pytimeparse2.py [testenv:mypy] basepython = python3.6 deps = mypy types-python-dateutil commands = mypy pytimeparse2.py [testenv:contrib] basepython = python3.6 skipsdist = True envdir = {toxinidir}/venv passenv = * allowlist_externals = * commands = python setup.py install_egg_info pip install -U -e . deps = tox [testenv:build] passenv = * changedir = . allowlist_externals = tox rm commands = rm -rf dist build tox -c tox_build.ini --workdir {toxworkdir} deps = 0707010000000F000081A4000000000000000000000001645D608F00000121000000000000000000000000000000000000002100000000pytimeparse2-1.7.1/tox_build.ini[tox] envlist = py36-{wheel,build} skipsdist = True [testenv] passenv = * changedir = . whitelist_externals = rm ls grep bash commands = rm -rf build build: python setup.py compile -v wheel: python setup.py bdist_wheel -v deps = wheel==0.31.1 setuptools>=40.6.3 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!151 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor