From 7231bb1e0d6e3f8181ff37179e868b71002f7127 Mon Sep 17 00:00:00 2001 From: remimd Date: Fri, 9 Jan 2026 21:05:37 +0100 Subject: [PATCH] Add asyncsafe and threadsafe injection tests --- .github/workflows/ci.yml | 2 +- tests/test_inject.py | 42 +++++++++++++++++++++++++++++++++ uv.lock | 50 ++++++++++++++++++++-------------------- 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a41d69..7300622 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: ci: strategy: matrix: - python-version: ["3.12", "3.13", "3.14"] + python-version: ["3.12", "3.13", "3.14", "3.14t"] name: Continuous Integration ・ Python ${{ matrix.python-version }} runs-on: ubuntu-latest diff --git a/tests/test_inject.py b/tests/test_inject.py index 50a0942..f9d3076 100644 --- a/tests/test_inject.py +++ b/tests/test_inject.py @@ -1,7 +1,9 @@ from abc import ABC, abstractmethod +from concurrent.futures import Future, ThreadPoolExecutor from dataclasses import dataclass from typing import Annotated, Any, Optional, TypeVar, Union +import anyio import pytest from injection import inject, injectable @@ -294,3 +296,43 @@ def function(a: A): ... function() assert module.is_locked + + async def test_inject_with_async_singleton(self, module): + class Dependency: ... + + @module.singleton + async def dependency_factory() -> Dependency: + await anyio.sleep(0) + return Dependency() + + instances = [] + + @module.inject + async def append_dependency(dependency: Dependency): + instances.append(dependency) + + async with anyio.create_task_group() as task_group: + for _ in range(100): + task_group.start_soon(append_dependency) + + reference = instances[0] + for instance in instances: + assert instance is reference + + def test_inject_with_threadsafe(self, module): + @module.singleton + class Dependency: ... + + @module.inject(threadsafe=True) + def get_dependency(dependency: Dependency) -> Dependency: + return dependency + + futures: list[Future[Dependency]] = [] + + with ThreadPoolExecutor() as executor: + for _ in range(100): + futures.append(executor.submit(get_dependency)) + + reference = futures[0].result() + for future in futures: + assert future.result() is reference diff --git a/uv.lock b/uv.lock index 01c5627..b1ca1ea 100644 --- a/uv.lock +++ b/uv.lock @@ -1431,42 +1431,42 @@ wheels = [ [[package]] name = "uv" -version = "0.9.22" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a4/e1/298ce517fa2dbe54e0ec8e126c22fe66adedc3aaaba3e5d3c056d62a4d64/uv-0.9.22.tar.gz", hash = "sha256:41c73a4938818ede30e601cd0be87953e5c6a83dc4762e04e626f2eb9b240ebe", size = 3835119, upload-time = "2026-01-06T10:49:35.192Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/53/09/37811eeabacd13c7fe9b6604d967e417124794d42b45d8469d2f421edc10/uv-0.9.22-py3-none-linux_armv6l.whl", hash = "sha256:1f979c9d313b4616d9865859ef520bea5df0d4f15c57214589f5676fafa440c1", size = 21319484, upload-time = "2026-01-06T10:49:42.435Z" }, - { url = "https://files.pythonhosted.org/packages/5e/68/bb76c97c284ce7fb8efa868994c2510588faa7075e60d8865d1373e54b7b/uv-0.9.22-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b78f2605d65c4925631d891dec99b677b05f50c774dedc6ef8968039a5bcfdb0", size = 20446647, upload-time = "2026-01-06T10:49:13.942Z" }, - { url = "https://files.pythonhosted.org/packages/af/49/7230b1d56aeaee0eefd346a70f582463f11fb7036d2d020bcf68053bd994/uv-0.9.22-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2a4155cf7d0231d0adae94257ee10d70c57c2f592207536ddd55d924590a8c15", size = 18967861, upload-time = "2026-01-06T10:49:26.026Z" }, - { url = "https://files.pythonhosted.org/packages/70/cf/7b33e791c0cb63587bb1f03f067764fc681c0d1693a6b9a2670ef2f8a4e9/uv-0.9.22-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:0d8f007616cac5962620252b56a1d8224e9b2de566e78558efe04cc18526d507", size = 20807382, upload-time = "2026-01-06T10:49:28.37Z" }, - { url = "https://files.pythonhosted.org/packages/e3/72/5486eab5344a30257544b42dd15e85d5de2ff7fab952a7a6e21cc946efae/uv-0.9.22-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3b2bcce464186f8fafa3bf2aa5d82db4e3229366345399cc3f5bcafd616b8fe0", size = 20914561, upload-time = "2026-01-06T10:49:08.996Z" }, - { url = "https://files.pythonhosted.org/packages/90/67/974adc8fd1baace83efaa2409dd19e60accfbca25c473ed9af8e8188484d/uv-0.9.22-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3422b093b8e6e8de31261133b420c34dbef81f3fd1d82f787ac771b00b54adf8", size = 21996463, upload-time = "2026-01-06T10:49:16.587Z" }, - { url = "https://files.pythonhosted.org/packages/99/7a/ef06158af9141e3b526bcb84ecd84fd1eed7eabf64bc830f302796af8646/uv-0.9.22-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b807bafe6b65fc1fe9c65ffd0d4228db894872de96e7200c44943f24beb68931", size = 23547447, upload-time = "2026-01-06T10:49:44.84Z" }, - { url = "https://files.pythonhosted.org/packages/e4/d7/b7f389311777403ea5230eb816b2aca159980cb8a3de5b9adb53cf19aa2e/uv-0.9.22-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:369b55341c6236f42d8fc335876308e5c57c921850975b3019cc9f7ebbe31567", size = 23159198, upload-time = "2026-01-06T10:49:39.938Z" }, - { url = "https://files.pythonhosted.org/packages/e5/cc/64514ba1102f24cbcb6eed39b22fe6fd04297ce1068552ae3c5fae63725b/uv-0.9.22-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0cdc653fb601aa7f273242823fa93024f5fd319c66cdf22f36d784858493564c", size = 22147053, upload-time = "2026-01-06T10:49:19.094Z" }, - { url = "https://files.pythonhosted.org/packages/40/15/63fb7a6908db2f03716c4a50aea7e27a7440fe6a09854282c401139afaf7/uv-0.9.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f45e1e0f26dd47fa01eb421c54cfd39de10fd52ac0a9d7ae45b92fce7d92b0b", size = 22225812, upload-time = "2026-01-06T10:49:48.109Z" }, - { url = "https://files.pythonhosted.org/packages/ea/fe/def406c118ac215f4c392b077fb75303d125310cf178774a728e5759d9eb/uv-0.9.22-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:8f73043ade8ff6335e19fe1f4e7425d5e28aec9cafd72d13d5b40bb1cbb85690", size = 20933749, upload-time = "2026-01-06T10:49:23.817Z" }, - { url = "https://files.pythonhosted.org/packages/7f/45/27464cf8697f31858084c9c3f716b3c39d3f9a2a8e30c8a58dbd1a519e24/uv-0.9.22-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:59c4f6b3659a68c26c50865432a7134386f607432160aad51e2247f862902697", size = 22080639, upload-time = "2026-01-06T10:49:21.521Z" }, - { url = "https://files.pythonhosted.org/packages/1c/9a/7008f6aad89442ef00735b4f4c8d86eaaeaa7392f4dec814469d212eb462/uv-0.9.22-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:77ec4c101d41d7738226466191a7d62f9fa4de06ea580e0801da2f5cd5fa08aa", size = 20894483, upload-time = "2026-01-06T10:49:37.201Z" }, - { url = "https://files.pythonhosted.org/packages/fe/97/74b4c782d410e5f891446d1d27107b0312fae0e83c7be2edf6867c408f81/uv-0.9.22-py3-none-musllinux_1_1_i686.whl", hash = "sha256:b1985559b38663642658069e8d09fa6c30ed1c67654b7e5765240d9e4e9cdd57", size = 21453244, upload-time = "2026-01-06T10:49:52.878Z" }, - { url = "https://files.pythonhosted.org/packages/01/17/b3055b9f82f87a727ed5f745aadda9c363d2e2dd180f99350431e98c0ad4/uv-0.9.22-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:e4b61a9c8b8dcbf64e642d2052342d36a46886b8bc3ccc407282962b970101af", size = 22446527, upload-time = "2026-01-06T10:49:50.59Z" }, - { url = "https://files.pythonhosted.org/packages/2d/39/03ed466a5afb8bfc104096bb577b26ed7e413177fee699c756916ab35ef5/uv-0.9.22-py3-none-win32.whl", hash = "sha256:d9d4be990bb92a68781f7c98d2321b528667b61d565c02ba978488c0210aa768", size = 20088632, upload-time = "2026-01-06T10:49:11.725Z" }, - { url = "https://files.pythonhosted.org/packages/32/49/9e3e19ba756c4a5e6acb4ea74336d3035f7959254fbb05f5eb77bff067ed/uv-0.9.22-py3-none-win_amd64.whl", hash = "sha256:9c238525272506845fe07c0b9088c5e33fcd738e1f49ef49dc3c8112096d2e3a", size = 22160389, upload-time = "2026-01-06T10:49:32.826Z" }, - { url = "https://files.pythonhosted.org/packages/79/78/4a10b718290eb6b9ab436286420c430f9ad7afa0c1b03c43692d6289fe2f/uv-0.9.22-py3-none-win_arm64.whl", hash = "sha256:012bdc5285a9cdb091ac514b7eb8a707e3b649af5355fe4afb4920bfe1958c00", size = 20556116, upload-time = "2026-01-06T10:49:30.493Z" }, +version = "0.9.23" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3b/21fe8951468c355fa4bfc7fc5d1c97f4bf414d29bf9308eb7781083ed084/uv-0.9.23.tar.gz", hash = "sha256:9bfa6816d76119ad3e6a97c9d1cb2022a166af31cd442bd4e42f674c8f9ab87d", size = 3852934, upload-time = "2026-01-09T19:46:06.417Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/b9/83bd7a85e0187ebbf5ae7e5dbb6c20581579fac5062073fc191ba7ae90e2/uv-0.9.23-py3-none-linux_armv6l.whl", hash = "sha256:1822c0e8bd15d2d377aa06360885262ad569547611078e2d83cc9a3cb57b72a9", size = 21407564, upload-time = "2026-01-09T19:45:15.468Z" }, + { url = "https://files.pythonhosted.org/packages/29/99/e430e0cee02815eafb22ad2f35ffa4ade975b0dc4819eb804bc6efa2d2aa/uv-0.9.23-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f5ca37e98ed8a8f7e8b6bb94758981f92e5e996cc3c32b3f718e82405fc4726e", size = 20568405, upload-time = "2026-01-09T19:45:25.397Z" }, + { url = "https://files.pythonhosted.org/packages/6f/11/cea89a5edbb6af28ac64114dc25abdc2d9ea81b5673207e499bef839cfeb/uv-0.9.23-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a4406c03091586fe7a00d7b0d03f5f6b5f73b5a62fd555ccb9ddd5346626dc43", size = 19014722, upload-time = "2026-01-09T19:45:52.568Z" }, + { url = "https://files.pythonhosted.org/packages/a8/26/d38ff6987aa971b8fbee036a356083bd9fd6605ac20cebc1fcc6dbff38b6/uv-0.9.23-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:afbcb83949b180236024b546ca93a0068336e8b3ccebb28d2721a14bb933dd8c", size = 20893728, upload-time = "2026-01-09T19:45:29.075Z" }, + { url = "https://files.pythonhosted.org/packages/00/68/0eb2740ec2357d5e7b44eb5d33a02e4f8d74fc41ee6ff4b93f7a77f726b8/uv-0.9.23-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f4556bf96b54a5673b88178054c1c8d6e39d1f2642590677c777b4d121fa96e1", size = 21032944, upload-time = "2026-01-09T19:45:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/d2/69/11418b991ea3fc4d555d352e27204e8e2ce67cc6b64a7708f3821693de37/uv-0.9.23-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c77f9a44d4d7333ae264c3810e52882b0877d90c66af43b42d73e38a1158fde1", size = 21952078, upload-time = "2026-01-09T19:46:03.957Z" }, + { url = "https://files.pythonhosted.org/packages/86/35/c7c7e1b05efc2b6122f14de18cd0691a64c8a30fd44a0ec0bdc25887b156/uv-0.9.23-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f5a9fe2b472628c239d56765786b79b894d37ace334a0868c158795fa0c9d454", size = 23645955, upload-time = "2026-01-09T19:45:11.959Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c1/51a60b7c0172b5d4f29e605fe54c5fe43db16d055285cd3414d2ad1cee5f/uv-0.9.23-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:940c4f88dadb91910f2643f71a83ec7700359a43e77a1e08731acbb70654f15b", size = 23231613, upload-time = "2026-01-09T19:45:36.141Z" }, + { url = "https://files.pythonhosted.org/packages/5e/75/61da4afd9b838fbfad24f5abf826e1e73b047ae975c0b4c52d11b129015f/uv-0.9.23-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af33450dd4d4b1544f6872725e666177a77751b2c7490998688210743a5b44ec", size = 22277438, upload-time = "2026-01-09T19:45:21.978Z" }, + { url = "https://files.pythonhosted.org/packages/ea/4a/9bba41dfe207c4083de036fdf08d4db779faf1bc05b00e86cb06a5d4d97a/uv-0.9.23-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:645ef5a067340320722b84c2abdd21587bda15be39e7ebf88ae5ace2be6fb192", size = 22326761, upload-time = "2026-01-09T19:45:56.143Z" }, + { url = "https://files.pythonhosted.org/packages/a8/97/111edb3b979f5a4433e040fad7033853408d8d0d8d7f98a9976984f77fb9/uv-0.9.23-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:4c5e4af9ec5450d75807b13d70bd7f57a19bad22dc8a2ddf313bddad5f672ea8", size = 21008087, upload-time = "2026-01-09T19:45:00.787Z" }, + { url = "https://files.pythonhosted.org/packages/53/ed/801df59697a18c5dda3c88b9323a06543bb1c5d15e46012d5c579afd0e72/uv-0.9.23-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5d97f91d49c95561dc16b2290f8ec34f5f7d22f8a81935b0c798ec053a164bdf", size = 22162896, upload-time = "2026-01-09T19:45:32.642Z" }, + { url = "https://files.pythonhosted.org/packages/ab/fe/413233c15f1e7dece47fabf5809f98f851a6c1dd72ae717bf26e86d5ceb7/uv-0.9.23-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:5d7e9a9e54510fdd3ad0ff94eda1bb13eb1fd3c33905e45228195b265c449b0f", size = 20991335, upload-time = "2026-01-09T19:45:42.065Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b8/79ce50366ff480879e6052c906c6bd48a70ea47f691ef9e7f13686b4d361/uv-0.9.23-py3-none-musllinux_1_1_i686.whl", hash = "sha256:e039205eef9cb91ff925da4f7d7507cf630c24b7fd043352a33d19cc9790f9f8", size = 21407799, upload-time = "2026-01-09T19:45:08.36Z" }, + { url = "https://files.pythonhosted.org/packages/da/5e/1ceeef97798d61497f7fe064eb7584cd26a24ca89ec95bb3a797ecad648e/uv-0.9.23-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:6391fab501516966dca12b14d6008201df47734c0d4b949602af9fc2e110e7e7", size = 22537456, upload-time = "2026-01-09T19:45:49.242Z" }, + { url = "https://files.pythonhosted.org/packages/17/a4/cafa5146cbedd90afc52b39edf591bac266e1a4f576180eb3cdb76fe6615/uv-0.9.23-py3-none-win32.whl", hash = "sha256:6de8501557603a672efb4ff7429e89e2d45a32ecd7f6b017544335b22da12423", size = 20213704, upload-time = "2026-01-09T19:45:45.736Z" }, + { url = "https://files.pythonhosted.org/packages/b7/9e/738c62166050f534d6620c3dc26066a4419b79e4aeac988b532d14169afd/uv-0.9.23-py3-none-win_amd64.whl", hash = "sha256:6091a85084ec882db9ebf84503a405a2e20da73fcbb7ad3697668e9f198cb167", size = 22292514, upload-time = "2026-01-09T19:46:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/14/84/830eb6bb16fc1320093e90be8ce06a09f85a78dc08c0e912a318cd9ad9c5/uv-0.9.23-py3-none-win_arm64.whl", hash = "sha256:097be29902bb8e58cde8f02f09e0679ac04e9736605d6d8caa2ecb0d0aadb49c", size = 20603593, upload-time = "2026-01-09T19:45:18.768Z" }, ] [[package]] name = "virtualenv" -version = "20.36.0" +version = "20.36.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/49/87e23d8f742f10f965bce5d6b285fc88a4f436b11daf6b6225d4d66f8492/virtualenv-20.36.0.tar.gz", hash = "sha256:a3601f540b515a7983508113f14e78993841adc3d83710fa70f0ac50f43b23ed", size = 6032237, upload-time = "2026-01-07T17:20:04.975Z" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/a3/4d310fa5f00863544e1d0f4de93bddec248499ccf97d4791bc3122c9d4f3/virtualenv-20.36.1.tar.gz", hash = "sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba", size = 6032239, upload-time = "2026-01-09T18:21:01.296Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/6a/0af36875e0023a1f2d0b66b4051721fc26740e947696922df1665b75e5d3/virtualenv-20.36.0-py3-none-any.whl", hash = "sha256:e7ded577f3af534fd0886d4ca03277f5542053bedb98a70a989d3c22cfa5c9ac", size = 6008261, upload-time = "2026-01-07T17:20:02.87Z" }, + { url = "https://files.pythonhosted.org/packages/6a/2a/dc2228b2888f51192c7dc766106cd475f1b768c10caaf9727659726f7391/virtualenv-20.36.1-py3-none-any.whl", hash = "sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f", size = 6008258, upload-time = "2026-01-09T18:20:59.425Z" }, ] [[package]]