dycw-utilities 0.123.0__tar.gz → 0.124.1__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.123.0 → dycw_utilities-0.124.1}/PKG-INFO +3 -3
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/pyproject.toml +5 -5
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_asyncio.py +119 -61
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_more_itertools.py +29 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_redis.py +2 -2
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_sqlalchemy.py +1 -1
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/asyncio.py +179 -41
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/more_itertools.py +62 -6
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/redis.py +2 -2
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/slack_sdk.py +6 -10
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/sqlalchemy.py +2 -1
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/.gitignore +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/LICENSE +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/README.md +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_astor.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_datetime.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_git.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_loguru.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_luigi.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_math.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_period.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_polars.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pydantic.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pyrsistent.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_python_dotenv.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_rich.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_statsmodel.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_streamlit.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_sys.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_tenacity.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/__init__.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/chain.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/decorated_async.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/decorated_sync.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/error_bind.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/many.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/one.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/recursive.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/task_group_one.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/task_group_two.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/two.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_traceback_funcs/untraced.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/astor.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/click.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/datetime.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/git.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/http.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/loguru.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/luigi.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/math.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/os.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/period.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pyrsistent.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/python_dotenv.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/random.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/re.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/rich.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/streamlit.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/sys.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/tenacity.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/text.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/types.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/version.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.123.0 → dycw_utilities-0.124.1}/src/utilities/zoneinfo.py +0 -0
@@ -1,12 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dycw-utilities
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.124.1
|
4
4
|
Author-email: Derek Wan <d.wan@icloud.com>
|
5
5
|
License-File: LICENSE
|
6
6
|
Requires-Python: >=3.12
|
7
7
|
Requires-Dist: typing-extensions<4.14,>=4.13.1
|
8
8
|
Provides-Extra: test
|
9
|
-
Requires-Dist: hypothesis<6.132,>=6.131.
|
9
|
+
Requires-Dist: hypothesis<6.132,>=6.131.24; extra == 'test'
|
10
10
|
Requires-Dist: pytest-asyncio<0.27,>=0.26.0; extra == 'test'
|
11
11
|
Requires-Dist: pytest-cov<6.2,>=6.1.1; extra == 'test'
|
12
12
|
Requires-Dist: pytest-instafail<0.6,>=0.5.0; extra == 'test'
|
@@ -80,7 +80,7 @@ Provides-Extra: zzz-test-hypothesis
|
|
80
80
|
Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
|
81
81
|
Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
|
82
82
|
Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
|
83
|
-
Requires-Dist: hypothesis<6.132,>=6.131.
|
83
|
+
Requires-Dist: hypothesis<6.132,>=6.131.24; extra == 'zzz-test-hypothesis'
|
84
84
|
Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
|
85
85
|
Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-hypothesis'
|
86
86
|
Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
|
@@ -26,7 +26,7 @@ dev = [
|
|
26
26
|
"fpdf2 >= 2.8.3, < 2.9",
|
27
27
|
"greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
|
28
28
|
"httpx >= 0.28.1, < 0.29", # for fastapi
|
29
|
-
"hypothesis >= 6.131.
|
29
|
+
"hypothesis >= 6.131.24, < 6.132",
|
30
30
|
"img2pdf >= 0.6.0, < 0.7",
|
31
31
|
"lightweight-charts >= 2.1, < 2.2",
|
32
32
|
"loguru >= 0.7.3, < 0.8",
|
@@ -92,11 +92,11 @@ dependencies = [
|
|
92
92
|
name = "dycw-utilities"
|
93
93
|
readme = "README.md"
|
94
94
|
requires-python = ">= 3.12"
|
95
|
-
version = "0.
|
95
|
+
version = "0.124.1"
|
96
96
|
|
97
97
|
[project.optional-dependencies]
|
98
98
|
test = [
|
99
|
-
"hypothesis >= 6.131.
|
99
|
+
"hypothesis >= 6.131.24, < 6.132",
|
100
100
|
"pytest >= 8.3.5, < 8.4",
|
101
101
|
"pytest-asyncio >= 0.26.0, < 0.27",
|
102
102
|
"pytest-cov >= 6.1.1, < 6.2",
|
@@ -174,7 +174,7 @@ zzz-test-hypothesis = [
|
|
174
174
|
"aiosqlite >= 0.21.0, < 0.22",
|
175
175
|
"asyncpg >= 0.30.0, < 0.31", # for sqlalchemy async
|
176
176
|
"greenlet >= 3.2.0, < 3.3", # for sqlalchemy async
|
177
|
-
"hypothesis >= 6.131.
|
177
|
+
"hypothesis >= 6.131.24, < 6.132",
|
178
178
|
"luigi >= 3.6.0, < 3.7",
|
179
179
|
"numpy >= 2.2.6, < 2.3",
|
180
180
|
"pathvalidate >= 3.2.3, < 3.3",
|
@@ -334,7 +334,7 @@ zzz-test-zoneinfo = [
|
|
334
334
|
# bump-my-version
|
335
335
|
[tool.bumpversion]
|
336
336
|
allow_dirty = true
|
337
|
-
current_version = "0.
|
337
|
+
current_version = "0.124.1"
|
338
338
|
|
339
339
|
[[tool.bumpversion.files]]
|
340
340
|
filename = "src/utilities/__init__.py"
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from asyncio import CancelledError, Event, Queue,
|
3
|
+
from asyncio import CancelledError, Event, Queue, run, sleep
|
4
|
+
from collections import deque
|
4
5
|
from contextlib import asynccontextmanager
|
5
6
|
from dataclasses import dataclass, field
|
6
7
|
from functools import partial
|
@@ -8,9 +9,10 @@ from itertools import chain, count
|
|
8
9
|
from re import search
|
9
10
|
from typing import TYPE_CHECKING, Any, ClassVar, Self, cast, override
|
10
11
|
|
11
|
-
from hypothesis import HealthCheck, Phase, given, settings
|
12
|
+
from hypothesis import HealthCheck, Phase, assume, given, settings
|
12
13
|
from hypothesis.strategies import (
|
13
14
|
DataObject,
|
15
|
+
booleans,
|
14
16
|
data,
|
15
17
|
integers,
|
16
18
|
just,
|
@@ -22,6 +24,7 @@ from hypothesis.strategies import (
|
|
22
24
|
from pytest import LogCaptureFixture, mark, param, raises
|
23
25
|
|
24
26
|
from utilities.asyncio import (
|
27
|
+
EnhancedQueue,
|
25
28
|
EnhancedTaskGroup,
|
26
29
|
InfiniteLooper,
|
27
30
|
InfiniteQueueLooper,
|
@@ -65,6 +68,77 @@ if TYPE_CHECKING:
|
|
65
68
|
)
|
66
69
|
|
67
70
|
|
71
|
+
class TestEnhancedQueue:
|
72
|
+
@given(
|
73
|
+
xs=lists(integers()),
|
74
|
+
wait=booleans(),
|
75
|
+
put_all=booleans(),
|
76
|
+
get_reverse=booleans(),
|
77
|
+
)
|
78
|
+
async def test_left(
|
79
|
+
self, *, xs: list[int], wait: int, put_all: bool, get_reverse: bool
|
80
|
+
) -> None:
|
81
|
+
_ = assume(not ((len(xs) == 0) and wait))
|
82
|
+
deq: deque[int] = deque()
|
83
|
+
for x in xs:
|
84
|
+
deq.appendleft(x)
|
85
|
+
queue: EnhancedQueue[int] = EnhancedQueue()
|
86
|
+
if put_all:
|
87
|
+
if wait:
|
88
|
+
await queue.put_left(*xs)
|
89
|
+
else:
|
90
|
+
queue.put_left_nowait(*xs)
|
91
|
+
else:
|
92
|
+
for i, x in enumerate(xs, start=1):
|
93
|
+
if wait:
|
94
|
+
await queue.put_left(x)
|
95
|
+
else:
|
96
|
+
queue.put_left_nowait(x)
|
97
|
+
assert queue.qsize() == i
|
98
|
+
assert list(deq) == xs[::-1]
|
99
|
+
if wait:
|
100
|
+
res = await queue.get_all(reverse=get_reverse)
|
101
|
+
else:
|
102
|
+
res = queue.get_all_nowait(reverse=get_reverse)
|
103
|
+
expected = xs if get_reverse else xs[::-1]
|
104
|
+
assert res == expected
|
105
|
+
|
106
|
+
@given(
|
107
|
+
xs=lists(integers()),
|
108
|
+
wait=booleans(),
|
109
|
+
put_all=booleans(),
|
110
|
+
get_reverse=booleans(),
|
111
|
+
)
|
112
|
+
async def test_right(
|
113
|
+
self, *, xs: list[int], wait: int, put_all: bool, get_reverse: bool
|
114
|
+
) -> None:
|
115
|
+
_ = assume(not ((len(xs) == 0) and wait))
|
116
|
+
deq: deque[int] = deque()
|
117
|
+
for x in xs:
|
118
|
+
deq.append(x)
|
119
|
+
queue: EnhancedQueue[int] = EnhancedQueue()
|
120
|
+
if put_all:
|
121
|
+
if wait:
|
122
|
+
await queue.put_right(*xs)
|
123
|
+
else:
|
124
|
+
queue.put_right_nowait(*xs)
|
125
|
+
assert queue.qsize() == len(xs)
|
126
|
+
else:
|
127
|
+
for i, x in enumerate(xs, start=1):
|
128
|
+
if wait:
|
129
|
+
await queue.put_right(x)
|
130
|
+
else:
|
131
|
+
queue.put_right_nowait(x)
|
132
|
+
assert queue.qsize() == i
|
133
|
+
assert list(deq) == xs
|
134
|
+
if wait:
|
135
|
+
res = await queue.get_all(reverse=get_reverse)
|
136
|
+
else:
|
137
|
+
res = queue.get_all_nowait(reverse=get_reverse)
|
138
|
+
expected = xs[::-1] if get_reverse else xs
|
139
|
+
assert res == expected
|
140
|
+
|
141
|
+
|
68
142
|
class TestEnhancedTaskGroup:
|
69
143
|
async def test_create_task_context_coroutine(self) -> None:
|
70
144
|
flag: bool = False
|
@@ -175,6 +249,24 @@ class TestGetEvent:
|
|
175
249
|
assert get_event(event=lambda: event) is event
|
176
250
|
|
177
251
|
|
252
|
+
class TestGetItems:
|
253
|
+
@given(
|
254
|
+
xs=lists(integers(), min_size=1),
|
255
|
+
max_size=integers(1, 10) | none(),
|
256
|
+
wait=booleans(),
|
257
|
+
)
|
258
|
+
async def test_main(
|
259
|
+
self, *, xs: list[int], max_size: int | None, wait: bool
|
260
|
+
) -> None:
|
261
|
+
queue: Queue[int] = Queue()
|
262
|
+
put_items_nowait(xs, queue)
|
263
|
+
if wait:
|
264
|
+
result = await get_items(queue, max_size=max_size)
|
265
|
+
else:
|
266
|
+
result = get_items_nowait(queue, max_size=max_size)
|
267
|
+
assert result == xs[:max_size]
|
268
|
+
|
269
|
+
|
178
270
|
class TestInfiniteLooper:
|
179
271
|
sleep_restart_cases: ClassVar[list[Any]] = [
|
180
272
|
param(60.0, "for 0:01:00"),
|
@@ -386,9 +478,9 @@ class TestInfiniteLooper:
|
|
386
478
|
Example(sleep_core=0.05, sleep_restart=0.05) as looper,
|
387
479
|
):
|
388
480
|
...
|
389
|
-
assert
|
390
|
-
assert 0 <= looper.counter <=
|
391
|
-
assert
|
481
|
+
assert 3 <= looper.initializations <= 7
|
482
|
+
assert 0 <= looper.counter <= 8
|
483
|
+
assert 13 <= external <= 22
|
392
484
|
|
393
485
|
async def test_with_coroutine_self_error(self) -> None:
|
394
486
|
class CustomError(Exception): ...
|
@@ -661,13 +753,13 @@ class TestInfiniteQueueLooper:
|
|
661
753
|
counter: int = 0
|
662
754
|
|
663
755
|
@override
|
664
|
-
async def
|
665
|
-
self.counter += len(
|
756
|
+
async def _process_queue(self) -> None:
|
757
|
+
self.counter += len(self._queue.get_all_nowait())
|
666
758
|
|
667
759
|
async with timeout_dur(duration=1.0), Example(sleep_core=0.05) as looper:
|
668
760
|
await sleep(0.1)
|
669
761
|
for i in range(10):
|
670
|
-
looper.
|
762
|
+
looper.put_right_nowait(i)
|
671
763
|
await sleep(0.05)
|
672
764
|
|
673
765
|
assert looper.counter == 10
|
@@ -678,13 +770,13 @@ class TestInfiniteQueueLooper:
|
|
678
770
|
output: set[int] = field(default_factory=set)
|
679
771
|
|
680
772
|
@override
|
681
|
-
async def
|
682
|
-
self.output.update(
|
773
|
+
async def _process_queue(self) -> None:
|
774
|
+
self.output.update(self._queue.get_all_nowait())
|
683
775
|
|
684
776
|
looper = Example(sleep_core=0.05)
|
685
777
|
assert len(looper) == 0
|
686
778
|
assert looper.empty()
|
687
|
-
looper.
|
779
|
+
looper.put_right_nowait(*range(n))
|
688
780
|
assert len(looper) == n
|
689
781
|
assert not looper.empty()
|
690
782
|
|
@@ -694,11 +786,11 @@ class TestInfiniteQueueLooper:
|
|
694
786
|
output: set[int] = field(default_factory=set)
|
695
787
|
|
696
788
|
@override
|
697
|
-
async def
|
698
|
-
self.output.update(
|
789
|
+
async def _process_queue(self) -> None:
|
790
|
+
self.output.update(self._queue.get_all_nowait())
|
699
791
|
|
700
792
|
looper = Example(sleep_core=0.05)
|
701
|
-
looper.
|
793
|
+
looper.put_right_nowait(*range(10))
|
702
794
|
async with looper:
|
703
795
|
await looper.run_until_empty()
|
704
796
|
assert looper.empty()
|
@@ -715,66 +807,32 @@ class TestInfiniteQueueLooper:
|
|
715
807
|
output: set[int] = field(default_factory=set)
|
716
808
|
|
717
809
|
@override
|
718
|
-
async def
|
719
|
-
raise CustomError
|
810
|
+
async def _process_queue(self) -> None:
|
811
|
+
raise CustomError
|
720
812
|
|
721
813
|
async with (
|
722
814
|
timeout_dur(duration=1.0),
|
723
815
|
Example(sleep_core=0.05, logger=logger) as looper,
|
724
816
|
):
|
725
|
-
looper.
|
817
|
+
looper.put_left_nowait(1)
|
726
818
|
if logger is not None:
|
727
819
|
message = caplog.messages[0]
|
728
|
-
expected = "'Example' encountered CustomError(
|
820
|
+
expected = "'Example' encountered 'CustomError()'; sleeping for 0:01:00..."
|
729
821
|
assert message == expected
|
730
822
|
|
731
823
|
|
732
|
-
class
|
733
|
-
@given(xs=lists(integers(), min_size=1),
|
734
|
-
async def
|
824
|
+
class TestPutItems:
|
825
|
+
@given(xs=lists(integers(), min_size=1), wait=booleans())
|
826
|
+
async def test_main(self, *, xs: list[int], wait: bool) -> None:
|
735
827
|
queue: Queue[int] = Queue()
|
736
|
-
|
737
|
-
|
738
|
-
if max_size is None:
|
739
|
-
assert result == xs
|
828
|
+
if wait:
|
829
|
+
put_items_nowait(xs, queue)
|
740
830
|
else:
|
741
|
-
assert result == xs[:max_size]
|
742
|
-
|
743
|
-
@given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
|
744
|
-
async def test_get_then_put(self, *, xs: list[int], max_size: int | None) -> None:
|
745
|
-
queue: Queue[int] = Queue()
|
746
|
-
|
747
|
-
async def put() -> None:
|
748
|
-
await sleep(0.01)
|
749
831
|
await put_items(xs, queue)
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
result = task.result()
|
755
|
-
if max_size is None:
|
756
|
-
assert result == xs
|
757
|
-
else:
|
758
|
-
assert result == xs[:max_size]
|
759
|
-
|
760
|
-
async def test_empty(self) -> None:
|
761
|
-
queue: Queue[int] = Queue()
|
762
|
-
with raises(TimeoutError): # noqa: PT012
|
763
|
-
async with timeout(0.01), TaskGroup() as tg:
|
764
|
-
_ = tg.create_task(get_items(queue))
|
765
|
-
_ = tg.create_task(sleep(0.02))
|
766
|
-
|
767
|
-
|
768
|
-
class TestPutAndGetItemsNoWait:
|
769
|
-
@given(xs=lists(integers(), min_size=1), max_size=integers(1, 10) | none())
|
770
|
-
def test_main(self, *, xs: list[int], max_size: int | None) -> None:
|
771
|
-
queue: Queue[int] = Queue()
|
772
|
-
put_items_nowait(xs, queue)
|
773
|
-
result = get_items_nowait(queue, max_size=max_size)
|
774
|
-
if max_size is None:
|
775
|
-
assert result == xs
|
776
|
-
else:
|
777
|
-
assert result == xs[:max_size]
|
832
|
+
result: list[int] = []
|
833
|
+
while not queue.empty():
|
834
|
+
result.append(await queue.get())
|
835
|
+
assert result == xs
|
778
836
|
|
779
837
|
|
780
838
|
class TestUniquePriorityQueue:
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
from collections.abc import Iterator
|
3
4
|
from typing import TYPE_CHECKING, Any, ClassVar, TypeGuard
|
4
5
|
|
5
6
|
from pytest import mark, param, raises
|
@@ -24,17 +25,45 @@ class TestBucketMapping:
|
|
24
25
|
def test_main(self) -> None:
|
25
26
|
mapping = bucket_mapping(self.iterable, lambda x: x[0])
|
26
27
|
assert set(mapping) == {"a", "b", "c"}
|
28
|
+
for value in mapping.values():
|
29
|
+
assert isinstance(value, Iterator)
|
30
|
+
assert not isinstance(value, list)
|
27
31
|
assert list(mapping["a"]) == ["a1", "a2"]
|
28
32
|
assert list(mapping["b"]) == ["b1", "b2", "b3"]
|
29
33
|
assert list(mapping["c"]) == ["c1", "c2"]
|
30
34
|
|
35
|
+
def test_transform(self) -> None:
|
36
|
+
mapping = bucket_mapping(
|
37
|
+
self.iterable, lambda x: x[0], transform=lambda x: int(x[-1])
|
38
|
+
)
|
39
|
+
assert set(mapping) == {"a", "b", "c"}
|
40
|
+
for value in mapping.values():
|
41
|
+
assert isinstance(value, Iterator)
|
42
|
+
assert not isinstance(value, list)
|
43
|
+
assert list(mapping["a"]) == [1, 2]
|
44
|
+
assert list(mapping["b"]) == [1, 2, 3]
|
45
|
+
assert list(mapping["c"]) == [1, 2]
|
46
|
+
|
31
47
|
def test_list(self) -> None:
|
32
48
|
mapping = bucket_mapping(self.iterable, lambda x: x[0], list=True)
|
33
49
|
assert set(mapping) == {"a", "b", "c"}
|
50
|
+
for value in mapping.values():
|
51
|
+
assert isinstance(value, list)
|
34
52
|
assert mapping["a"] == ["a1", "a2"]
|
35
53
|
assert mapping["b"] == ["b1", "b2", "b3"]
|
36
54
|
assert mapping["c"] == ["c1", "c2"]
|
37
55
|
|
56
|
+
def test_transform_and_list(self) -> None:
|
57
|
+
mapping = bucket_mapping(
|
58
|
+
self.iterable, lambda x: x[0], transform=lambda x: int(x[-1]), list=True
|
59
|
+
)
|
60
|
+
assert set(mapping) == {"a", "b", "c"}
|
61
|
+
for value in mapping.values():
|
62
|
+
assert isinstance(value, list)
|
63
|
+
assert mapping["a"] == [1, 2]
|
64
|
+
assert mapping["b"] == [1, 2, 3]
|
65
|
+
assert mapping["c"] == [1, 2]
|
66
|
+
|
38
67
|
|
39
68
|
class TestPartitionList:
|
40
69
|
def test_main(self) -> None:
|
@@ -150,7 +150,7 @@ class TestPublisher:
|
|
150
150
|
|
151
151
|
async def sleep_then_put() -> None:
|
152
152
|
await sleep(0.1)
|
153
|
-
publisher.
|
153
|
+
publisher.put_right_nowait((channel, obj))
|
154
154
|
|
155
155
|
with raises(ExceptionGroup): # noqa: PT012
|
156
156
|
async with EnhancedTaskGroup(timeout=1.0) as tg:
|
@@ -187,7 +187,7 @@ class TestPublisher:
|
|
187
187
|
|
188
188
|
async def sleep_then_put() -> None:
|
189
189
|
await sleep(0.1)
|
190
|
-
publisher.
|
190
|
+
publisher.put_right_nowait((channel, text))
|
191
191
|
|
192
192
|
with raises(ExceptionGroup): # noqa: PT012
|
193
193
|
async with EnhancedTaskGroup(timeout=1.0) as tg:
|
@@ -1169,7 +1169,7 @@ class TestUpserter:
|
|
1169
1169
|
engine = await sqlalchemy_engines(data, table)
|
1170
1170
|
pairs = [(id_, init) for id_, init, _ in triples]
|
1171
1171
|
async with Upserter(duration=1.0, sleep_core=0.1, engine=engine) as upserter:
|
1172
|
-
upserter.
|
1172
|
+
upserter.put_right_nowait((pairs, table))
|
1173
1173
|
|
1174
1174
|
sel = select(table)
|
1175
1175
|
async with engine.begin() as conn:
|