dycw-utilities 0.147.3__tar.gz → 0.148.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/PKG-INFO +1 -1
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/pyproject.toml +2 -2
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_asyncio.py +33 -10
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_pottery.py +3 -4
- dycw_utilities-0.148.0/src/tests/test_yield_access/script.py +61 -0
- dycw_utilities-0.148.0/src/tests/test_yield_access/script.sh +54 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/asyncio.py +36 -7
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pottery.py +6 -35
- dycw_utilities-0.148.0/src/utilities/pytest_plugins/__init__.py +1 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/.gitignore +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/LICENSE +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/README.md +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_gzip.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_inflect.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_json.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_objects/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_objects/objects.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_postgres.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_pytest_randomly.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_statsmodels.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_typed_settings.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.147.3/src/utilities/pytest_plugins → dycw_utilities-0.148.0/src/tests/test_yield_access}/__init__.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/click.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/gzip.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/http.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/json.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/math.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/os.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/period.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/postgres.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/random.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/re.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/string.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/text.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/typed_settings.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/types.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/version.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/utilities/zoneinfo.py +0 -0
@@ -102,7 +102,7 @@ dependencies = [
|
|
102
102
|
name = "dycw-utilities"
|
103
103
|
readme = "README.md"
|
104
104
|
requires-python = ">= 3.12"
|
105
|
-
version = "0.
|
105
|
+
version = "0.148.0"
|
106
106
|
|
107
107
|
[project.entry-points.pytest11]
|
108
108
|
pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
|
@@ -135,7 +135,7 @@ test = [
|
|
135
135
|
# bump-my-version
|
136
136
|
[tool.bumpversion]
|
137
137
|
allow_dirty = true
|
138
|
-
current_version = "0.
|
138
|
+
current_version = "0.148.0"
|
139
139
|
|
140
140
|
[[tool.bumpversion.files]]
|
141
141
|
filename = "src/utilities/__init__.py"
|
@@ -8,11 +8,12 @@ from typing import TYPE_CHECKING, ClassVar
|
|
8
8
|
|
9
9
|
from hypothesis import given
|
10
10
|
from hypothesis.strategies import booleans, dictionaries, integers, lists, none
|
11
|
-
from pytest import RaisesGroup, raises
|
11
|
+
from pytest import LogCaptureFixture, RaisesGroup, mark, param, raises
|
12
12
|
|
13
13
|
from utilities.asyncio import (
|
14
14
|
AsyncDict,
|
15
15
|
EnhancedTaskGroup,
|
16
|
+
get_coroutine_name,
|
16
17
|
get_items,
|
17
18
|
get_items_nowait,
|
18
19
|
loop_until_succeed,
|
@@ -27,6 +28,7 @@ from utilities.asyncio import (
|
|
27
28
|
)
|
28
29
|
from utilities.hypothesis import pairs, text_ascii
|
29
30
|
from utilities.pytest import skipif_windows
|
31
|
+
from utilities.text import unique_str
|
30
32
|
from utilities.timer import Timer
|
31
33
|
from utilities.whenever import MILLISECOND, SECOND, get_now
|
32
34
|
|
@@ -287,6 +289,16 @@ class TestEnhancedTaskGroup:
|
|
287
289
|
_ = tg.create_task(sleep_td(2 * self.delta))
|
288
290
|
|
289
291
|
|
292
|
+
class TestGetCoroutineName:
|
293
|
+
def test_main(self) -> None:
|
294
|
+
async def func() -> None:
|
295
|
+
return None
|
296
|
+
|
297
|
+
result = get_coroutine_name(func)
|
298
|
+
expected = "func"
|
299
|
+
assert result == expected
|
300
|
+
|
301
|
+
|
290
302
|
class TestGetItems:
|
291
303
|
@given(
|
292
304
|
xs=lists(integers(), min_size=1),
|
@@ -306,7 +318,12 @@ class TestGetItems:
|
|
306
318
|
|
307
319
|
|
308
320
|
class TestLoopUntilSucceed:
|
309
|
-
|
321
|
+
@mark.parametrize("sleep", [param(MILLISECOND), param(None)])
|
322
|
+
@mark.parametrize("use_logger", [param(True), param(False)])
|
323
|
+
async def test_main(
|
324
|
+
self, *, caplog: LogCaptureFixture, sleep: TimeDelta | None, use_logger: bool
|
325
|
+
) -> None:
|
326
|
+
caplog.set_level("DEBUG", logger=(name := unique_str()))
|
310
327
|
counter = 0
|
311
328
|
|
312
329
|
async def func() -> None:
|
@@ -315,12 +332,22 @@ class TestLoopUntilSucceed:
|
|
315
332
|
if counter <= 3:
|
316
333
|
raise ValueError
|
317
334
|
|
318
|
-
|
335
|
+
assert await loop_until_succeed(
|
336
|
+
lambda: func(), logger=name if use_logger else None, sleep=sleep
|
337
|
+
)
|
319
338
|
assert counter == 4
|
320
339
|
|
340
|
+
if use_logger:
|
341
|
+
messages = [r.message for r in caplog.records if r.name == name]
|
342
|
+
expected = 3 * (
|
343
|
+
["Error running 'func'"]
|
344
|
+
+ ([] if sleep is None else ["Sleeping for PT0.001S..."])
|
345
|
+
+ ["Retrying 'func'..."]
|
346
|
+
)
|
347
|
+
assert messages == expected
|
348
|
+
|
321
349
|
async def test_error(self) -> None:
|
322
350
|
counter = 0
|
323
|
-
errors: list[Exception] = []
|
324
351
|
|
325
352
|
async def func() -> None:
|
326
353
|
nonlocal counter
|
@@ -328,12 +355,8 @@ class TestLoopUntilSucceed:
|
|
328
355
|
if counter <= 3:
|
329
356
|
raise ValueError
|
330
357
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
_ = await loop_until_succeed(lambda: func(), error=error)
|
335
|
-
assert counter == 4
|
336
|
-
assert len(errors) == 3
|
358
|
+
assert not await loop_until_succeed(lambda: func(), errors=ValueError)
|
359
|
+
assert counter == 1
|
337
360
|
|
338
361
|
|
339
362
|
class TestPutItems:
|
@@ -1,7 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from asyncio import TaskGroup
|
4
|
-
from itertools import repeat
|
5
4
|
from typing import TYPE_CHECKING, ClassVar
|
6
5
|
|
7
6
|
from pottery import AIORedlock
|
@@ -74,7 +73,7 @@ class TestTryYieldCoroutineLooper:
|
|
74
73
|
redis, key, timeout_acquire=self.delta, logger=logger
|
75
74
|
) as looper:
|
76
75
|
if looper is not None:
|
77
|
-
await looper(self.func_main, lst)
|
76
|
+
assert await looper(self.func_main, lst)
|
78
77
|
|
79
78
|
async def delayed(
|
80
79
|
self,
|
@@ -102,11 +101,11 @@ class TestTryYieldCoroutineLooper:
|
|
102
101
|
logger=name if use_logger else None,
|
103
102
|
) as looper:
|
104
103
|
assert looper is not None
|
105
|
-
await looper(self.func_error, lst)
|
104
|
+
assert await looper(self.func_error, lst)
|
106
105
|
|
107
106
|
if use_logger:
|
108
107
|
messages = [r.message for r in caplog.records if r.name == name]
|
109
|
-
expected =
|
108
|
+
expected = 3 * ["Error running 'func_error'", "Retrying 'func_error'..."]
|
110
109
|
assert messages == expected
|
111
110
|
|
112
111
|
async def func_error(self, lst: list[None], /) -> None:
|
@@ -0,0 +1,61 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from asyncio import run
|
4
|
+
from logging import getLogger
|
5
|
+
from random import randint
|
6
|
+
from typing import TYPE_CHECKING
|
7
|
+
|
8
|
+
from redis.asyncio import Redis
|
9
|
+
|
10
|
+
from utilities.asyncio import sleep_td
|
11
|
+
from utilities.logging import setup_logging
|
12
|
+
from utilities.pathlib import get_repo_root
|
13
|
+
from utilities.pottery import extend_lock, try_yield_coroutine_looper
|
14
|
+
from utilities.whenever import SECOND
|
15
|
+
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
from pottery import AIORedlock
|
18
|
+
|
19
|
+
_LOGGER = getLogger(__name__)
|
20
|
+
|
21
|
+
|
22
|
+
async def script(*, lock: AIORedlock | None = None) -> None:
|
23
|
+
total = 1000
|
24
|
+
fail = 30
|
25
|
+
success = 3
|
26
|
+
while True:
|
27
|
+
n = randint(0, total)
|
28
|
+
if n < fail:
|
29
|
+
_LOGGER.info("n = %d; failing...", n)
|
30
|
+
msg = f"n = {n}; failure"
|
31
|
+
raise ValueError(msg)
|
32
|
+
if fail <= n < (fail + success):
|
33
|
+
_LOGGER.info("n = %d; succeeding...", n)
|
34
|
+
return
|
35
|
+
_LOGGER.info("n = %d", n)
|
36
|
+
await extend_lock(lock=lock)
|
37
|
+
await sleep_td(SECOND / 3)
|
38
|
+
|
39
|
+
|
40
|
+
async def service() -> None:
|
41
|
+
redis = Redis()
|
42
|
+
async with try_yield_coroutine_looper(
|
43
|
+
redis,
|
44
|
+
"utilities-test",
|
45
|
+
num=1,
|
46
|
+
timeout_release=5 * SECOND,
|
47
|
+
logger=_LOGGER,
|
48
|
+
sleep_error=4 * SECOND,
|
49
|
+
) as looper:
|
50
|
+
if looper is not None:
|
51
|
+
result = await looper(script, lock=looper.lock)
|
52
|
+
_LOGGER.info("script %s", "succeeded" if result else "failed")
|
53
|
+
|
54
|
+
|
55
|
+
def main() -> None:
|
56
|
+
setup_logging(logger=_LOGGER, files_dir=get_repo_root().joinpath(".logs"))
|
57
|
+
run(service())
|
58
|
+
|
59
|
+
|
60
|
+
if __name__ == "__main__":
|
61
|
+
main()
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env sh
|
2
|
+
|
3
|
+
# Add to your `crontab` as:
|
4
|
+
# * * * * * /Users/derekwan/work/python-utilities/tests/test_yield_access/script.sh
|
5
|
+
|
6
|
+
# helpers
|
7
|
+
echo_pid_date() { echo "[$$ | $(date +'%Y-%m-%d %H:%M:%S')] $*"; }
|
8
|
+
|
9
|
+
# add to `$PATH`
|
10
|
+
for __dir in "${HOME}/.local/bin" '/opt/homebrew/bin' '/opt/homebrew/opt/postgresql@17/bin'; do
|
11
|
+
if [ -d "${__dir}" ]; then
|
12
|
+
case ":${PATH}:" in
|
13
|
+
*:"$__dir":*) ;;
|
14
|
+
*)
|
15
|
+
export PATH="${__dir}:${PATH}"
|
16
|
+
;;
|
17
|
+
esac
|
18
|
+
fi
|
19
|
+
done
|
20
|
+
|
21
|
+
# log file
|
22
|
+
__package_dir="${HOME}/work/python-utilities"
|
23
|
+
__log_file="${__package_dir}/.logs/test-yield-access"
|
24
|
+
|
25
|
+
# check if binaries are accessible
|
26
|
+
for __app in direnv just uv; do
|
27
|
+
if ! command -v "${__app}" >/dev/null 2>&1; then
|
28
|
+
echo_pid_date "ERROR: Command '${__app}' not found; exiting..." 2>&1 | tee -a "${__log_file}"
|
29
|
+
exit
|
30
|
+
fi
|
31
|
+
done
|
32
|
+
|
33
|
+
# enter package
|
34
|
+
echo_pid_date "Entering package directory '${__package_dir}'..." 2>&1 | tee -a "${__log_file}"
|
35
|
+
cd "${__package_dir}" || exit
|
36
|
+
|
37
|
+
# trim log
|
38
|
+
__threshold=$((10 * 1024 * 1024))
|
39
|
+
if [ -f "${__log_file}" ]; then
|
40
|
+
__log_size=$(wc -c <"${__log_file}")
|
41
|
+
if [ "${__log_size}" -gt "${__threshold}" ]; then
|
42
|
+
echo_pid_date "Truncating log file '${__log_file}' (log size = ${__log_size})..." 2>&1 | tee -a "${__log_file}"
|
43
|
+
__total_lines=$(wc -l <"${__log_file}")
|
44
|
+
__keep_lines=$((__total_lines / 2))
|
45
|
+
__tmp_log_file="${__log_file}.tmp.$$"
|
46
|
+
tail -n "${__keep_lines}" "${__log_file}" >"${__tmp_log_file}" && mv "${__tmp_log_file}" "${__log_file}"
|
47
|
+
fi
|
48
|
+
fi
|
49
|
+
|
50
|
+
# run the script
|
51
|
+
echo_pid_date "Running 'PYTHONPATH=src/tests/test_yield_access python -m script'..." 2>&1 | tee -a "${__log_file}"
|
52
|
+
__start="$(date +%s)"
|
53
|
+
PYTHONPATH=src/tests/test_yield_access direnv exec . python -m script "$*" 2>&1 | tee -a "${__log_file}"
|
54
|
+
__exit_code="$?"
|
@@ -37,8 +37,10 @@ from typing import (
|
|
37
37
|
|
38
38
|
from utilities.errors import ImpossibleCaseError
|
39
39
|
from utilities.functions import ensure_int, ensure_not_none, to_bool
|
40
|
+
from utilities.logging import get_logger
|
40
41
|
from utilities.random import SYSTEM_RANDOM
|
41
42
|
from utilities.sentinel import Sentinel, sentinel
|
43
|
+
from utilities.warnings import suppress_warnings
|
42
44
|
from utilities.whenever import get_now, round_date_or_date_time, to_nanoseconds
|
43
45
|
|
44
46
|
if TYPE_CHECKING:
|
@@ -63,6 +65,7 @@ if TYPE_CHECKING:
|
|
63
65
|
from utilities.types import (
|
64
66
|
Coro,
|
65
67
|
Delta,
|
68
|
+
LoggerOrName,
|
66
69
|
MaybeCallableBool,
|
67
70
|
MaybeType,
|
68
71
|
SupportsKeysAndGetItem,
|
@@ -340,6 +343,20 @@ class EnhancedTaskGroup(TaskGroup):
|
|
340
343
|
##
|
341
344
|
|
342
345
|
|
346
|
+
def get_coroutine_name(func: Callable[[], Coro[Any]], /) -> str:
|
347
|
+
"""Get the name of a coroutine, and then dispose of it gracefully."""
|
348
|
+
coro = func()
|
349
|
+
name = coro.__name__
|
350
|
+
with suppress_warnings(
|
351
|
+
message="coroutine '.*' was never awaited", category=RuntimeWarning
|
352
|
+
):
|
353
|
+
del coro
|
354
|
+
return name
|
355
|
+
|
356
|
+
|
357
|
+
##
|
358
|
+
|
359
|
+
|
343
360
|
async def get_items[T](queue: Queue[T], /, *, max_size: int | None = None) -> list[T]:
|
344
361
|
"""Get items from a queue; if empty then wait."""
|
345
362
|
try:
|
@@ -380,23 +397,34 @@ async def loop_until_succeed(
|
|
380
397
|
func: Callable[[], Coro[None]],
|
381
398
|
/,
|
382
399
|
*,
|
383
|
-
|
400
|
+
logger: LoggerOrName | None = None,
|
401
|
+
errors: type[Exception] | tuple[type[Exception], ...] | None = None,
|
384
402
|
sleep: Delta | None = None,
|
385
|
-
) ->
|
403
|
+
) -> bool:
|
386
404
|
"""Repeatedly call a coroutine until it succeeds."""
|
405
|
+
name = get_coroutine_name(func)
|
387
406
|
while True:
|
388
407
|
try:
|
389
|
-
|
390
|
-
except Exception as
|
391
|
-
if
|
392
|
-
error(
|
408
|
+
await func()
|
409
|
+
except Exception as error: # noqa: BLE001
|
410
|
+
if logger is not None:
|
411
|
+
get_logger(logger=logger).error("Error running %r", name, exc_info=True)
|
393
412
|
exc_type, exc_value, traceback = sys.exc_info()
|
394
413
|
if (exc_type is None) or (exc_value is None): # pragma: no cover
|
395
414
|
raise ImpossibleCaseError(
|
396
415
|
case=[f"{exc_type=}", f"{exc_value=}"]
|
397
416
|
) from None
|
398
417
|
sys.excepthook(exc_type, exc_value, traceback)
|
399
|
-
|
418
|
+
if (errors is not None) and isinstance(error, errors):
|
419
|
+
return False
|
420
|
+
if sleep is not None:
|
421
|
+
if logger is not None:
|
422
|
+
get_logger(logger=logger).info("Sleeping for %s...", sleep)
|
423
|
+
await sleep_td(sleep)
|
424
|
+
if logger is not None:
|
425
|
+
get_logger(logger=logger).info("Retrying %r...", name)
|
426
|
+
else:
|
427
|
+
return True
|
400
428
|
|
401
429
|
|
402
430
|
##
|
@@ -522,6 +550,7 @@ __all__ = [
|
|
522
550
|
"AsyncDict",
|
523
551
|
"EnhancedTaskGroup",
|
524
552
|
"StreamCommandOutput",
|
553
|
+
"get_coroutine_name",
|
525
554
|
"get_items",
|
526
555
|
"get_items_nowait",
|
527
556
|
"loop_until_succeed",
|
@@ -5,16 +5,14 @@ from dataclasses import dataclass
|
|
5
5
|
from sys import maxsize
|
6
6
|
from typing import TYPE_CHECKING, override
|
7
7
|
|
8
|
-
from pottery import AIORedlock
|
8
|
+
from pottery import AIORedlock, ExtendUnlockedLock
|
9
9
|
from pottery.exceptions import ReleaseUnlockedLock
|
10
10
|
from redis.asyncio import Redis
|
11
11
|
|
12
12
|
from utilities.asyncio import loop_until_succeed, sleep_td, timeout_td
|
13
13
|
from utilities.contextlib import enhanced_async_context_manager
|
14
|
-
from utilities.functools import partial
|
15
14
|
from utilities.iterables import always_iterable
|
16
15
|
from utilities.logging import get_logger
|
17
|
-
from utilities.warnings import suppress_warnings
|
18
16
|
from utilities.whenever import MILLISECOND, SECOND, to_seconds
|
19
17
|
|
20
18
|
if TYPE_CHECKING:
|
@@ -72,10 +70,7 @@ async def try_yield_coroutine_looper(
|
|
72
70
|
throttle=throttle,
|
73
71
|
) as lock:
|
74
72
|
yield CoroutineLooper(lock=lock, logger=logger, sleep=sleep_error)
|
75
|
-
except
|
76
|
-
_YieldAccessUnableToAcquireLockError,
|
77
|
-
_YieldAccessAcquiredUnlockedLockError,
|
78
|
-
) as error:
|
73
|
+
except _YieldAccessUnableToAcquireLockError as error: # skipif-ci-and-not-linux
|
79
74
|
if logger is not None:
|
80
75
|
get_logger(logger=logger).info("%s", error)
|
81
76
|
async with nullcontext():
|
@@ -92,27 +87,14 @@ class CoroutineLooper:
|
|
92
87
|
|
93
88
|
async def __call__[**P](
|
94
89
|
self, func: Callable[P, Coro[None]], *args: P.args, **kwargs: P.kwargs
|
95
|
-
) ->
|
90
|
+
) -> bool:
|
96
91
|
def make_coro() -> Coro[None]:
|
97
92
|
return func(*args, **kwargs)
|
98
93
|
|
99
|
-
await loop_until_succeed(
|
100
|
-
make_coro,
|
94
|
+
return await loop_until_succeed(
|
95
|
+
make_coro, logger=self.logger, errors=ExtendUnlockedLock, sleep=self.sleep
|
101
96
|
)
|
102
97
|
|
103
|
-
def _error(self, error: Exception, /, *, func: Callable[[], Coro[None]]) -> None:
|
104
|
-
_ = error
|
105
|
-
if self.logger is not None:
|
106
|
-
coro = func()
|
107
|
-
name = coro.__name__ # skipif-ci-and-not-linux
|
108
|
-
with suppress_warnings(
|
109
|
-
message="coroutine '.*' was never awaited", category=RuntimeWarning
|
110
|
-
):
|
111
|
-
del coro
|
112
|
-
get_logger(logger=self.logger).error(
|
113
|
-
"Error running %r", name, exc_info=True
|
114
|
-
)
|
115
|
-
|
116
98
|
|
117
99
|
##
|
118
100
|
|
@@ -150,8 +132,6 @@ async def yield_access(
|
|
150
132
|
lock = await _get_first_available_lock(
|
151
133
|
key, locks, num=num, timeout=timeout_acquire, sleep=sleep
|
152
134
|
)
|
153
|
-
if (await lock.locked()) == 0.0: # pragma: no cover
|
154
|
-
raise _YieldAccessAcquiredUnlockedLockError(key=lock.key)
|
155
135
|
yield lock
|
156
136
|
finally: # skipif-ci-and-not-linux
|
157
137
|
await sleep_td(throttle)
|
@@ -175,9 +155,7 @@ async def _get_first_available_lock(
|
|
175
155
|
)
|
176
156
|
async with timeout_td(timeout, error=error): # skipif-ci-and-not-linux
|
177
157
|
while True:
|
178
|
-
if (
|
179
|
-
(result := await _get_first_available_lock_if_any(locks)) is not None
|
180
|
-
) and (await result.locked() > 0.0):
|
158
|
+
if (result := await _get_first_available_lock_if_any(locks)) is not None:
|
181
159
|
return result
|
182
160
|
await sleep_td(sleep)
|
183
161
|
|
@@ -215,13 +193,6 @@ class _YieldAccessUnableToAcquireLockError(YieldAccessError):
|
|
215
193
|
return f"Unable to acquire any 1 of {self.num} locks for {self.key!r} after {self.timeout}" # skipif-ci-and-not-linux
|
216
194
|
|
217
195
|
|
218
|
-
@dataclass(kw_only=True, slots=True)
|
219
|
-
class _YieldAccessAcquiredUnlockedLockError(YieldAccessError):
|
220
|
-
@override
|
221
|
-
def __str__(self) -> str:
|
222
|
-
return f"Acquired an unlocked lock {self.key!r}" # pragma: no cover
|
223
|
-
|
224
|
-
|
225
196
|
__all__ = [
|
226
197
|
"CoroutineLooper",
|
227
198
|
"YieldAccessError",
|
@@ -0,0 +1 @@
|
|
1
|
+
from __future__ import annotations
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_with/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.147.3 → dycw_utilities-0.148.0}/src/tests/modules/package_without/module_2.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|