-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
3.1.0: pytest coverage of 100.0% not reached #29
Comments
I don't see how or why... that code and those tests haven't even been touched the past 6 months. And the automated tests are working without issue: https://github.com/WoLpH/python-utils/runs/4819234204?check_suite_focus=true |
Actually, looking at the output from the automated tests and your tests I can see at least 1 issue. It seems your tests are not running the tests in Github actions tests:
|
The tests paths are configured in pytest.ini, do you have any idea why it's not reading that? https://github.com/WoLpH/python-utils/blob/c70f3b8b05686e84bc191995b7cce44b99f53c42/pytest.ini#L2-L4 |
I have no idea 🤔 + /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/python-utils-3.1.0, configfile: pytest.ini
plugins: hypothesis-6.35.0, cov-3.0.0, flake8-1.0.7, mypy-0.8.1
collected 53 items
setup.py FF [ 3%]
_python_utils_tests/__init__.py . [ 5%]
_python_utils_tests/test_import.py ....... [ 18%]
_python_utils_tests/test_python_utils.py .. [ 22%]
_python_utils_tests/test_time.py .ssss..... [ 41%]
docs/conf.py . [ 43%]
python_utils/__init__.py . [ 45%]
python_utils/__about__.py . [ 47%]
python_utils/aio.py . [ 49%]
python_utils/compat.py . [ 50%]
python_utils/containers.py ... [ 56%]
python_utils/converters.py ....... [ 69%]
python_utils/decorators.py ... [ 75%]
python_utils/formatters.py ... [ 81%]
python_utils/import_.py . [ 83%]
python_utils/logger.py .. [ 86%]
python_utils/terminal.py . [ 88%]
python_utils/time.py ..... [ 98%]
python_utils/types.py . [100%]
================================================================================= FAILURES =================================================================================
_________________________________________________________________________________ setup.py _________________________________________________________________________________
4: error: Skipping analyzing "setuptools": module is installed, but missing library stubs or py.typed marker
4: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
_______________________________________________________________________________ test session _______________________________________________________________________________
mypy exited with status 1.
============================================================================= warnings summary =============================================================================
_python_utils_tests/test_time.py:18
/home/tkloczko/rpmbuild/BUILD/python-utils-3.1.0/_python_utils_tests/test_time.py:18: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
@pytest.mark.asyncio
_python_utils_tests/test_time.py::test_aio_timeout_generator[0.1-0.06-0.5-0.1-acount-2]
_python_utils_tests/test_time.py::test_aio_timeout_generator[0.2-0.06-0.5-0.1-acount-4]
_python_utils_tests/test_time.py::test_aio_timeout_generator[0.3-0.06-1.0-None-acount-5]
_python_utils_tests/test_time.py::test_aio_timeout_generator[timeout3-interval3-2.0-maximum_interval3-acount-2]
/usr/lib/python3.8/site-packages/_pytest/python.py:172: PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped.
You need to install a suitable plugin for your async framework, for example:
- anyio
- pytest-asyncio
- pytest-tornasync
- pytest-trio
- pytest-twisted
warnings.warn(PytestUnhandledCoroutineWarning(msg.format(nodeid)))
-- Docs: https://docs.pytest.org/en/stable/warnings.html
---------- coverage: platform linux, python 3.8.12-final-0 -----------
Name Stmts Miss Branch BrPart Cover Missing
------------------------------------------------------------------------
python_utils/__about__.py 6 0 0 0 100%
python_utils/__init__.py 28 0 0 0 100%
python_utils/aio.py 6 3 2 0 62% 7-9
python_utils/compat.py 0 0 0 0 100%
python_utils/containers.py 55 0 28 0 100%
python_utils/converters.py 82 0 44 0 100%
python_utils/decorators.py 18 0 4 0 100%
python_utils/formatters.py 30 0 20 0 100%
python_utils/import_.py 34 0 22 0 100%
python_utils/logger.py 36 0 4 0 100%
python_utils/terminal.py 3 0 0 0 100%
python_utils/time.py 74 15 32 0 82% 200-222
python_utils/types.py 13 0 0 0 100%
------------------------------------------------------------------------
TOTAL 385 18 156 0 96%
Coverage HTML written to dir htmlcov
FAIL Required test coverage of 100.0% not reached. Total coverage: 95.93%
=================================================================================== mypy ===================================================================================
Found 1 error in 1 file (checked 19 source files)
========================================================================= short test summary info ==========================================================================
SKIPPED [4] ../../../../../usr/lib/python3.8/site-packages/_pytest/python.py:173: async def function and no async plugin installed (see warnings)
FAILED setup.py::mypy
FAILED setup.py::mypy-status
====================================================== 2 failed, 47 passed, 4 skipped, 5 warnings in 62.24s (0:01:02) ======================================================
+ /usr/bin/pytest -ra python_utils --no-cov
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/python-utils-3.1.0, configfile: pytest.ini
plugins: hypothesis-6.35.0, cov-3.0.0, flake8-1.0.7, mypy-0.8.1
collected 31 items
python_utils/__init__.py .. [ 6%]
python_utils/__about__.py . [ 9%]
python_utils/aio.py . [ 12%]
python_utils/compat.py . [ 16%]
python_utils/containers.py ... [ 25%]
python_utils/converters.py ....... [ 48%]
python_utils/decorators.py ... [ 58%]
python_utils/formatters.py ... [ 67%]
python_utils/import_.py . [ 70%]
python_utils/logger.py .. [ 77%]
python_utils/terminal.py . [ 80%]
python_utils/time.py ..... [ 96%]
python_utils/types.py . [100%]
=================================================================================== mypy ===================================================================================
Success: no issues found in 13 source files
=========================================================================== 31 passed in 11.20s ============================================================================ |
The setuptools warning and the asyncio warnings indicate missing requirements. These are part of the I think it should run fine once those are installed |
pytest output after add =========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/python-utils-3.1.0, configfile: pytest.ini
plugins: hypothesis-6.35.0, cov-3.0.0, flake8-1.0.7, mypy-0.8.1, asyncio-0.17.0
collected 31 items
python_utils/__init__.py .. [ 6%]
python_utils/__about__.py . [ 9%]
python_utils/aio.py . [ 12%]
python_utils/compat.py . [ 16%]
python_utils/containers.py ... [ 25%]
python_utils/converters.py ....... [ 48%]
python_utils/decorators.py ... [ 58%]
python_utils/formatters.py ... [ 67%]
python_utils/import_.py . [ 70%]
python_utils/logger.py .. [ 77%]
python_utils/terminal.py . [ 80%]
python_utils/time.py ..... [ 96%]
python_utils/types.py . [100%]
============================================================================= warnings summary =============================================================================
../../../../../usr/lib/python3.8/site-packages/pytest_asyncio/plugin.py:112
/usr/lib/python3.8/site-packages/pytest_asyncio/plugin.py:112: DeprecationWarning: The 'asyncio_mode' default value will change to 'strict' in future, please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' in pytest configuration file.
config.issue_config_time_warning(LEGACY_MODE, stacklevel=2)
-- Docs: https://docs.pytest.org/en/stable/warnings.html
=================================================================================== mypy ===================================================================================
Success: no issues found in 13 source files
====================================================================== 31 passed, 1 warning in 11.15s ====================================================================== So looks OK now however still is one pytest warning. |
Nevertheless after remove + /usr/bin/pytest -ra python_utils
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/python-utils-3.1.0, configfile: pytest.ini
plugins: hypothesis-6.35.0, cov-3.0.0, flake8-1.0.7, mypy-0.8.1, asyncio-0.17.0
collected 31 items
python_utils/__init__.py .. [ 6%]
python_utils/__about__.py . [ 9%]
python_utils/aio.py . [ 12%]
python_utils/compat.py . [ 16%]
python_utils/containers.py ... [ 25%]
python_utils/converters.py ....... [ 48%]
python_utils/decorators.py ... [ 58%]
python_utils/formatters.py ... [ 67%]
python_utils/import_.py . [ 70%]
python_utils/logger.py .. [ 77%]
python_utils/terminal.py . [ 80%]
python_utils/time.py ..... [ 96%]
python_utils/types.py . [100%]
============================================================================= warnings summary =============================================================================
../../../../../usr/lib/python3.8/site-packages/pytest_asyncio/plugin.py:112
/usr/lib/python3.8/site-packages/pytest_asyncio/plugin.py:112: DeprecationWarning: The 'asyncio_mode' default value will change to 'strict' in future, please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' in pytest configuration file.
config.issue_config_time_warning(LEGACY_MODE, stacklevel=2)
-- Docs: https://docs.pytest.org/en/stable/warnings.html
---------- coverage: platform linux, python 3.8.12-final-0 -----------
Name Stmts Miss Branch BrPart Cover Missing
------------------------------------------------------------------------
python_utils/__about__.py 6 0 0 0 100%
python_utils/__init__.py 28 0 0 0 100%
python_utils/aio.py 6 3 2 0 62% 7-9
python_utils/compat.py 0 0 0 0 100%
python_utils/containers.py 55 0 28 0 100%
python_utils/converters.py 82 0 44 0 100%
python_utils/decorators.py 18 0 4 0 100%
python_utils/formatters.py 30 0 20 0 100%
python_utils/import_.py 34 30 22 0 11% 31-85
python_utils/logger.py 36 0 4 0 100%
python_utils/terminal.py 3 0 0 0 100%
python_utils/time.py 74 17 32 2 78% 175, 200-222, 253
python_utils/types.py 13 0 0 0 100%
------------------------------------------------------------------------
TOTAL 385 50 156 2 86%
Coverage HTML written to dir htmlcov
FAIL Required test coverage of 100.0% not reached. Total coverage: 85.95%
=================================================================================== mypy ===================================================================================
Success: no issues found in 13 source files
====================================================================== 31 passed, 1 warning in 16.12s ====================================================================== |
Did you see my previous message about installing the extra tests packages? It looks like those might be missing. |
Yes however I've lost somehow
Looking one more time on that list I still don't have packaged |
Looks like latest pytest is failing + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-utils-3.1.0-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-utils-3.1.0-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra python_utils
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.13, pytest-7.1.2, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/python-utils-3.1.0, configfile: pytest.ini
plugins: mypy-0.9.1, flake8-1.1.1, asyncio-0.18.2
asyncio: mode=legacy
collected 31 items
python_utils/__init__.py .F [ 6%]
python_utils/__about__.py . [ 9%]
python_utils/aio.py . [ 12%]
python_utils/compat.py . [ 16%]
python_utils/containers.py F.. [ 25%]
python_utils/converters.py ....... [ 48%]
python_utils/decorators.py ... [ 58%]
python_utils/formatters.py ... [ 67%]
python_utils/import_.py . [ 70%]
python_utils/logger.py .. [ 77%]
python_utils/terminal.py . [ 80%]
python_utils/time.py ..... [ 96%]
python_utils/types.py . [100%]
================================================================================= FAILURES =================================================================================
_______________________________________________________________________________ test session _______________________________________________________________________________
mypy exited with status 1.
________________________________________________________________________ python_utils/containers.py ________________________________________________________________________
37: error: Signature of "update" incompatible with supertype "MutableMapping"
37: note: Superclass:
37: note: @overload
37: note: def update(self, SupportsKeysAndGetItem[KT, VT], **kwargs: VT) -> None
37: note: @overload
37: note: def update(self, Iterable[Tuple[KT, VT]], **kwargs: VT) -> None
37: note: @overload
37: note: def update(self, **kwargs: VT) -> None
37: note: Subclass:
37: note: def update(self, *args: Union[Mapping[Any, Any], Iterable[Union[Tuple[Any, Any], Mapping[Any, Any]]]], **kwargs: Any) -> None
============================================================================= warnings summary =============================================================================
../../../../../usr/lib/python3.8/site-packages/pytest_asyncio/plugin.py:191
/usr/lib/python3.8/site-packages/pytest_asyncio/plugin.py:191: DeprecationWarning: The 'asyncio_mode' default value will change to 'strict' in future, please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' in pytest configuration file.
config.issue_config_time_warning(LEGACY_MODE, stacklevel=2)
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=================================================================================== mypy ===================================================================================
Found 1 error in 1 file (checked 13 source files)
========================================================================= short test summary info ==========================================================================
FAILED python_utils/__init__.py::mypy-status
FAILED python_utils/containers.py::mypy
================================================================= 2 failed, 29 passed, 1 warning in 7.21s ==================================================================
|
Thank you for letting me know :) I've fixed all the issues and enabled nit-picky mode by default for the documentation tests |
Just tested new version and generally test suite look better now. + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-utils-3.3.0-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-utils-3.3.0-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.13, pytest-7.1.2, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0, configfile: pytest.ini
plugins: mypy-0.9.1, asyncio-0.18.2
asyncio: mode=strict
collected 71 items
setup.py FF [ 2%]
_python_utils_tests/__init__.py . [ 4%]
_python_utils_tests/test_decorators.py ... [ 8%]
_python_utils_tests/test_generators.py .... [ 14%]
_python_utils_tests/test_import.py ....... [ 23%]
_python_utils_tests/test_logger.py .. [ 26%]
_python_utils_tests/test_python_utils.py .. [ 29%]
_python_utils_tests/test_time.py ............ [ 46%]
docs/conf.py . [ 47%]
python_utils/__init__.py . [ 49%]
python_utils/__about__.py . [ 50%]
python_utils/aio.py . [ 52%]
python_utils/compat.py . [ 53%]
python_utils/containers.py ... [ 57%]
python_utils/converters.py ....... [ 67%]
python_utils/decorators.py .... [ 73%]
python_utils/exceptions.py .. [ 76%]
python_utils/formatters.py .... [ 81%]
python_utils/generators.py . [ 83%]
python_utils/import_.py . [ 84%]
python_utils/logger.py ... [ 88%]
python_utils/loguru.py . [ 90%]
python_utils/terminal.py . [ 91%]
python_utils/time.py ..... [ 98%]
python_utils/types.py . [100%]
================================================================================= FAILURES =================================================================================
_________________________________________________________________________________ setup.py _________________________________________________________________________________
4: error: Skipping analyzing "setuptools": module is installed, but missing library stubs or py.typed marker
4: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
_______________________________________________________________________________ test session _______________________________________________________________________________
mypy exited with status 1.
============================================================================= warnings summary =============================================================================
../../../../../usr/lib/python3.8/site-packages/_pytest/config/__init__.py:1252
/usr/lib/python3.8/site-packages/_pytest/config/__init__.py:1252: PytestConfigWarning: Unknown config option: flake8-ignore
self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=================================================================================== mypy ===================================================================================
Found 1 error in 1 file (checked 25 source files)
========================================================================= short test summary info ==========================================================================
FAILED setup.py::mypy
FAILED setup.py::mypy-status
================================================================= 2 failed, 69 passed, 1 warning in 37.77s ================================================================= I'm not sure how to do that but IMO it would be good to make |
Also I've manually tested pytest output with + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-utils-3.3.0-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-utils-3.3.0-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra --black
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.13, pytest-7.1.2, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0, configfile: pytest.ini
plugins: mypy-0.9.1, asyncio-0.18.2, black-0.3.12
asyncio: mode=strict
collected 96 items
setup.py FFF [ 3%]
_python_utils_tests/__init__.py .. [ 5%]
_python_utils_tests/test_decorators.py F... [ 9%]
_python_utils_tests/test_generators.py F.... [ 14%]
_python_utils_tests/test_import.py F....... [ 22%]
_python_utils_tests/test_logger.py F.. [ 26%]
_python_utils_tests/test_python_utils.py F.. [ 29%]
_python_utils_tests/test_time.py F............ [ 42%]
docs/conf.py F. [ 44%]
python_utils/__init__.py F. [ 46%]
python_utils/__about__.py F. [ 48%]
python_utils/aio.py F. [ 51%]
python_utils/compat.py .. [ 53%]
python_utils/containers.py F... [ 57%]
python_utils/converters.py F....... [ 65%]
python_utils/decorators.py F.... [ 70%]
python_utils/exceptions.py F.. [ 73%]
python_utils/formatters.py F.... [ 79%]
python_utils/generators.py F. [ 81%]
python_utils/import_.py F. [ 83%]
python_utils/logger.py F... [ 87%]
python_utils/loguru.py F. [ 89%]
python_utils/terminal.py F. [ 91%]
python_utils/time.py F..... [ 97%]
python_utils/types.py F. [100%]
================================================================================= FAILURES =================================================================================
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/setup.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/setup.py 2022-05-29 04:46:43.153873 +0000
@@ -4,50 +4,51 @@
import setuptools
# To prevent importing about and thereby breaking the coverage info we use this
# exec hack
about: typing.Dict[str, str] = {}
-with open('python_utils/__about__.py') as fp:
+with open("python_utils/__about__.py") as fp:
exec(fp.read(), about)
-if os.path.isfile('README.rst'):
- long_description = open('README.rst').read()
+if os.path.isfile("README.rst"):
+ long_description = open("README.rst").read()
else:
- long_description = 'See http://pypi.python.org/pypi/python-utils/'
+ long_description = "See http://pypi.python.org/pypi/python-utils/"
-if __name__ == '__main__':
+if __name__ == "__main__":
setuptools.setup(
- python_requires='>3.6.0',
- name='python-utils',
- version=about['__version__'],
- author=about['__author__'],
- author_email=about['__author_email__'],
- description=about['__description__'],
- url=about['__url__'],
- license='BSD',
- packages=setuptools.find_packages(exclude=[
- '_python_utils_tests', '*.__pycache__']),
+ python_requires=">3.6.0",
+ name="python-utils",
+ version=about["__version__"],
+ author=about["__author__"],
+ author_email=about["__author_email__"],
+ description=about["__description__"],
+ url=about["__url__"],
+ license="BSD",
+ packages=setuptools.find_packages(
+ exclude=["_python_utils_tests", "*.__pycache__"]
+ ),
long_description=long_description,
- tests_require=['pytest'],
+ tests_require=["pytest"],
extras_require={
- 'loguru': [
- 'loguru',
+ "loguru": [
+ "loguru",
],
- 'docs': [
- 'mock',
- 'sphinx',
- 'python-utils',
+ "docs": [
+ "mock",
+ "sphinx",
+ "python-utils",
],
- 'tests': [
- 'flake8',
- 'pytest',
- 'pytest-cov',
- 'pytest-mypy',
- 'pytest-flake8',
- 'pytest-asyncio',
- 'sphinx',
- 'types-setuptools',
- 'loguru',
+ "tests": [
+ "flake8",
+ "pytest",
+ "pytest-cov",
+ "pytest-mypy",
+ "pytest-flake8",
+ "pytest-asyncio",
+ "sphinx",
+ "types-setuptools",
+ "loguru",
],
},
- classifiers=['License :: OSI Approved :: BSD License'],
+ classifiers=["License :: OSI Approved :: BSD License"],
)
_________________________________________________________________________________ setup.py _________________________________________________________________________________
4: error: Skipping analyzing "setuptools": module is installed, but missing library stubs or py.typed marker
4: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
_______________________________________________________________________________ test session _______________________________________________________________________________
mypy exited with status 1.
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_decorators.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_decorators.py 2022-05-29 04:47:17.147670 +0000
@@ -12,11 +12,11 @@
return mock
def test_sample_called(random):
demo_function = MagicMock()
- decorated = sample(0.5)(demo_function)
+ decorated = sample(0.5)(demo_function)
random.return_value = 0.4
decorated()
random.return_value = 0.0
decorated()
args = [1, 2]
@@ -31,6 +31,6 @@
decorated = sample(0.5)(demo_function)
random.return_value = 0.5
decorated()
random.return_value = 1.0
decorated()
- assert demo_function.call_count == 0
\ No newline at end of file
+ assert demo_function.call_count == 0
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_generators.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_generators.py 2022-05-29 04:47:17.379777 +0000
@@ -14,12 +14,11 @@
@pytest.mark.asyncio
async def test_abatcher_timed():
batches = []
async for batch in python_utils.abatcher(
- python_utils.acount(stop=10, delay=0.08),
- interval=0.2
+ python_utils.acount(stop=10, delay=0.08), interval=0.2
):
batches.append(batch)
assert len(batches) == 3
assert sum(len(batch) for batch in batches) == 10
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_import.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_import.py 2022-05-29 04:47:18.439799 +0000
@@ -6,43 +6,44 @@
relative_import(i)
def relative_import(level):
locals_ = {}
- globals_ = {'__name__': 'python_utils.import_'}
- import_.import_global('.formatters', locals_=locals_, globals_=globals_)
- assert 'camel_to_underscore' in globals_
+ globals_ = {"__name__": "python_utils.import_"}
+ import_.import_global(".formatters", locals_=locals_, globals_=globals_)
+ assert "camel_to_underscore" in globals_
def test_import_globals_without_inspection():
locals_ = {}
- globals_ = {'__name__': __name__}
- import_.import_global(
- 'python_utils.formatters', locals_=locals_, globals_=globals_)
- assert 'camel_to_underscore' in globals_
+ globals_ = {"__name__": __name__}
+ import_.import_global("python_utils.formatters", locals_=locals_, globals_=globals_)
+ assert "camel_to_underscore" in globals_
def test_import_globals_single_method():
locals_ = {}
- globals_ = {'__name__': __name__}
+ globals_ = {"__name__": __name__}
import_.import_global(
- 'python_utils.formatters', ['camel_to_underscore'], locals_=locals_,
- globals_=globals_)
- assert 'camel_to_underscore' in globals_
+ "python_utils.formatters",
+ ["camel_to_underscore"],
+ locals_=locals_,
+ globals_=globals_,
+ )
+ assert "camel_to_underscore" in globals_
def test_import_globals_with_inspection():
- import_.import_global('python_utils.formatters')
- assert 'camel_to_underscore' in globals()
+ import_.import_global("python_utils.formatters")
+ assert "camel_to_underscore" in globals()
def test_import_globals_missing_module():
- import_.import_global(
- 'python_utils.spam', exceptions=ImportError, locals_=locals())
- assert 'camel_to_underscore' in globals()
+ import_.import_global("python_utils.spam", exceptions=ImportError, locals_=locals())
+ assert "camel_to_underscore" in globals()
def test_import_locals_missing_module():
import_.import_global(
- 'python_utils.spam', exceptions=ImportError, globals_=globals())
- assert 'camel_to_underscore' in globals()
-
+ "python_utils.spam", exceptions=ImportError, globals_=globals()
+ )
+ assert "camel_to_underscore" in globals()
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_logger.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_logger.py 2022-05-29 04:47:18.686776 +0000
@@ -1,19 +1,19 @@
import pytest
from python_utils.loguru import Logurud
-loguru = pytest.importorskip('loguru')
+loguru = pytest.importorskip("loguru")
def test_logurud():
class MyClass(Logurud):
pass
my_class = MyClass()
- my_class.debug('debug')
- my_class.info('info')
- my_class.warning('warning')
- my_class.error('error')
- my_class.exception('exception')
- my_class.log(0, 'log')
+ my_class.debug("debug")
+ my_class.info("info")
+ my_class.warning("warning")
+ my_class.error("error")
+ my_class.exception("exception")
+ my_class.log(0, "log")
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_python_utils.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_python_utils.py 2022-05-29 04:47:18.886611 +0000
@@ -5,6 +5,5 @@
# The setup.py requires this so we better make sure they exist :)
assert __about__.__version__
assert __about__.__author__
assert __about__.__author_email__
assert __about__.__description__
-
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_time.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/_python_utils_tests/test_time.py 2022-05-29 04:47:19.226729 +0000
@@ -6,43 +6,58 @@
import python_utils
@pytest.mark.parametrize(
- 'timeout,interval,interval_multiplier,maximum_interval,iterable,result', [
+ "timeout,interval,interval_multiplier,maximum_interval,iterable,result",
+ [
(0.2, 0.1, 0.4, 0.2, python_utils.acount, 2),
(0.3, 0.1, 0.4, 0.2, python_utils.acount(), 3),
(0.3, 0.06, 1.0, None, python_utils.acount, 5),
- (timedelta(seconds=0.1), timedelta(seconds=0.06),
- 2.0, timedelta(seconds=0.1), python_utils.acount, 2),
- ])
+ (
+ timedelta(seconds=0.1),
+ timedelta(seconds=0.06),
+ 2.0,
+ timedelta(seconds=0.1),
+ python_utils.acount,
+ 2,
+ ),
+ ],
+)
@pytest.mark.asyncio
-async def test_aio_timeout_generator(timeout, interval, interval_multiplier,
- maximum_interval, iterable, result):
+async def test_aio_timeout_generator(
+ timeout, interval, interval_multiplier, maximum_interval, iterable, result
+):
i = None
async for i in python_utils.aio_timeout_generator(
- timeout, interval, iterable,
- maximum_interval=maximum_interval
+ timeout, interval, iterable, maximum_interval=maximum_interval
):
pass
assert i == result
@pytest.mark.parametrize(
- 'timeout,interval,interval_multiplier,maximum_interval,iterable,result', [
- (0.01, 0.006, 0.5, 0.01, 'abc', 'c'),
+ "timeout,interval,interval_multiplier,maximum_interval,iterable,result",
+ [
+ (0.01, 0.006, 0.5, 0.01, "abc", "c"),
(0.01, 0.006, 0.5, 0.01, itertools.count, 2),
(0.01, 0.006, 0.5, 0.01, itertools.count(), 2),
- (0.01, 0.006, 1.0, None, 'abc', 'c'),
- (timedelta(seconds=0.01),
- timedelta(seconds=0.006),
- 2.0, timedelta(seconds=0.01),
- itertools.count, 2),
- ])
-def test_timeout_generator(timeout, interval, interval_multiplier,
- maximum_interval, iterable, result):
+ (0.01, 0.006, 1.0, None, "abc", "c"),
+ (
+ timedelta(seconds=0.01),
+ timedelta(seconds=0.006),
+ 2.0,
+ timedelta(seconds=0.01),
+ itertools.count,
+ 2,
+ ),
+ ],
+)
+def test_timeout_generator(
+ timeout, interval, interval_multiplier, maximum_interval, iterable, result
+):
i = None
for i in python_utils.timeout_generator(
timeout=timeout,
interval=interval,
interval_multiplier=interval_multiplier,
@@ -102,12 +117,11 @@
async for i in generator():
pass
# Test regular timeout with clean exit
@python_utils.aio_generator_timeout_detector_decorator(
- timeout=0.05,
- on_timeout=None
+ timeout=0.05, on_timeout=None
)
async def generator():
for i in range(10):
await asyncio.sleep(i / 100.0)
yield i
@@ -128,12 +142,11 @@
async for i in generator():
pass
# Test total timeout with clean exit
@python_utils.aio_generator_timeout_detector_decorator(
- total_timeout=0.1,
- on_timeout=None
+ total_timeout=0.1, on_timeout=None
)
async def generator():
for i in range(10):
await asyncio.sleep(i / 100.0)
yield i
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/docs/conf.py 2022-05-29 04:46:35.637674 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/docs/conf.py 2022-05-29 04:47:21.984024 +0000
@@ -11,17 +11,18 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
from datetime import date
import os
import sys
-sys.path.insert(0, os.path.abspath('..'))
+
+sys.path.insert(0, os.path.abspath(".."))
from python_utils import __about__
# -- Project information -----------------------------------------------------
-project = 'Python Utils'
+project = "Python Utils"
author = __about__.__author__
copyright = f'{date.today().year}, <a href="http://wol.ph/">{author}</a>'
# The full version, including alpha/beta/rc tags
release = __about__.__version__
@@ -41,36 +42,35 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
- 'sphinx.ext.autodoc',
- 'sphinx.ext.doctest',
- 'sphinx.ext.intersphinx',
- 'sphinx.ext.todo',
- 'sphinx.ext.coverage',
- 'sphinx.ext.viewcode',
+ "sphinx.ext.autodoc",
+ "sphinx.ext.doctest",
+ "sphinx.ext.intersphinx",
+ "sphinx.ext.todo",
+ "sphinx.ext.coverage",
+ "sphinx.ext.viewcode",
]
# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'alabaster'
+html_theme = "alabaster"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
-intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
-
+intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/__init__.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/__init__.py 2022-05-29 04:47:22.216832 +0000
@@ -30,44 +30,44 @@
timedelta_to_seconds,
timeout_generator,
)
__all__ = [
- 'aio',
- 'generators',
- 'compat',
- 'converters',
- 'decorators',
- 'formatters',
- 'import_',
- 'logger',
- 'terminal',
- 'time',
- 'types',
- 'to_int',
- 'to_float',
- 'to_unicode',
- 'to_str',
- 'scale_1024',
- 'remap',
- 'set_attributes',
- 'listify',
- 'camel_to_underscore',
- 'timesince',
- 'import_global',
- 'get_terminal_size',
- 'timedelta_to_seconds',
- 'format_time',
- 'timeout_generator',
- 'acount',
- 'abatcher',
- 'batcher',
- 'aio_timeout_generator',
- 'aio_generator_timeout_detector_decorator',
- 'aio_generator_timeout_detector',
- 'delta_to_seconds',
- 'delta_to_seconds_or_none',
- 'reraise',
- 'raise_exception',
- 'Logged',
- 'LoggerBase',
+ "aio",
+ "generators",
+ "compat",
+ "converters",
+ "decorators",
+ "formatters",
+ "import_",
+ "logger",
+ "terminal",
+ "time",
+ "types",
+ "to_int",
+ "to_float",
+ "to_unicode",
+ "to_str",
+ "scale_1024",
+ "remap",
+ "set_attributes",
+ "listify",
+ "camel_to_underscore",
+ "timesince",
+ "import_global",
+ "get_terminal_size",
+ "timedelta_to_seconds",
+ "format_time",
+ "timeout_generator",
+ "acount",
+ "abatcher",
+ "batcher",
+ "aio_timeout_generator",
+ "aio_generator_timeout_detector_decorator",
+ "aio_generator_timeout_detector",
+ "delta_to_seconds",
+ "delta_to_seconds_or_none",
+ "reraise",
+ "raise_exception",
+ "Logged",
+ "LoggerBase",
]
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/__about__.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/__about__.py 2022-05-29 04:47:22.418395 +0000
@@ -1,9 +1,10 @@
-__package_name__: str = 'python-utils'
-__author__: str = 'Rick van Hattem'
-__author_email__: str = 'Wolph@wol.ph'
+__package_name__: str = "python-utils"
+__author__: str = "Rick van Hattem"
+__author_email__: str = "Wolph@wol.ph"
__description__: str = (
- 'Python Utils is a module with some convenient utilities not included '
- 'with the standard Python install')
-__url__: str = 'https://github.com/WoLpH/python-utils'
+ "Python Utils is a module with some convenient utilities not included "
+ "with the standard Python install"
+)
+__url__: str = "https://github.com/WoLpH/python-utils"
# Omit type info due to automatic versioning script
-__version__ = '3.3.0'
+__version__ = "3.3.0"
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/aio.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/aio.py 2022-05-29 04:47:22.608639 +0000
@@ -1,15 +1,15 @@
-'''
+"""
Asyncio equivalents to regular Python functions.
-'''
+"""
import asyncio
import itertools
async def acount(start=0, step=1, delay=0, stop=None):
- '''Asyncio version of itertools.count()'''
+ """Asyncio version of itertools.count()"""
for item in itertools.count(start, step): # pragma: no branch
if stop is not None and item >= stop:
break
yield item
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/containers.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/containers.py 2022-05-29 04:47:23.077700 +0000
@@ -7,44 +7,36 @@
from . import types
if typing.TYPE_CHECKING:
import _typeshed # noqa: F401
-KT = types.TypeVar('KT')
-VT = types.TypeVar('VT')
+KT = types.TypeVar("KT")
+VT = types.TypeVar("VT")
DT = types.Dict[KT, VT]
KT_cast = types.Optional[types.Callable[[Any], KT]]
VT_cast = types.Optional[types.Callable[[Any], VT]]
# Using types.Union instead of | since Python 3.7 doesn't fully support it
DictUpdateArgs = types.Union[
types.Mapping,
types.Iterable[types.Union[types.Tuple[Any, Any], types.Mapping]],
- '_typeshed.SupportsKeysAndGetItem[KT, VT]',
+ "_typeshed.SupportsKeysAndGetItem[KT, VT]",
]
class CastedDictBase(types.Dict[KT, VT], abc.ABC):
_key_cast: KT_cast
_value_cast: VT_cast
def __init__(
- self,
- key_cast: KT_cast = None,
- value_cast: VT_cast = None,
- *args,
- **kwargs
+ self, key_cast: KT_cast = None, value_cast: VT_cast = None, *args, **kwargs
) -> None:
self._value_cast = value_cast
self._key_cast = key_cast
self.update(*args, **kwargs)
- def update(
- self,
- *args: DictUpdateArgs,
- **kwargs: VT
- ) -> None:
+ def update(self, *args: DictUpdateArgs, **kwargs: VT) -> None:
if args:
kwargs.update(*args)
if kwargs:
for key, value in kwargs.items():
@@ -56,11 +48,11 @@
return super().__setitem__(key, value)
class CastedDict(CastedDictBase):
- '''
+ """
Custom dictionary that casts keys and values to the specified typing.
Note that you can specify the types for mypy and type hinting with:
CastedDict[int, int](int, int)
@@ -88,21 +80,21 @@
>>> d['3'] = '4'
>>> d.update({'5': '6'})
>>> d.update([('7', '8')])
>>> d
{1: 2, '3': '4', '5': '6', '7': '8'}
- '''
+ """
def __setitem__(self, key, value):
if self._value_cast is not None:
value = self._value_cast(value)
super().__setitem__(key, value)
class LazyCastedDict(CastedDictBase):
- '''
+ """
Custom dictionary that casts keys and lazily casts values to the specified
typing. Note that the values are cast only when they are accessed and
are not cached between executions.
Note that you can specify the types for mypy and type hinting with:
@@ -141,11 +133,11 @@
>>> list(d.items())
[(1, 2), ('3', '4'), ('5', '6'), ('7', '8')]
>>> d['3']
'4'
- '''
+ """
def __setitem__(self, key, value):
if self._key_cast is not None:
key = self._key_cast(key)
@@ -175,9 +167,9 @@
else:
for value in super().values():
yield self._value_cast(value)
-if __name__ == '__main__':
+if __name__ == "__main__":
import doctest
doctest.testmod()
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/converters.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/converters.py 2022-05-29 04:47:23.468462 +0000
@@ -5,16 +5,16 @@
from . import types
def to_int(
- input_: typing.Optional[str] = None,
- default: int = 0,
- exception: types.ExceptionsType = (ValueError, TypeError),
- regexp: types.O[types.Pattern] = None,
+ input_: typing.Optional[str] = None,
+ default: int = 0,
+ exception: types.ExceptionsType = (ValueError, TypeError),
+ regexp: types.O[types.Pattern] = None,
) -> int:
- r'''
+ r"""
Convert the given input to an integer or return default
When trying to convert the exceptions given in the exception parameter
are automatically catched and the default will be returned.
@@ -70,19 +70,19 @@
1
>>> to_int('abc', regexp=123)
Traceback (most recent call last):
...
TypeError: unknown argument for regexp parameter: 123
- '''
+ """
if regexp is True:
- regexp = re.compile(r'(\d+)')
+ regexp = re.compile(r"(\d+)")
elif isinstance(regexp, str):
regexp = re.compile(regexp)
- elif hasattr(regexp, 'search'):
+ elif hasattr(regexp, "search"):
pass
elif regexp is not None:
- raise TypeError('unknown argument for regexp parameter: %r' % regexp)
+ raise TypeError("unknown argument for regexp parameter: %r" % regexp)
try:
if regexp and input_:
match = regexp.search(input_)
if match:
@@ -95,16 +95,16 @@
except exception: # type: ignore
return default
def to_float(
- input_: str,
- default: int = 0,
- exception: types.ExceptionsType = (ValueError, TypeError),
- regexp: types.O[types.Pattern] = None,
+ input_: str,
+ default: int = 0,
+ exception: types.ExceptionsType = (ValueError, TypeError),
+ regexp: types.O[types.Pattern] = None,
) -> types.Number:
- r'''
+ r"""
Convert the given `input_` to an integer or return default
When trying to convert the exceptions given in the exception parameter
are automatically catched and the default will be returned.
@@ -150,20 +150,20 @@
'1.00'
>>> '%.2f' % to_float('abc', regexp=123)
Traceback (most recent call last):
...
TypeError: unknown argument for regexp parameter
- '''
+ """
if regexp is True:
- regexp = re.compile(r'(\d+(\.\d+|))')
+ regexp = re.compile(r"(\d+(\.\d+|))")
elif isinstance(regexp, str):
regexp = re.compile(regexp)
- elif hasattr(regexp, 'search'):
+ elif hasattr(regexp, "search"):
pass
elif regexp is not None:
- raise TypeError('unknown argument for regexp parameter')
+ raise TypeError("unknown argument for regexp parameter")
try:
if regexp:
match = regexp.search(input_)
if match:
@@ -172,15 +172,15 @@
except exception:
return default
def to_unicode(
- input_: types.StringTypes,
- encoding: str = 'utf-8',
- errors: str = 'replace',
+ input_: types.StringTypes,
+ encoding: str = "utf-8",
+ errors: str = "replace",
) -> str:
- '''Convert objects to unicode, if needed decodes string with the given
+ """Convert objects to unicode, if needed decodes string with the given
encoding and errors settings.
:rtype: str
>>> to_unicode(b'a')
@@ -192,24 +192,24 @@
>>> class Foo(object): __str__ = lambda s: u'a'
>>> to_unicode(Foo())
'a'
>>> to_unicode(Foo)
"<class 'python_utils.converters.Foo'>"
- '''
+ """
if isinstance(input_, bytes):
input_ = input_.decode(encoding, errors)
else:
input_ = str(input_)
return input_
def to_str(
- input_: types.StringTypes,
- encoding: str = 'utf-8',
- errors: str = 'replace',
+ input_: types.StringTypes,
+ encoding: str = "utf-8",
+ errors: str = "replace",
) -> bytes:
- '''Convert objects to string, encodes to the given encoding
+ """Convert objects to string, encodes to the given encoding
:rtype: str
>>> to_str('a')
b'a'
@@ -220,25 +220,26 @@
>>> class Foo(object): __str__ = lambda s: u'a'
>>> to_str(Foo())
'a'
>>> to_str(Foo)
"<class 'python_utils.converters.Foo'>"
- '''
+ """
if isinstance(input_, bytes):
pass
else:
- if not hasattr(input_, 'encode'):
+ if not hasattr(input_, "encode"):
input_ = str(input_)
input_ = input_.encode(encoding, errors)
return input_
def scale_1024(
- x: types.Number, n_prefixes: int,
+ x: types.Number,
+ n_prefixes: int,
) -> types.Tuple[types.Number, types.Number]:
- '''Scale a number down to a suitable size, based on powers of 1024.
+ """Scale a number down to a suitable size, based on powers of 1024.
Returns the scaled number and the power of 1024 used.
Use to format numbers of bytes to KiB, MiB, etc.
@@ -250,25 +251,27 @@
(0.0, 0)
>>> scale_1024(0.5, 2)
(0.5, 0)
>>> scale_1024(1, 2)
(1.0, 0)
- '''
+ """
if x <= 0:
power = 0
else:
power = min(int(math.log(x, 2) / 10), n_prefixes - 1)
scaled = float(x) / (2 ** (10 * power))
return scaled, power
def remap(
- value: types.DecimalNumber,
- old_min: types.DecimalNumber, old_max: types.DecimalNumber,
- new_min: types.DecimalNumber, new_max: types.DecimalNumber,
+ value: types.DecimalNumber,
+ old_min: types.DecimalNumber,
+ old_max: types.DecimalNumber,
+ new_min: types.DecimalNumber,
+ new_max: types.DecimalNumber,
) -> types.DecimalNumber:
- '''
+ """
remap a value from one range into another.
>>> remap(500, 0, 1000, 0, 100)
50
>>> remap(250.0, 0.0, 1000.0, 0.0, 100.0)
@@ -335,26 +338,26 @@
of any of the passed parameters ar `decimal.Decimal`, the return type
will be `float` if any of the passed parameters are a `float` otherwise
the returned type will be `int`.
:rtype: int, float, decimal.Decimal
- '''
+ """
type_: types.Type[types.DecimalNumber]
if (
- isinstance(value, decimal.Decimal) or
- isinstance(old_min, decimal.Decimal) or
- isinstance(old_max, decimal.Decimal) or
- isinstance(new_min, decimal.Decimal) or
- isinstance(new_max, decimal.Decimal)
+ isinstance(value, decimal.Decimal)
+ or isinstance(old_min, decimal.Decimal)
+ or isinstance(old_max, decimal.Decimal)
+ or isinstance(new_min, decimal.Decimal)
+ or isinstance(new_max, decimal.Decimal)
):
type_ = decimal.Decimal
elif (
- isinstance(value, float) or
- isinstance(old_min, float) or
- isinstance(old_max, float) or
- isinstance(new_min, float) or
- isinstance(new_max, float)
+ isinstance(value, float)
+ or isinstance(old_min, float)
+ or isinstance(old_max, float)
+ or isinstance(new_min, float)
+ or isinstance(new_max, float)
):
type_ = float
else:
type_ = int
@@ -367,16 +370,14 @@
old_range = old_max - old_min # type: ignore
new_range = new_max - new_min # type: ignore
if old_range == 0:
- raise ValueError('Input range ({}-{}) is empty'.format(
- old_min, old_max))
+ raise ValueError("Input range ({}-{}) is empty".format(old_min, old_max))
if new_range == 0:
- raise ValueError('Output range ({}-{}) is empty'.format(
- new_min, new_max))
+ raise ValueError("Output range ({}-{}) is empty".format(new_min, new_max))
new_value = (value - old_min) * new_range # type: ignore
if type_ == int:
new_value //= old_range # type: ignore
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/decorators.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/decorators.py 2022-05-29 04:47:23.725721 +0000
@@ -3,11 +3,11 @@
import random
from . import types
def set_attributes(**kwargs):
- '''Decorator to set attributes on functions and classes
+ """Decorator to set attributes on functions and classes
A common usage for this pattern is the Django Admin where
functions can get an optional short_description. To illustrate:
Example from the Django admin using this decorator:
@@ -24,22 +24,22 @@
>>> def upper_case_name(obj):
... return ("%s %s" % (obj.first_name, obj.last_name)).upper()
>>> upper_case_name.short_description = 'Name'
- '''
+ """
def _set_attributes(function):
for key, value in kwargs.items():
setattr(function, key, value)
return function
return _set_attributes
def listify(collection: types.Callable = list, allow_empty: bool = True):
- '''
+ """
Convert any generator to a list or other type of collection.
>>> @listify()
... def generator():
... yield 1
@@ -79,11 +79,11 @@
... yield 'a', 1
... yield 'b', 2
>>> dict_generator()
{'a': 1, 'b': 2}
- '''
+ """
def _listify(function):
@functools.wraps(function)
def __listify(*args, **kwargs):
result = function(*args, **kwargs)
@@ -95,11 +95,11 @@
return _listify
def sample(sample_rate: float):
- '''
+ """
Limit calls to a function based on given sample rate.
Number of calls to the function will be roughly equal to
sample_rate percentage.
Usage:
@@ -108,16 +108,23 @@
... def demo_function(*args, **kwargs):
... return 1
Calls to *demo_function* will be limited to 50% approximatly.
- '''
+ """
+
def _sample(function):
@functools.wraps(function)
def __sample(*args, **kwargs):
if random.random() < sample_rate:
return function(*args, **kwargs)
else:
- logging.debug('Skipped execution of %r(%r, %r) due to sampling', function, args, kwargs) # noqa: E501
+ logging.debug(
+ "Skipped execution of %r(%r, %r) due to sampling",
+ function,
+ args,
+ kwargs,
+ ) # noqa: E501
return __sample
+
return _sample
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/exceptions.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/exceptions.py 2022-05-29 04:47:23.936041 +0000
@@ -4,19 +4,19 @@
def raise_exception(
exception_class: typing.Type[Exception],
*args: typing.Any,
**kwargs: typing.Any,
) -> typing.Callable:
- '''
+ """
Returns a function that raises an exception of the given type with the
given arguments.
>>> raise_exception(ValueError, 'spam')('eggs')
Traceback (most recent call last):
...
ValueError: spam
- '''
+ """
def raise_(*args_: typing.Any, **kwargs_: typing.Any) -> typing.Any:
raise exception_class(*args, **kwargs)
return raise_
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/formatters.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/formatters.py 2022-05-29 04:47:24.224922 +0000
@@ -2,11 +2,11 @@
from python_utils import types
def camel_to_underscore(name: str) -> str:
- '''Convert camel case style naming to underscore/snake case style naming
+ """Convert camel case style naming to underscore/snake case style naming
If there are existing underscores they will be collapsed with the
to-be-added underscores. Multiple consecutive capital letters will not be
split except for the last one.
@@ -18,37 +18,35 @@
'spam_and_bacon'
>>> camel_to_underscore('__SpamAndBacon__')
'__spam_and_bacon__'
>>> camel_to_underscore('__SpamANDBacon__')
'__spam_and_bacon__'
- '''
+ """
output = []
for i, c in enumerate(name):
if i > 0:
pc = name[i - 1]
- if c.isupper() and not pc.isupper() and pc != '_':
+ if c.isupper() and not pc.isupper() and pc != "_":
# Uppercase and the previous character isn't upper/underscore?
# Add the underscore
- output.append('_')
+ output.append("_")
elif i > 3 and not c.isupper():
# Will return the last 3 letters to check if we are changing
# case
- previous = name[i - 3:i]
+ previous = name[i - 3 : i]
if previous.isalpha() and previous.isupper():
- output.insert(len(output) - 1, '_')
+ output.insert(len(output) - 1, "_")
output.append(c.lower())
- return ''.join(output)
+ return "".join(output)
def apply_recursive(
- function: types.Callable[[str], str],
- data: types.OptionalScope = None,
- **kwargs
+ function: types.Callable[[str], str], data: types.OptionalScope = None, **kwargs
) -> types.OptionalScope:
- '''
+ """
Apply a function to all keys in a scope recursively
>>> apply_recursive(camel_to_underscore, {'SpamEggsAndBacon': 'spam'})
{'spam_eggs_and_bacon': 'spam'}
>>> apply_recursive(camel_to_underscore, {'SpamEggsAndBacon': {
@@ -60,11 +58,11 @@
>>> b = apply_recursive(camel_to_underscore, a)
>>> b
{'a_b_c': 123, 'def': {'de_f': 456}}
>>> apply_recursive(camel_to_underscore, None)
- '''
+ """
if data is None:
return None
elif isinstance(data, dict):
return {
@@ -74,14 +72,13 @@
else:
return data
def timesince(
- dt: types.Union[datetime.datetime, datetime.timedelta],
- default: str = 'just now'
+ dt: types.Union[datetime.datetime, datetime.timedelta], default: str = "just now"
) -> str:
- '''
+ """
Returns string representing 'time since' e.g.
3 days ago, 5 hours ago etc.
>>> now = datetime.datetime.now()
>>> timesince(now)
@@ -118,34 +115,34 @@
'1 hour and 2 minutes ago'
>>> timesince(now - datetime.timedelta(seconds=3721))
'1 hour and 2 minutes ago'
>>> timesince(datetime.timedelta(seconds=3721))
'1 hour and 2 minutes ago'
- '''
+ """
if isinstance(dt, datetime.timedelta):
diff = dt
else:
now = datetime.datetime.now()
diff = abs(now - dt)
periods = (
- (diff.days / 365, 'year', 'years'),
- (diff.days % 365 / 30, 'month', 'months'),
- (diff.days % 30 / 7, 'week', 'weeks'),
- (diff.days % 7, 'day', 'days'),
- (diff.seconds / 3600, 'hour', 'hours'),
- (diff.seconds % 3600 / 60, 'minute', 'minutes'),
- (diff.seconds % 60, 'second', 'seconds'),
+ (diff.days / 365, "year", "years"),
+ (diff.days % 365 / 30, "month", "months"),
+ (diff.days % 30 / 7, "week", "weeks"),
+ (diff.days % 7, "day", "days"),
+ (diff.seconds / 3600, "hour", "hours"),
+ (diff.seconds % 3600 / 60, "minute", "minutes"),
+ (diff.seconds % 60, "second", "seconds"),
)
output = []
for period, singular, plural in periods:
if int(period):
if int(period) == 1:
- output.append('%d %s' % (period, singular))
+ output.append("%d %s" % (period, singular))
else:
- output.append('%d %s' % (period, plural))
+ output.append("%d %s" % (period, plural))
if output:
- return '%s ago' % ' and '.join(output[:2])
+ return "%s ago" % " and ".join(output[:2])
return default
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/generators.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/generators.py 2022-05-29 04:47:24.478103 +0000
@@ -7,17 +7,17 @@
async def abatcher(
generator: types.AsyncGenerator,
batch_size: types.Optional[int] = None,
interval: types.Optional[types.delta_type] = None,
):
- '''
+ """
Asyncio generator wrapper that returns items with a given batch size or
interval (whichever is reached first).
- '''
+ """
batch: list = []
- assert batch_size or interval, 'Must specify either batch_size or interval'
+ assert batch_size or interval, "Must specify either batch_size or interval"
if interval:
interval_s = python_utils.delta_to_seconds(interval)
next_yield = time.perf_counter() + interval_s
else:
@@ -46,13 +46,13 @@
# want to burst too much
next_yield = time.perf_counter() + interval_s
def batcher(iterable, batch_size):
- '''
+ """
Generator wrapper that returns items with a given batch size
- '''
+ """
batch = []
for item in iterable:
batch.append(item)
if len(batch) == batch_size:
yield batch
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/import_.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/import_.py 2022-05-29 04:47:24.739549 +0000
@@ -4,18 +4,18 @@
class DummyException(Exception):
pass
def import_global(
- name: str,
- modules: types.Optional[types.List[str]] = None,
- exceptions: types.ExceptionsType = DummyException,
- locals_: types.OptionalScope = None,
- globals_: types.OptionalScope = None,
- level: int = -1,
+ name: str,
+ modules: types.Optional[types.List[str]] = None,
+ exceptions: types.ExceptionsType = DummyException,
+ locals_: types.OptionalScope = None,
+ globals_: types.OptionalScope = None,
+ level: int = -1,
) -> types.Any:
- '''Import the requested items into the global scope
+ """Import the requested items into the global scope
WARNING! this method _will_ overwrite your global scope
If you have a variable named "path" and you call import_global('sys')
it will be overwritten with sys.path
@@ -25,19 +25,20 @@
exception (Exception): the exception to catch, e.g. ImportError
`locals_`: the `locals()` method (in case you need a different scope)
`globals_`: the `globals()` method (in case you need a different scope)
level (int): the level to import from, this can be used for
relative imports
- '''
+ """
frame = None
- name_parts: types.List[str] = name.split('.')
+ name_parts: types.List[str] = name.split(".")
modules_set: types.Set[str] = set()
try:
# If locals_ or globals_ are not given, autodetect them by inspecting
# the current stack
if locals_ is None or globals_ is None:
import inspect
+
frame = inspect.stack()[1][0]
if locals_ is None:
locals_ = frame.f_locals
@@ -50,11 +51,11 @@
name_parts = name_parts[1:]
level = 1
# raise IOError((name, level))
module = __import__(
- name=name_parts[0] or '.',
+ name=name_parts[0] or ".",
globals=globals_,
locals=locals_,
fromlist=name_parts[1:],
level=max(level, 0),
)
@@ -63,24 +64,23 @@
# spam.eggs should return eggs, not spam)
try:
for attr in name_parts[1:]:
module = getattr(module, attr)
except AttributeError:
- raise ImportError('No module named ' + '.'.join(name_parts))
+ raise ImportError("No module named " + ".".join(name_parts))
# If no list of modules is given, autodetect from either __all__
# or a dir() of the module
if not modules:
- modules_set = set(getattr(module, '__all__', dir(module)))
+ modules_set = set(getattr(module, "__all__", dir(module)))
else:
modules_set = set(modules).intersection(dir(module))
# Add all items in modules to the global scope
for k in set(dir(module)).intersection(modules_set):
- if k and k[0] != '_':
+ if k and k[0] != "_":
globals_[k] = getattr(module, k)
except exceptions as e:
return e
finally:
# Clean up, just to be sure
- del name, name_parts, modules, modules_set, exceptions, locals_, \
- globals_, frame
+ del name, name_parts, modules, modules_set, exceptions, locals_, globals_, frame
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/logger.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/logger.py 2022-05-29 04:47:25.016549 +0000
@@ -1,16 +1,16 @@
import abc
import functools
import logging
-__all__ = ['Logged']
+__all__ = ["Logged"]
import typing
class LoggerBase(abc.ABC):
- '''Class which automatically adds logging utilities to your class when
+ """Class which automatically adds logging utilities to your class when
interiting. Expects `logger` to be a logging.Logger or compatible instance.
Adds easy access to debug, info, warning, error, exception and log methods
>>> class MyClass(LoggerBase):
@@ -24,18 +24,19 @@
>>> my_class.info('info')
>>> my_class.warning('warning')
>>> my_class.error('error')
>>> my_class.exception('exception')
>>> my_class.log(0, 'log')
- '''
+ """
+
# Being a tad lazy here and not creating a Protocol.
# The actual classes define the correct type anyway
logger: typing.Any
@classmethod
def __get_name(cls, *name_parts: str) -> str:
- return '.'.join(n.strip() for n in name_parts if n.strip())
+ return ".".join(n.strip() for n in name_parts if n.strip())
@classmethod
@functools.wraps(logging.debug)
def debug(cls, msg: str, *args: typing.Any, **kwargs: typing.Any):
cls.logger.debug(msg, *args, **kwargs)
@@ -65,11 +66,11 @@
def log(cls, lvl: int, msg: str, *args: typing.Any, **kwargs: typing.Any):
cls.logger.log(lvl, msg, *args, **kwargs)
class Logged(LoggerBase):
- '''Class which automatically adds a named logger to your class when
+ """Class which automatically adds a named logger to your class when
interiting
Adds easy access to debug, info, warning, error, exception and log methods
>>> class MyClass(Logged):
@@ -84,18 +85,16 @@
>>> my_class.exception('exception')
>>> my_class.log(0, 'log')
>>> my_class._Logged__get_name('spam')
'spam'
- '''
+ """
logger: logging.Logger # pragma: no cover
@classmethod
def __get_name(cls, *name_parts: str) -> str:
return LoggerBase._LoggerBase__get_name(*name_parts) # type: ignore
def __new__(cls, *args, **kwargs):
- cls.logger = logging.getLogger(
- cls.__get_name(cls.__module__, cls.__name__)
- )
+ cls.logger = logging.getLogger(cls.__get_name(cls.__module__, cls.__name__))
return super(Logged, cls).__new__(cls)
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/loguru.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/loguru.py 2022-05-29 04:47:25.228765 +0000
@@ -2,11 +2,11 @@
from . import logger
import loguru
-__all__ = ['Logurud']
+__all__ = ["Logurud"]
class Logurud(logger.LoggerBase):
logger: loguru.Logger
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/terminal.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/terminal.py 2022-05-29 04:47:25.572693 +0000
@@ -3,54 +3,58 @@
from . import converters
def get_terminal_size() -> typing.Tuple[int, int]: # pragma: no cover
- '''Get the current size of your terminal
+ """Get the current size of your terminal
Multiple returns are not always a good idea, but in this case it greatly
simplifies the code so I believe it's justified. It's not the prettiest
function but that's never really possible with cross-platform code.
Returns:
width, height: Two integers containing width and height
- '''
+ """
w: typing.Optional[int]
h: typing.Optional[int]
try:
# Default to 79 characters for IPython notebooks
from IPython import get_ipython # type: ignore
+
ipython = get_ipython()
from ipykernel import zmqshell # type: ignore
+
if isinstance(ipython, zmqshell.ZMQInteractiveShell):
return 79, 24
except Exception: # pragma: no cover
pass
try:
# This works for Python 3, but not Pypy3. Probably the best method if
# it's supported so let's always try
import shutil
+
w, h = shutil.get_terminal_size()
if w and h:
# The off by one is needed due to progressbars in some cases, for
# safety we'll always substract it.
return w - 1, h
except Exception: # pragma: no cover
pass
try:
- w = converters.to_int(os.environ.get('COLUMNS'))
- h = converters.to_int(os.environ.get('LINES'))
+ w = converters.to_int(os.environ.get("COLUMNS"))
+ h = converters.to_int(os.environ.get("LINES"))
if w and h:
return w, h
except Exception: # pragma: no cover
pass
try:
import blessings # type: ignore
+
terminal = blessings.Terminal()
w = terminal.width
h = terminal.height
if w and h:
return w, h
@@ -98,12 +102,14 @@
except Exception:
return None
if res:
import struct
- (_, _, _, _, _, left, top, right, bottom, _, _) = \
- struct.unpack("hhhhHhhhhhh", csbi.raw)
+
+ (_, _, _, _, _, left, top, right, bottom, _, _) = struct.unpack(
+ "hhhhHhhhhhh", csbi.raw
+ )
w = right - left
h = bottom - top
return w, h
else:
return None
@@ -111,18 +117,25 @@
def _get_terminal_size_tput(): # pragma: no cover
# get terminal width src: http://stackoverflow.com/questions/263890/
try:
import subprocess
+
proc = subprocess.Popen(
- ['tput', 'cols'], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ ["tput", "cols"],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
output = proc.communicate(input=None)
w = int(output[0])
proc = subprocess.Popen(
- ['tput', 'lines'], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ ["tput", "lines"],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
output = proc.communicate(input=None)
h = int(output[0])
return w, h
except Exception:
return None
@@ -132,12 +145,12 @@
def ioctl_GWINSZ(fd):
try:
import fcntl
import termios
import struct
- size = struct.unpack(
- 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
+
+ size = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234"))
except Exception:
return None
return size
size = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
@@ -149,10 +162,10 @@
os.close(fd)
except Exception:
pass
if not size:
try:
- size = os.environ['LINES'], os.environ['COLUMNS']
+ size = os.environ["LINES"], os.environ["COLUMNS"]
except Exception:
return None
return int(size[1]), int(size[0])
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/time.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/time.py 2022-05-29 04:47:26.011248 +0000
@@ -11,11 +11,11 @@
# a pull request if you know a better way that functions for Python 2 and 3
epoch = datetime.datetime(year=1970, month=1, day=1)
def timedelta_to_seconds(delta: datetime.timedelta) -> types.Number:
- '''Convert a timedelta to seconds with the microseconds as fraction
+ """Convert a timedelta to seconds with the microseconds as fraction
Note that this method has become largely obsolete with the
`timedelta.total_seconds()` method introduced in Python 2.7.
>>> from datetime import timedelta
@@ -25,11 +25,11 @@
'1'
>>> '%.6f' % timedelta_to_seconds(timedelta(seconds=1, microseconds=1))
'1.000001'
>>> '%.6f' % timedelta_to_seconds(timedelta(microseconds=1))
'0.000001'
- '''
+ """
# Only convert to float if needed
if delta.microseconds:
total = delta.microseconds * 1e-6
else:
total = 0
@@ -37,11 +37,11 @@
total += delta.days * 60 * 60 * 24
return total
def delta_to_seconds(interval: types.delta_type) -> float:
- '''
+ """
Convert a timedelta to seconds
>>> delta_to_seconds(datetime.timedelta(seconds=1))
1
>>> delta_to_seconds(datetime.timedelta(seconds=1, microseconds=1))
@@ -50,33 +50,33 @@
1
>>> delta_to_seconds('whatever') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: Unknown type ...
- '''
+ """
if isinstance(interval, datetime.timedelta):
return timedelta_to_seconds(interval)
elif isinstance(interval, (int, float)):
return interval
else:
- raise TypeError('Unknown type %s: %r' % (type(interval), interval))
+ raise TypeError("Unknown type %s: %r" % (type(interval), interval))
def delta_to_seconds_or_none(
- interval: types.Optional[types.delta_type]
+ interval: types.Optional[types.delta_type],
) -> types.Optional[float]:
if interval is None:
return None
else:
return delta_to_seconds(interval)
def format_time(
timestamp: types.timestamp_type,
- precision: datetime.timedelta = datetime.timedelta(seconds=1)
+ precision: datetime.timedelta = datetime.timedelta(seconds=1),
) -> str:
- '''Formats timedelta/datetime/seconds
+ """Formats timedelta/datetime/seconds
>>> format_time('1')
'0:00:01'
>>> format_time(1.234)
'0:00:01'
@@ -93,11 +93,11 @@
>>> format_time(format_time) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: Unknown type ...
- '''
+ """
precision_seconds = precision.total_seconds()
if isinstance(timestamp, str):
timestamp = float(timestamp)
@@ -113,11 +113,11 @@
seconds = seconds - (seconds % precision_seconds)
return str(datetime.timedelta(seconds=seconds))
elif isinstance(timestamp, datetime.datetime): # pragma: no cover
# Python 2 doesn't have the timestamp method
- if hasattr(timestamp, 'timestamp'):
+ if hasattr(timestamp, "timestamp"):
seconds = timestamp.timestamp()
else:
seconds = timedelta_to_seconds(timestamp - epoch)
# Truncate the number to the given precision
@@ -129,24 +129,23 @@
dt = datetime.datetime.max
return str(dt)
elif isinstance(timestamp, datetime.date):
return str(timestamp)
elif timestamp is None:
- return '--:--:--'
- else:
- raise TypeError('Unknown type %s: %r' % (type(timestamp), timestamp))
+ return "--:--:--"
+ else:
+ raise TypeError("Unknown type %s: %r" % (type(timestamp), timestamp))
def timeout_generator(
timeout: types.delta_type,
interval: types.delta_type = datetime.timedelta(seconds=1),
- iterable: types.Union[types.Iterable, types.Callable] =
- itertools.count,
+ iterable: types.Union[types.Iterable, types.Callable] = itertools.count,
interval_multiplier: float = 1.0,
maximum_interval: types.Optional[types.delta_type] = None,
):
- '''
+ """
Generator that walks through the given iterable (a counter by default)
until the float_timeout is reached with a configurable float_interval
between items
>>> for i in timeout_generator(0.1, 0.06):
@@ -171,11 +170,11 @@
>>> for i in timeout_generator(timeout, interval, interval_multiplier=2):
... print(i)
0
1
2
- '''
+ """
float_timeout: float = delta_to_seconds(timeout)
float_interval: float = delta_to_seconds(interval)
float_maximum_interval: types.Optional[float] = delta_to_seconds_or_none(
maximum_interval
)
@@ -201,16 +200,15 @@
async def aio_timeout_generator(
timeout: types.delta_type,
interval: types.delta_type = datetime.timedelta(seconds=1),
- iterable: types.Union[
- types.AsyncIterable, types.Callable] = aio.acount,
+ iterable: types.Union[types.AsyncIterable, types.Callable] = aio.acount,
interval_multiplier: float = 1.0,
maximum_interval: types.Optional[types.delta_type] = None,
):
- '''
+ """
Aync generator that walks through the given iterable (a counter by
default) until the float_timeout is reached with a configurable
float_interval between items
The interval_exponent automatically increases the float_timeout with each
@@ -219,11 +217,11 @@
float_interval with each run, specify 2.
Doctests and asyncio are not friends, so no examples. But this function is
effectively the same as the `timeout_generator` but it uses `async for`
instead.
- '''
+ """
float_timeout: float = delta_to_seconds(timeout)
float_interval: float = delta_to_seconds(interval)
float_maximum_interval: types.Optional[float] = delta_to_seconds_or_none(
maximum_interval
)
@@ -253,49 +251,41 @@
timeout: types.Optional[types.delta_type] = None,
total_timeout: types.Optional[types.delta_type] = None,
on_timeout: types.Optional[types.Callable] = exceptions.reraise,
**kwargs,
):
- '''
+ """
This function is used to detect if an asyncio generator has not yielded
an element for a set amount of time.
The `on_timeout` argument is called with the `generator`, `timeout`,
`total_timeout`, `exception` and the extra `**kwargs` to this function as
arguments.
If `on_timeout` is not specified, the exception is reraised.
If `on_timeout` is `None`, the exception is silently ignored and the
generator will finish as normal.
- '''
+ """
if total_timeout is None:
total_timeout_end = None
else:
- total_timeout_end = time.perf_counter() + delta_to_seconds(
- total_timeout
- )
+ total_timeout_end = time.perf_counter() + delta_to_seconds(total_timeout)
timeout_s = python_utils.delta_to_seconds_or_none(timeout)
while True:
try:
if total_timeout_end and time.perf_counter() >= total_timeout_end:
- raise asyncio.TimeoutError('Total timeout reached')
+ raise asyncio.TimeoutError("Total timeout reached")
if timeout_s:
yield await asyncio.wait_for(generator.__anext__(), timeout_s)
else:
yield await generator.__anext__()
except asyncio.TimeoutError as exception:
if on_timeout is not None:
- await on_timeout(
- generator,
- timeout,
- total_timeout,
- exception,
- **kwargs
- )
+ await on_timeout(generator, timeout, total_timeout, exception, **kwargs)
break
except StopAsyncIteration:
break
@@ -304,18 +294,18 @@
timeout: types.Optional[types.delta_type] = None,
total_timeout: types.Optional[types.delta_type] = None,
on_timeout: types.Optional[types.Callable] = exceptions.reraise,
**kwargs,
):
- '''
+ """
A decorator wrapper for aio_generator_timeout_detector.
- '''
+ """
def _timeout_detector_decorator(generator: types.Callable):
- '''
+ """
The decorator itself.
- '''
+ """
@functools.wraps(generator)
def wrapper(*args, **wrapper_kwargs):
return aio_generator_timeout_detector(
generator(*args, **wrapper_kwargs),
____________________________________________________________________________ Black format check ____________________________________________________________________________
--- /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/types.py 2022-05-29 02:07:44 +0000
+++ /home/tkloczko/rpmbuild/BUILD/python-utils-3.3.0/python_utils/types.py 2022-05-29 04:47:26.879586 +0000
@@ -1,15 +1,17 @@
import datetime
import decimal
from typing import * # pragma: no cover
+
# import * does not import Pattern
from typing import Pattern
# Quickhand for optional because it gets so much use. If only Python had
# support for an optional type shorthand such as `SomeType?` instead of
# `Optional[SomeType]`.
from typing import Optional as O
+
# Since the Union operator is only supported for Python 3.10, we'll create a
# shorthand for it.
from typing import Union as U
Scope = Dict[str, Any]
@@ -32,109 +34,102 @@
]
assert Pattern
__all__ = [
- 'OptionalScope',
- 'Number',
- 'DecimalNumber',
- 'delta_type',
- 'timestamp_type',
-
+ "OptionalScope",
+ "Number",
+ "DecimalNumber",
+ "delta_type",
+ "timestamp_type",
# The types from the typing module.
-
# Super-special typing primitives.
- 'Annotated',
- 'Any',
- 'Callable',
- 'ClassVar',
- 'Concatenate',
- 'Final',
- 'ForwardRef',
- 'Generic',
- 'Literal',
- 'Optional',
- 'ParamSpec',
- 'Protocol',
- 'Tuple',
- 'Type',
- 'TypeVar',
- 'Union',
-
+ "Annotated",
+ "Any",
+ "Callable",
+ "ClassVar",
+ "Concatenate",
+ "Final",
+ "ForwardRef",
+ "Generic",
+ "Literal",
+ "Optional",
+ "ParamSpec",
+ "Protocol",
+ "Tuple",
+ "Type",
+ "TypeVar",
+ "Union",
# ABCs (from collections.abc).
- 'AbstractSet', # collections.abc.Set.
- 'ByteString',
- 'Container',
- 'ContextManager',
- 'Hashable',
- 'ItemsView',
- 'Iterable',
- 'Iterator',
- 'KeysView',
- 'Mapping',
- 'MappingView',
- 'MutableMapping',
- 'MutableSequence',
- 'MutableSet',
- 'Sequence',
- 'Sized',
- 'ValuesView',
- 'Awaitable',
- 'AsyncIterator',
- 'AsyncIterable',
- 'Coroutine',
- 'Collection',
- 'AsyncGenerator',
- 'AsyncContextManager',
-
+ "AbstractSet", # collections.abc.Set.
+ "ByteString",
+ "Container",
+ "ContextManager",
+ "Hashable",
+ "ItemsView",
+ "Iterable",
+ "Iterator",
+ "KeysView",
+ "Mapping",
+ "MappingView",
+ "MutableMapping",
+ "MutableSequence",
+ "MutableSet",
+ "Sequence",
+ "Sized",
+ "ValuesView",
+ "Awaitable",
+ "AsyncIterator",
+ "AsyncIterable",
+ "Coroutine",
+ "Collection",
+ "AsyncGenerator",
+ "AsyncContextManager",
# Structural checks, a.k.a. protocols.
- 'Reversible',
- 'SupportsAbs',
- 'SupportsBytes',
- 'SupportsComplex',
- 'SupportsFloat',
- 'SupportsIndex',
- 'SupportsInt',
- 'SupportsRound',
-
+ "Reversible",
+ "SupportsAbs",
+ "SupportsBytes",
+ "SupportsComplex",
+ "SupportsFloat",
+ "SupportsIndex",
+ "SupportsInt",
+ "SupportsRound",
# Concrete collection types.
- 'ChainMap',
- 'Counter',
- 'Deque',
- 'Dict',
- 'DefaultDict',
- 'List',
- 'OrderedDict',
- 'Set',
- 'FrozenSet',
- 'NamedTuple', # Not really a type.
- 'TypedDict', # Not really a type.
- 'Generator',
-
+ "ChainMap",
+ "Counter",
+ "Deque",
+ "Dict",
+ "DefaultDict",
+ "List",
+ "OrderedDict",
+ "Set",
+ "FrozenSet",
+ "NamedTuple", # Not really a type.
+ "TypedDict", # Not really a type.
+ "Generator",
# Other concrete types.
- 'BinaryIO',
- 'IO',
- 'Match',
- 'Pattern',
- 'TextIO',
-
+ "BinaryIO",
+ "IO",
+ "Match",
+ "Pattern",
+ "TextIO",
# One-off things.
- 'AnyStr',
- 'cast',
- 'final',
- 'get_args',
- 'get_origin',
- 'get_type_hints',
- 'is_typeddict',
- 'NewType',
- 'no_type_check',
- 'no_type_check_decorator',
- 'NoReturn',
- 'overload',
- 'ParamSpecArgs',
- 'ParamSpecKwargs',
- 'runtime_checkable',
- 'Text',
- 'TYPE_CHECKING',
- 'TypeAlias',
- 'TypeGuard',
+ "AnyStr",
+ "cast",
+ "final",
+ "get_args",
+ "get_origin",
+ "get_type_hints",
+ "is_typeddict",
+ "NewType",
+ "no_type_check",
+ "no_type_check_decorator",
+ "NoReturn",
+ "overload",
+ "ParamSpecArgs",
+ "ParamSpecKwargs",
+ "runtime_checkable",
+ "Text",
+ "TYPE_CHECKING",
+ "TypeAlias",
+ "TypeGuard",
]
============================================================================= warnings summary =============================================================================
../../../../../usr/lib/python3.8/site-packages/_pytest/config/__init__.py:1252
/usr/lib/python3.8/site-packages/_pytest/config/__init__.py:1252: PytestConfigWarning: Unknown config option: flake8-ignore
self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")
../../../../../usr/lib/python3.8/site-packages/_pytest/nodes.py:146: 25 warnings
/usr/lib/python3.8/site-packages/_pytest/nodes.py:146: PytestDeprecationWarning: <class 'pytest_black.BlackItem'> is not using a cooperative constructor and only takes {'fspath', 'parent'}.
See https://docs.pytest.org/en/stable/deprecations.html#constructors-of-custom-pytest-node-subclasses-should-take-kwargs for more details.
warnings.warn(
../../../../../usr/lib/python3.8/site-packages/_pytest/nodes.py:264: 25 warnings
/usr/lib/python3.8/site-packages/_pytest/nodes.py:264: PytestRemovedIn8Warning: The (fspath: py.path.local) argument to BlackItem is deprecated. Please use the (path: pathlib.Path) argument instead.
See https://docs.pytest.org/en/latest/deprecations.html#fspath-argument-for-node-constructors-replaced-with-pathlib-path
return cls._create(parent=parent, **kw)
../../../../../usr/lib/python3.8/site-packages/_pytest/nodes.py:708
/usr/lib/python3.8/site-packages/_pytest/nodes.py:708: PytestWarning: BlackItem is an Item subclass and should not be a collector, however its bases File are collectors.
Please split the Collectors and the Item into separate node types.
Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html
example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/
warnings.warn(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=================================================================================== mypy ===================================================================================
Found 1 error in 1 file (checked 25 source files)
========================================================================= short test summary info ==========================================================================
FAILED setup.py::BLACK
FAILED setup.py::mypy
FAILED setup.py::mypy-status
FAILED _python_utils_tests/test_decorators.py::BLACK
FAILED _python_utils_tests/test_generators.py::BLACK
FAILED _python_utils_tests/test_import.py::BLACK
FAILED _python_utils_tests/test_logger.py::BLACK
FAILED _python_utils_tests/test_python_utils.py::BLACK
FAILED _python_utils_tests/test_time.py::BLACK
FAILED docs/conf.py::BLACK
FAILED python_utils/__init__.py::BLACK
FAILED python_utils/__about__.py::BLACK
FAILED python_utils/aio.py::BLACK
FAILED python_utils/containers.py::BLACK
FAILED python_utils/converters.py::BLACK
FAILED python_utils/decorators.py::BLACK
FAILED python_utils/exceptions.py::BLACK
FAILED python_utils/formatters.py::BLACK
FAILED python_utils/generators.py::BLACK
FAILED python_utils/import_.py::BLACK
FAILED python_utils/logger.py::BLACK
FAILED python_utils/loguru.py::BLACK
FAILED python_utils/terminal.py::BLACK
FAILED python_utils/time.py::BLACK
FAILED python_utils/types.py::BLACK
=============================================================== 25 failed, 71 passed, 52 warnings in 44.22s ================================================================ |
Thank you for letting me know @kloczek That setting actually isn't needed anymore since the last migration to flake8 from pytest-flake8. I've run |
Yep .. 😄
The text was updated successfully, but these errors were encountered: