Skip to content

3.1.0: pytest coverage of 100.0% not reached #29

Closed

Description

@kloczek

Yep .. 😄

+ 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.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%]

---------- 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 in 16.24s ============================================================================

Activity

  1. wolph commented on Jan 15, 2022

    @wolph
    Owner

    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

  2. wolph commented on Jan 15, 2022

    @wolph
    Owner

    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 _python_utils_tests:

    Github actions tests:

    setup.py ..                                                              [  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 ..........                              [ 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%]
    
  3. wolph commented on Jan 15, 2022

    @wolph
    Owner

    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

  4. kloczek commented on Jan 15, 2022

    @kloczek
    Author

    I have no idea 🤔
    Nevertheless when I'm running pytest without params pytest is scanning not only files specified in python_files (as same as in your case) and it shows as well some warnings.

    + /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) ======================================================
    

    pytest and coverity used in my env are listed in pytest headr.
    Because pytest have been scanning setup.py Ive decided to add python_utils as pytest param.
    Temporary in my rpm build procedure I'm using --no-cov

    + /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 ============================================================================
    
  5. wolph commented on Jan 15, 2022

    @wolph
    Owner

    The setuptools warning and the asyncio warnings indicate missing requirements. These are part of the tests extras in the requirements: https://github.com/WoLpH/python-utils/blob/c70f3b8b05686e84bc191995b7cce44b99f53c42/setup.py#L37-L46

    I think it should run fine once those are installed

  6. kloczek commented on Jan 15, 2022

    @kloczek
    Author

    pytest output after add pytest-asyncio to build env

    =========================================================================== 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.

  7. kloczek commented on Jan 15, 2022

    @kloczek
    Author

    Nevertheless after remove --no-cov still coverity dost not show 100% 🤔

    + /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 ======================================================================
    
  8. wolph commented on Jan 15, 2022

    @wolph
    Owner

    Did you see my previous message about installing the extra tests packages?

    It looks like those might be missing.

  9. kloczek commented on Jan 15, 2022

    @kloczek
    Author

    Did you see my previous message about installing the extra tests packages?

    Yes however I've lost somehow pytest-asyncio (my fault).

    It looks like those might be missing.

    Looking one more time on that list I still don't have packaged types-setuptools.
    Do you think that that eooe may be caused by missing that module? 🤔

  10. kloczek commented on May 4, 2022

    @kloczek
    Author

    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 ==================================================================
    

    asyncio_mode warning can be fixed by add asyncio_mode=auto to pytest.ini

  11. wolph commented on May 12, 2022

    @wolph
    Owner

    Thank you for letting me know :)

    I've fixed all the issues and enabled nit-picky mode by default for the documentation tests

  12. kloczek commented on May 29, 2022

    @kloczek
    Author

    Just tested new version and generally test suite look better now.
    Tis time I've tested as well pytest without specify python_utils as param.
    Looks like mypy complains about content of the setup.py

    + 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 flake8 optional without emitting that warning.
    If you don't want to make it optional I would be glad to learn how to supress that exact warning because in my build procedure I don't need 'flake8` as obligatory rpm spec file BuildRequires.

  13. kloczek commented on May 29, 2022

    @kloczek
    Author

    Also I've manually tested pytest output with pytest-black installed and I think that it would be good to apply patch generated by that extension

    Details
    + 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 ================================================================
    
  14. added a commit that references this issue on May 29, 2022
    157c39b
  15. wolph commented on May 29, 2022

    @wolph
    Owner

    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 black on the code as well but I'm not going to use the pytest-black plugin. I just moved away from pytest-flake8 because those kinds of plugins tend not to last (i've had to replace multiple over the years)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions