diff --git a/.gitattributes b/.gitattributes index 7c22901f765..68c97b74c3d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -**/pinned-requirements.txt linguist-generated=true +**/pinned-requirements*.txt linguist-generated=true diff --git a/Makefile b/Makefile index 2d76f8e9549..d6dd32cd6ca 100644 --- a/Makefile +++ b/Makefile @@ -131,6 +131,7 @@ update-gateways-envoy: generate-pip-lockfiles: ./generate-pip-lockfile.sh hail/python/hailtop ./generate-pip-lockfile.sh hail/python + uv pip compile --python-version 3.10 --python-platform linux --upgrade hail/python/requirements.txt --output-file=hail/python/pinned-requirements-py310.txt ./generate-pip-lockfile.sh hail/python/dev ./generate-pip-lockfile.sh gear ./generate-pip-lockfile.sh web_common diff --git a/auth/test/pytest.ini b/auth/test/pytest.ini index af2398e723d..cc3d4277380 100644 --- a/auth/test/pytest.ini +++ b/auth/test/pytest.ini @@ -1,5 +1,7 @@ [pytest] asyncio_mode = auto +asyncio_default_fixture_loop_scope = session +asyncio_default_test_loop_scope = session addopts = --strict-markers markers = unchecked_allocator: tests that use the unchecked allocator diff --git a/batch/pinned-requirements.txt b/batch/pinned-requirements.txt index 71cdf516ec6..333ab41b23a 100644 --- a/batch/pinned-requirements.txt +++ b/batch/pinned-requirements.txt @@ -1,8 +1,8 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python-version 3.10 --python-platform linux batch/requirements.txt --output-file=batch/pinned-requirements.txt +# uv pip compile --python-version 3.11 --python-platform linux batch/requirements.txt --output-file=batch/pinned-requirements.txt aiodocker==0.27.0 # via -r batch/requirements.txt -aiohappyeyeballs==2.6.2 +aiohappyeyeballs==2.7.1 # via # -c batch/../gear/pinned-requirements.txt # -c batch/../hail/python/dev/pinned-requirements.txt @@ -26,13 +26,7 @@ aiosignal==1.4.0 # -c batch/../web_common/pinned-requirements.txt # aiohttp async-timeout==5.0.1 - # via - # -c batch/../gear/pinned-requirements.txt - # -c batch/../hail/python/dev/pinned-requirements.txt - # -c batch/../hail/python/pinned-requirements.txt - # -c batch/../web_common/pinned-requirements.txt - # -r batch/requirements.txt - # aiohttp + # via -r batch/requirements.txt attrs==26.1.0 # via # -c batch/../gear/pinned-requirements.txt @@ -46,13 +40,13 @@ certifi==2026.6.17 # -c batch/../hail/python/dev/pinned-requirements.txt # -c batch/../hail/python/pinned-requirements.txt # requests -cffi==2.0.0 +cffi==2.1.0 # via # -c batch/../gear/pinned-requirements.txt # -c batch/../hail/python/dev/pinned-requirements.txt # -c batch/../hail/python/pinned-requirements.txt # cryptography -charset-normalizer==3.4.7 +charset-normalizer==3.4.9 # via # -c batch/../gear/pinned-requirements.txt # -c batch/../hail/python/dev/pinned-requirements.txt @@ -78,7 +72,7 @@ google-api-core==2.31.0 # -c batch/../gear/pinned-requirements.txt # google-cloud-core # google-cloud-storage -google-auth==2.55.1 +google-auth==2.56.0 # via # -c batch/../gear/pinned-requirements.txt # -c batch/../hail/python/pinned-requirements.txt @@ -87,7 +81,7 @@ google-auth==2.55.1 # google-cloud-storage google-cloud-core==2.6.0 # via google-cloud-storage -google-cloud-storage==3.12.1 +google-cloud-storage==3.13.0 # via -r batch/requirements.txt google-crc32c==1.8.0 # via @@ -115,7 +109,7 @@ multidict==6.7.1 # -c batch/../web_common/pinned-requirements.txt # aiohttp # yarl -numpy==2.2.6 +numpy==2.4.6 # via # -c batch/../hail/python/dev/pinned-requirements.txt # -c batch/../hail/python/pinned-requirements.txt @@ -142,7 +136,7 @@ propcache==0.5.2 # -c batch/../web_common/pinned-requirements.txt # aiohttp # yarl -proto-plus==1.28.0 +proto-plus==1.28.1 # via # -c batch/../gear/pinned-requirements.txt # google-api-core @@ -152,7 +146,7 @@ protobuf==7.35.1 # google-api-core # googleapis-common-protos # proto-plus -pyasn1==0.6.3 +pyasn1==0.6.4 # via # -c batch/../gear/pinned-requirements.txt # -c batch/../hail/python/pinned-requirements.txt @@ -195,7 +189,7 @@ tenacity==9.1.4 # via # -c batch/../hail/python/pinned-requirements.txt # plotly -typing-extensions==4.15.0 +typing-extensions==4.16.0 # via # -c batch/../gear/pinned-requirements.txt # -c batch/../hail/python/dev/pinned-requirements.txt @@ -203,9 +197,7 @@ typing-extensions==4.15.0 # -c batch/../web_common/pinned-requirements.txt # aiohttp # aiosignal - # cryptography - # multidict -tzdata==2026.2 +tzdata==2026.3 # via # -c batch/../hail/python/dev/pinned-requirements.txt # -c batch/../hail/python/pinned-requirements.txt diff --git a/batch/test/conftest.py b/batch/test/conftest.py index 7bf61e4bcbb..0313a4b8719 100644 --- a/batch/test/conftest.py +++ b/batch/test/conftest.py @@ -1,25 +1,16 @@ -import asyncio import hashlib import logging import os import pytest +from hailtop.batch_client import aioclient from hailtop.batch_client.client import BatchClient from hailtop.config import get_remote_tmpdir log = logging.getLogger(__name__) -@pytest.fixture(scope="session") -def event_loop(): - loop = asyncio.get_event_loop() - try: - yield loop - finally: - loop.close() - - @pytest.fixture(autouse=True) def log_before_after(): log.info('starting test') @@ -34,6 +25,13 @@ def client(): client.close() +@pytest.fixture +async def async_client(): + client = await aioclient.BatchClient.create('test') + yield client + await client.close() + + @pytest.fixture(scope='module') def remote_tmpdir(): return get_remote_tmpdir('batch_tests') diff --git a/batch/test/pytest.ini b/batch/test/pytest.ini index af2398e723d..cc3d4277380 100644 --- a/batch/test/pytest.ini +++ b/batch/test/pytest.ini @@ -1,5 +1,7 @@ [pytest] asyncio_mode = auto +asyncio_default_fixture_loop_scope = session +asyncio_default_test_loop_scope = session addopts = --strict-markers markers = unchecked_allocator: tests that use the unchecked allocator diff --git a/batch/test/test_batch.py b/batch/test/test_batch.py index 56cfcab8506..d6fe2f9645b 100644 --- a/batch/test/test_batch.py +++ b/batch/test/test_batch.py @@ -1409,8 +1409,8 @@ def test_verify_private_network_is_restricted(client: BatchClient): assert False -async def test_old_clients_that_submit_mount_docker_socket_false_is_ok(client: BatchClient): - b = create_batch(client)._async_batch +async def test_old_clients_that_submit_mount_docker_socket_false_is_ok(async_client: AioBatchClient): + b = create_batch(async_client) await b._open_batch() b.create_job(DOCKER_ROOT_IMAGE, command=['sleep', '30']) update_id = await b._create_update() @@ -1427,8 +1427,8 @@ async def test_old_clients_that_submit_mount_docker_socket_false_is_ok(client: B await b._submit_jobs(update_id, [spec_bytes], pbar_task) -async def test_old_clients_that_submit_mount_docker_socket_true_is_rejected(client: BatchClient): - b = create_batch(client)._async_batch +async def test_old_clients_that_submit_mount_docker_socket_true_is_rejected(async_client: AioBatchClient): + b = create_batch(async_client) await b._open_batch() b.create_job(DOCKER_ROOT_IMAGE, command=['sleep', '30']) update_id = await b._create_update() @@ -2234,8 +2234,8 @@ def test_cancel_job_group_with_different_nested_updates(client: BatchClient): b.cancel() -async def test_get_and_cancel_job_group_with_unsubmitted_job_group_updates(client: BatchClient): - b = create_batch(client)._async_batch +async def test_get_and_cancel_job_group_with_unsubmitted_job_group_updates(async_client: AioBatchClient): + b = create_batch(async_client) jg = b.create_job_group() jg.create_job(DOCKER_ROOT_IMAGE, ['sleep', '300']) await b.submit() diff --git a/build.yaml b/build.yaml index 18e2d30fe22..6560c49047a 100644 --- a/build.yaml +++ b/build.yaml @@ -1560,7 +1560,7 @@ steps: inputs: - from: /repo/docker/hailgenetics/hail to: /io/repo/docker/hailgenetics/hail - - from: /repo/hail/python/pinned-requirements.txt + - from: /repo/hail/python/pinned-requirements-py310.txt to: /io/repo/hail/python/pinned-requirements.txt - from: /derived/release/hail/build/deploy/dist to: /io/repo/wheel @@ -2751,6 +2751,7 @@ steps: -vv \ --instafail \ --durations=50 \ + --asyncio-mode=auto \ /io/test_requester_pays_parsing.py inputs: - from: /derived/release/hail/build/deploy/dist diff --git a/check_pip_requirements.sh b/check_pip_requirements.sh index 42e02361870..96d7a7d59f5 100755 --- a/check_pip_requirements.sh +++ b/check_pip_requirements.sh @@ -11,7 +11,7 @@ do new_pinned_no_comments=$(mktemp) uv pip compile \ - --python-version 3.10 \ + --python-version 3.11 \ --python-platform linux \ --quiet $reqs $pinned --output-file=$new_pinned # Get rid of comments that might differ despite requirements being the same diff --git a/ci/pinned-requirements.txt b/ci/pinned-requirements.txt index d0e313b125c..16cb66a23ef 100644 --- a/ci/pinned-requirements.txt +++ b/ci/pinned-requirements.txt @@ -1,18 +1,18 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python-version 3.10 --python-platform linux ci/requirements.txt --output-file=ci/pinned-requirements.txt +# uv pip compile --python-version 3.11 --python-platform linux ci/requirements.txt --output-file=ci/pinned-requirements.txt certifi==2026.6.17 # via # -c ci/../gear/pinned-requirements.txt # -c ci/../hail/python/dev/pinned-requirements.txt # -c ci/../hail/python/pinned-requirements.txt # requests -cffi==2.0.0 +cffi==2.1.0 # via # -c ci/../gear/pinned-requirements.txt # -c ci/../hail/python/dev/pinned-requirements.txt # -c ci/../hail/python/pinned-requirements.txt # cryptography -charset-normalizer==3.4.7 +charset-normalizer==3.4.9 # via # -c ci/../gear/pinned-requirements.txt # -c ci/../hail/python/dev/pinned-requirements.txt @@ -67,14 +67,12 @@ six==1.17.0 # -c ci/../hail/python/dev/pinned-requirements.txt # -c ci/../hail/python/pinned-requirements.txt # python-dateutil -typing-extensions==4.15.0 +typing-extensions==4.16.0 # via # -c ci/../gear/pinned-requirements.txt # -c ci/../hail/python/dev/pinned-requirements.txt # -c ci/../hail/python/pinned-requirements.txt # -c ci/../web_common/pinned-requirements.txt - # cryptography - # pyjwt # zulip uritemplate==4.2.0 # via diff --git a/ci/test/pytest.ini b/ci/test/pytest.ini index 2f4c80e3075..7e4076691e2 100644 --- a/ci/test/pytest.ini +++ b/ci/test/pytest.ini @@ -1,2 +1,4 @@ [pytest] asyncio_mode = auto +asyncio_default_fixture_loop_scope = session +asyncio_default_test_loop_scope = session diff --git a/gear/pinned-requirements.txt b/gear/pinned-requirements.txt index f14fc212997..4ad1ba03d66 100644 --- a/gear/pinned-requirements.txt +++ b/gear/pinned-requirements.txt @@ -1,6 +1,6 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python-version 3.10 --python-platform linux gear/requirements.txt --output-file=gear/pinned-requirements.txt -aiohappyeyeballs==2.6.2 +# uv pip compile --python-version 3.11 --python-platform linux gear/requirements.txt --output-file=gear/pinned-requirements.txt +aiohappyeyeballs==2.7.1 # via # -c gear/../hail/python/dev/pinned-requirements.txt # -c gear/../hail/python/hailtop/pinned-requirements.txt @@ -23,12 +23,6 @@ aiosignal==1.4.0 # -c gear/../hail/python/hailtop/pinned-requirements.txt # -c gear/../hail/python/pinned-requirements.txt # aiohttp -async-timeout==5.0.1 - # via - # -c gear/../hail/python/dev/pinned-requirements.txt - # -c gear/../hail/python/hailtop/pinned-requirements.txt - # -c gear/../hail/python/pinned-requirements.txt - # aiohttp attrs==26.1.0 # via # -c gear/../hail/python/dev/pinned-requirements.txt @@ -42,13 +36,13 @@ certifi==2026.6.17 # -c gear/../hail/python/pinned-requirements.txt # kubernetes-asyncio # requests -cffi==2.0.0 +cffi==2.1.0 # via # -c gear/../hail/python/dev/pinned-requirements.txt # -c gear/../hail/python/hailtop/pinned-requirements.txt # -c gear/../hail/python/pinned-requirements.txt # cryptography -charset-normalizer==3.4.7 +charset-normalizer==3.4.9 # via # -c gear/../hail/python/dev/pinned-requirements.txt # -c gear/../hail/python/hailtop/pinned-requirements.txt @@ -70,7 +64,7 @@ google-api-core==2.31.0 # via google-api-python-client google-api-python-client==2.198.0 # via google-cloud-profiler -google-auth==2.55.1 +google-auth==2.56.0 # via # -c gear/../hail/python/hailtop/pinned-requirements.txt # -c gear/../hail/python/pinned-requirements.txt @@ -125,7 +119,7 @@ propcache==0.5.2 # -c gear/../hail/python/pinned-requirements.txt # aiohttp # yarl -proto-plus==1.28.0 +proto-plus==1.28.1 # via google-api-core protobuf==7.35.1 # via @@ -133,7 +127,7 @@ protobuf==7.35.1 # google-cloud-profiler # googleapis-common-protos # proto-plus -pyasn1==0.6.3 +pyasn1==0.6.4 # via # -c gear/../hail/python/hailtop/pinned-requirements.txt # -c gear/../hail/python/pinned-requirements.txt @@ -193,15 +187,13 @@ sortedcontainers==2.4.0 # -c gear/../hail/python/hailtop/pinned-requirements.txt # -c gear/../hail/python/pinned-requirements.txt # -r gear/requirements.txt -typing-extensions==4.15.0 +typing-extensions==4.16.0 # via # -c gear/../hail/python/dev/pinned-requirements.txt # -c gear/../hail/python/hailtop/pinned-requirements.txt # -c gear/../hail/python/pinned-requirements.txt # aiohttp # aiosignal - # cryptography - # multidict uritemplate==4.2.0 # via google-api-python-client urllib3==2.7.0 diff --git a/generate-pip-lockfile.sh b/generate-pip-lockfile.sh index 2efe9572103..64f5acc2daa 100755 --- a/generate-pip-lockfile.sh +++ b/generate-pip-lockfile.sh @@ -7,6 +7,6 @@ set -ex package=$1 uv pip compile \ - --python-version 3.10 \ + --python-version 3.11 \ --python-platform linux \ --upgrade $package/requirements.txt --output-file=$package/pinned-requirements.txt diff --git a/hail/python/dev/pinned-requirements.txt b/hail/python/dev/pinned-requirements.txt index 89d19f297d1..1f1d57a9d6e 100644 --- a/hail/python/dev/pinned-requirements.txt +++ b/hail/python/dev/pinned-requirements.txt @@ -1,6 +1,6 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python-version 3.10 --python-platform linux hail/python/dev/requirements.txt --output-file=hail/python/dev/pinned-requirements.txt -aiohappyeyeballs==2.6.2 +# uv pip compile --python-version 3.11 --python-platform linux hail/python/dev/requirements.txt --output-file=hail/python/dev/pinned-requirements.txt +aiohappyeyeballs==2.7.1 # via # -c hail/python/dev/../pinned-requirements.txt # aiohttp @@ -16,7 +16,7 @@ aiosignal==1.4.0 # aiohttp alabaster==0.7.16 # via sphinx -anyio==4.14.1 +anyio==4.14.2 # via # httpx # jupyter-server @@ -37,10 +37,6 @@ asttokens==2.4.1 # stack-data async-lru==2.3.0 # via jupyterlab -async-timeout==5.0.1 - # via - # -c hail/python/dev/../pinned-requirements.txt - # aiohttp attrs==26.1.0 # via # -c hail/python/dev/../pinned-requirements.txt @@ -64,13 +60,13 @@ certifi==2026.6.17 # httpcore # httpx # requests -cffi==2.0.0 +cffi==2.1.0 # via # -c hail/python/dev/../pinned-requirements.txt # argon2-cffi-bindings cfgv==3.5.0 # via pre-commit -charset-normalizer==3.4.7 +charset-normalizer==3.4.9 # via # -c hail/python/dev/../pinned-requirements.txt # requests @@ -115,11 +111,6 @@ docutils==0.18.1 # sphinx-rtd-theme entrypoints==0.4 # via jupyter-client -exceptiongroup==1.3.1 - # via - # anyio - # ipython - # pytest execnet==2.1.2 # via pytest-xdist executing==2.2.1 @@ -128,7 +119,7 @@ executing==2.2.1 # stack-data fastjsonschema==2.21.2 # via nbformat -filelock==3.29.4 +filelock==3.29.7 # via # python-discovery # virtualenv @@ -161,8 +152,6 @@ idna==3.18 # yarl imagesize==2.0.0 # via sphinx -importlib-metadata==9.0.0 - # via build iniconfig==2.3.0 # via pytest ipykernel==6.29.5 @@ -172,7 +161,7 @@ ipykernel==6.29.5 # jupyterlab # nbclassic # notebook -ipython==8.39.0 +ipython==9.15.0 # via # ipykernel # ipywidgets @@ -181,6 +170,8 @@ ipython-genutils==0.2.0 # via # nbclassic # notebook +ipython-pygments-lexers==1.1.1 + # via ipython ipywidgets==8.1.8 # via jupyter isoduration==20.11.0 @@ -198,6 +189,7 @@ jinja2==3.1.6 # nbconvert # nbsphinx # notebook + # pytest-html # sphinx json5==0.15.0 # via jupyterlab-server @@ -212,7 +204,7 @@ jsonschema-specifications==2025.9.1 # via jsonschema jupyter==1.1.1 # via -r hail/python/dev/requirements.txt -jupyter-builder==1.0.2 +jupyter-builder==1.1.0 # via jupyterlab jupyter-client==7.4.9 # via @@ -247,7 +239,7 @@ jupyter-server==2.20.0 # notebook-shim jupyter-server-terminals==0.5.4 # via jupyter-server -jupyterlab==4.6.0 +jupyterlab==4.6.1 # via jupyter jupyterlab-pygments==0.3.0 # via nbconvert @@ -264,7 +256,7 @@ markupsafe==3.0.3 # -c hail/python/dev/../pinned-requirements.txt # jinja2 # nbconvert -matplotlib==3.10.9 +matplotlib==3.11.0 # via -r hail/python/dev/requirements.txt matplotlib-inline==0.2.2 # via @@ -272,7 +264,7 @@ matplotlib-inline==0.2.2 # ipython mccabe==0.7.0 # via pylint -mistune==3.3.2 +mistune==3.3.3 # via nbconvert mock==5.1.0 # via -r hail/python/dev/requirements.txt @@ -322,7 +314,7 @@ notebook-shim==0.2.4 # via # jupyterlab # nbclassic -numpy==2.2.6 +numpy==2.4.6 # via # -c hail/python/dev/../pinned-requirements.txt # contourpy @@ -352,7 +344,7 @@ pathspec==0.12.1 # via curlylint pexpect==4.9.0 # via ipython -pillow==12.2.0 +pillow==12.3.0 # via # -c hail/python/dev/../pinned-requirements.txt # -r hail/python/dev/requirements.txt @@ -381,15 +373,15 @@ propcache==0.5.2 # aiohttp # yarl psutil==7.2.2 - # via ipykernel + # via + # ipykernel + # ipython ptyprocess==0.7.0 # via # pexpect # terminado pure-eval==0.2.3 # via stack-data -py==1.11.0 - # via pytest-forked pycparser==3.0 # via # -c hail/python/dev/../pinned-requirements.txt @@ -400,8 +392,10 @@ pygments==2.20.0 # aiohttp-devtools # devtools # ipython + # ipython-pygments-lexers # jupyter-console # nbconvert + # pytest # sphinx pylint==3.3.9 # via -r hail/python/dev/requirements.txt @@ -411,22 +405,19 @@ pyproject-hooks==1.2.0 # via build pyright==1.1.411 # via -r hail/python/dev/requirements.txt -pytest==7.4.4 +pytest==9.1.1 # via # -r hail/python/dev/requirements.txt # pytest-asyncio - # pytest-forked # pytest-html # pytest-instafail # pytest-metadata # pytest-mock # pytest-timeout # pytest-xdist -pytest-asyncio==0.21.2 +pytest-asyncio==1.4.0 # via -r hail/python/dev/requirements.txt -pytest-forked==1.6.0 - # via pytest-xdist -pytest-html==1.22.1 +pytest-html==4.2.0 # via -r hail/python/dev/requirements.txt pytest-instafail==0.5.0 # via -r hail/python/dev/requirements.txt @@ -438,7 +429,7 @@ pytest-timeout==2.4.0 # via -r hail/python/dev/requirements.txt pytest-timestamper==0.0.10 # via -r hail/python/dev/requirements.txt -pytest-xdist==2.5.0 +pytest-xdist==3.8.0 # via -r hail/python/dev/requirements.txt python-dateutil==2.9.0.post0 # via @@ -446,7 +437,7 @@ python-dateutil==2.9.0.post0 # arrow # jupyter-client # matplotlib -python-discovery==1.4.2 +python-discovery==1.4.4 # via virtualenv python-json-logger==2.0.7 # via @@ -484,7 +475,7 @@ rfc3986-validator==0.1.1 # jupyter-events rfc3987-syntax==1.1.0 # via jsonschema -rpds-py==0.30.0 +rpds-py==2026.6.3 # via # jsonschema # referencing @@ -543,13 +534,6 @@ tinycss2==1.5.1 # via bleach toml==0.10.2 # via curlylint -tomli==2.4.1 - # via - # build - # jupyter-builder - # jupyterlab - # pylint - # pytest tomlkit==0.15.0 # via pylint tornado==6.5.7 @@ -581,7 +565,7 @@ traitlets==5.15.1 # notebook types-chardet==5.0.4.6 # via -r hail/python/dev/requirements.txt -types-decorator==5.2.0.20260519 +types-decorator==5.2.0.20260712 # via -r hail/python/dev/requirements.txt types-deprecated==1.3.1.20260520 # via -r hail/python/dev/requirements.txt @@ -593,7 +577,7 @@ types-pyyaml==6.0.12.20260518 # via -r hail/python/dev/requirements.txt types-requests==2.31.0.6 # via -r hail/python/dev/requirements.txt -types-setuptools==82.0.0.20260518 +types-setuptools==83.0.0.20260706 # via -r hail/python/dev/requirements.txt types-six==1.17.0.20260518 # via -r hail/python/dev/requirements.txt @@ -603,23 +587,18 @@ types-urllib3==1.26.25.14 # via # -r hail/python/dev/requirements.txt # types-requests -typing-extensions==4.15.0 +typing-extensions==4.16.0 # via # -c hail/python/dev/../pinned-requirements.txt # aiohttp # aiosignal # anyio - # astroid - # async-lru # beautifulsoup4 - # exceptiongroup # ipython - # mistune - # multidict # pyright + # pytest-asyncio # referencing - # virtualenv -tzdata==2026.2 +tzdata==2026.3 # via # -c hail/python/dev/../pinned-requirements.txt # arrow @@ -629,15 +608,15 @@ urllib3==2.7.0 # via # -c hail/python/dev/../pinned-requirements.txt # requests -uv==0.11.24 +uv==0.11.28 # via -r hail/python/dev/requirements.txt -uv-build==0.11.24 +uv-build==0.11.28 # via -r hail/python/dev/requirements.txt -virtualenv==21.5.1 +virtualenv==21.6.1 # via pre-commit watchfiles==1.2.0 # via aiohttp-devtools -wcwidth==0.8.1 +wcwidth==0.8.2 # via prompt-toolkit webcolors==25.10.0 # via jsonschema @@ -653,5 +632,3 @@ yarl==1.24.2 # via # -c hail/python/dev/../pinned-requirements.txt # aiohttp -zipp==4.1.0 - # via importlib-metadata diff --git a/hail/python/dev/requirements.txt b/hail/python/dev/requirements.txt index 83646cbc362..1171a6656df 100644 --- a/hail/python/dev/requirements.txt +++ b/hail/python/dev/requirements.txt @@ -11,12 +11,11 @@ uv-build>=0.11.15,<0.12 curlylint>=0.13.1,<1 click>=8.1.2,<9 mock>=5.1,<5.2 -pytest>=7.1.3,<8 -pytest-html>=1.20.0,<2 -pytest-xdist>=2.2.1,<3 +pytest>=9.0,<10 +pytest-html>=4.0,<5 +pytest-xdist>=3.8,<4 pytest-instafail>=0.4.2,<1 -# https://github.com/hail-is/hail/issues/14130 -pytest-asyncio>=0.14.0,<0.23 +pytest-asyncio>=1.4,<2 pytest-timestamper>=0.0.9,<1 pytest-timeout>=2.1,<3 pytest-mock>=3.14,<4 diff --git a/hail/python/hailtop/pinned-requirements.txt b/hail/python/hailtop/pinned-requirements.txt index 0c67e27cad6..7eaa54292a2 100644 --- a/hail/python/hailtop/pinned-requirements.txt +++ b/hail/python/hailtop/pinned-requirements.txt @@ -1,8 +1,8 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python-version 3.10 --python-platform linux hail/python/hailtop/requirements.txt --output-file=hail/python/hailtop/pinned-requirements.txt +# uv pip compile --python-version 3.11 --python-platform linux hail/python/hailtop/requirements.txt --output-file=hail/python/hailtop/pinned-requirements.txt aiodns==2.0.0 # via -r hail/python/hailtop/requirements.txt -aiohappyeyeballs==2.6.2 +aiohappyeyeballs==2.7.1 # via aiohttp aiohttp==3.14.1 # via -r hail/python/hailtop/requirements.txt @@ -10,8 +10,6 @@ aiosignal==1.4.0 # via aiohttp annotated-doc==0.0.4 # via typer -async-timeout==5.0.1 - # via aiohttp attrs==26.1.0 # via aiohttp azure-common==1.1.28 @@ -30,9 +28,9 @@ azure-mgmt-storage==20.1.0 # via -r hail/python/hailtop/requirements.txt azure-storage-blob==12.30.0 # via -r hail/python/hailtop/requirements.txt -boto3==1.43.36 +boto3==1.43.47 # via -r hail/python/hailtop/requirements.txt -botocore==1.43.36 +botocore==1.43.47 # via # -r hail/python/hailtop/requirements.txt # boto3 @@ -41,11 +39,11 @@ certifi==2026.6.17 # via # msrest # requests -cffi==2.0.0 +cffi==2.1.0 # via # cryptography # pycares -charset-normalizer==3.4.7 +charset-normalizer==3.4.9 # via requests click==8.4.2 # via typer @@ -65,13 +63,13 @@ frozenlist==1.8.0 # -r hail/python/hailtop/requirements.txt # aiohttp # aiosignal -google-auth==2.55.1 +google-auth==2.56.0 # via # -r hail/python/hailtop/requirements.txt # google-auth-oauthlib google-auth-oauthlib==0.8.0 # via -r hail/python/hailtop/requirements.txt -humanize==4.15.0 +humanize==4.16.0 # via -r hail/python/hailtop/requirements.txt idna==3.18 # via @@ -111,7 +109,7 @@ propcache==0.5.2 # via # aiohttp # yarl -pyasn1==0.6.3 +pyasn1==0.6.4 # via pyasn1-modules pyasn1-modules==0.4.2 # via google-auth @@ -143,7 +141,7 @@ rich==12.6.0 # via # -r hail/python/hailtop/requirements.txt # typer -s3transfer==0.19.0 +s3transfer==0.19.1 # via boto3 setuptools==81.0.0 # via -r hail/python/hailtop/requirements.txt @@ -159,17 +157,14 @@ tabulate==0.10.0 # via -r hail/python/hailtop/requirements.txt typer==0.24.2 # via -r hail/python/hailtop/requirements.txt -typing-extensions==4.15.0 +typing-extensions==4.16.0 # via # aiohttp # aiosignal # azure-core # azure-identity # azure-storage-blob - # cryptography # janus - # multidict - # pyjwt urllib3==2.7.0 # via # botocore diff --git a/hail/python/pinned-requirements-py310.txt b/hail/python/pinned-requirements-py310.txt new file mode 100644 index 00000000000..c0d57a2bee4 --- /dev/null +++ b/hail/python/pinned-requirements-py310.txt @@ -0,0 +1,345 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile --python-version 3.10 --python-platform linux hail/python/requirements.txt --output-file=hail/python/pinned-requirements-py310.txt +aiodns==2.0.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +aiohappyeyeballs==2.7.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # aiohttp +aiohttp==3.14.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +aiosignal==1.4.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # aiohttp +annotated-doc==0.0.4 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # typer +async-timeout==5.0.1 + # via aiohttp +attrs==26.1.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # aiohttp +avro==1.11.5 + # via -r hail/python/requirements.txt +azure-common==1.1.28 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # azure-mgmt-storage +azure-core==1.41.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # azure-identity + # azure-mgmt-core + # azure-storage-blob + # msrest +azure-identity==1.25.3 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +azure-mgmt-core==1.6.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # azure-mgmt-storage +azure-mgmt-storage==20.1.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +azure-storage-blob==12.30.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +bokeh==3.9.1 + # via -r hail/python/requirements.txt +boto3==1.43.47 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +botocore==1.43.47 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt + # boto3 + # s3transfer +certifi==2026.6.17 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # msrest + # requests +cffi==2.1.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # cryptography + # pycares +charset-normalizer==3.4.9 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # requests +click==8.4.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # typer +commonmark==0.9.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # rich +contourpy==1.3.2 + # via + # -r hail/python/requirements.txt + # bokeh +cryptography==49.0.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # azure-identity + # azure-storage-blob + # google-auth + # msal + # pyjwt +decorator==5.3.1 + # via -r hail/python/requirements.txt +deprecated==1.2.18 + # via -r hail/python/requirements.txt +dill==0.4.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +frozenlist==1.8.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt + # aiohttp + # aiosignal +google-auth==2.56.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt + # google-auth-oauthlib +google-auth-oauthlib==0.8.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +humanize==4.16.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +idna==3.18 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # requests + # yarl +isodate==0.7.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # azure-storage-blob + # msrest +janus==1.0.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +jinja2==3.1.6 + # via bokeh +jmespath==1.1.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # boto3 + # botocore +jproperties==2.1.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +markupsafe==3.0.3 + # via jinja2 +msal==1.37.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # azure-identity + # msal-extensions +msal-extensions==1.3.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # azure-identity +msrest==0.7.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # azure-mgmt-storage +multidict==6.7.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # aiohttp + # yarl +narwhals==2.24.0 + # via bokeh +nest-asyncio==1.6.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +numpy==2.2.6 + # via + # -r hail/python/requirements.txt + # bokeh + # contourpy + # pandas + # scipy +oauthlib==3.3.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # requests-oauthlib +orjson==3.11.9 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +packaging==26.2 + # via + # bokeh + # plotly +pandas==2.3.3 + # via -r hail/python/requirements.txt +parsimonious==0.11.0 + # via -r hail/python/requirements.txt +pillow==12.3.0 + # via bokeh +plotly==5.24.1 + # via -r hail/python/requirements.txt +propcache==0.5.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # aiohttp + # yarl +py4j==0.10.9.7 + # via pyspark +pyasn1==0.6.4 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # pyasn1-modules +pyasn1-modules==0.4.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # google-auth +pycares==5.0.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # aiodns +pycparser==3.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # cffi +pygments==2.20.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # rich +pyjwt==2.13.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # msal +pyspark==3.5.3 + # via + # -c hail/python/dataproc-pre-installed-requirements.txt + # -r hail/python/requirements.txt +python-dateutil==2.9.0.post0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # botocore + # pandas +python-json-logger==2.0.7 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +pytz==2026.2 + # via pandas +pyyaml==6.0.3 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt + # bokeh +regex==2026.7.10 + # via parsimonious +requests==2.34.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/requirements.txt + # azure-core + # msal + # msrest + # requests-oauthlib +requests-oauthlib==2.0.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # google-auth-oauthlib + # msrest +rich==12.6.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt + # typer +s3transfer==0.19.1 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # boto3 +scipy==1.15.3 + # via -r hail/python/requirements.txt +setuptools==81.0.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +shellingham==1.5.4 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # typer +six==1.17.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # jproperties + # python-dateutil +sortedcontainers==2.4.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +tabulate==0.10.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +tenacity==9.1.4 + # via plotly +tornado==6.5.7 + # via bokeh +typer==0.24.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +typing-extensions==4.16.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # aiohttp + # aiosignal + # azure-core + # azure-identity + # azure-storage-blob + # cryptography + # janus + # multidict + # pyjwt +tzdata==2026.3 + # via pandas +urllib3==2.7.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # botocore + # requests +uvloop==0.21.0 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # -r hail/python/hailtop/requirements.txt +wrapt==1.17.3 + # via deprecated +xyzservices==2026.3.0 + # via bokeh +yarl==1.24.2 + # via + # -c hail/python/hailtop/pinned-requirements.txt + # aiohttp diff --git a/hail/python/pinned-requirements.txt b/hail/python/pinned-requirements.txt index 49b9d4a1e98..dc8befa6f7d 100644 --- a/hail/python/pinned-requirements.txt +++ b/hail/python/pinned-requirements.txt @@ -1,10 +1,10 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python-version 3.10 --python-platform linux hail/python/requirements.txt --output-file=hail/python/pinned-requirements.txt +# uv pip compile --python-version 3.11 --python-platform linux hail/python/requirements.txt --output-file=hail/python/pinned-requirements.txt aiodns==2.0.0 # via # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt -aiohappyeyeballs==2.6.2 +aiohappyeyeballs==2.7.1 # via # -c hail/python/hailtop/pinned-requirements.txt # aiohttp @@ -20,10 +20,6 @@ annotated-doc==0.0.4 # via # -c hail/python/hailtop/pinned-requirements.txt # typer -async-timeout==5.0.1 - # via - # -c hail/python/hailtop/pinned-requirements.txt - # aiohttp attrs==26.1.0 # via # -c hail/python/hailtop/pinned-requirements.txt @@ -59,11 +55,11 @@ azure-storage-blob==12.30.0 # -r hail/python/hailtop/requirements.txt bokeh==3.9.1 # via -r hail/python/requirements.txt -boto3==1.43.36 +boto3==1.43.47 # via # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt -botocore==1.43.36 +botocore==1.43.47 # via # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt @@ -74,12 +70,12 @@ certifi==2026.6.17 # -c hail/python/hailtop/pinned-requirements.txt # msrest # requests -cffi==2.0.0 +cffi==2.1.0 # via # -c hail/python/hailtop/pinned-requirements.txt # cryptography # pycares -charset-normalizer==3.4.7 +charset-normalizer==3.4.9 # via # -c hail/python/hailtop/pinned-requirements.txt # requests @@ -92,7 +88,9 @@ commonmark==0.9.2 # -c hail/python/hailtop/pinned-requirements.txt # rich contourpy==1.3.2 - # via bokeh + # via + # -r hail/python/requirements.txt + # bokeh cryptography==49.0.0 # via # -c hail/python/hailtop/pinned-requirements.txt @@ -115,7 +113,7 @@ frozenlist==1.8.0 # -r hail/python/hailtop/requirements.txt # aiohttp # aiosignal -google-auth==2.55.1 +google-auth==2.56.0 # via # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt @@ -124,7 +122,7 @@ google-auth-oauthlib==0.8.0 # via # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt -humanize==4.15.0 +humanize==4.16.0 # via # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt @@ -173,13 +171,13 @@ multidict==6.7.1 # -c hail/python/hailtop/pinned-requirements.txt # aiohttp # yarl -narwhals==2.22.1 +narwhals==2.24.0 # via bokeh nest-asyncio==1.6.0 # via # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt -numpy==2.2.6 +numpy==2.4.6 # via # -r hail/python/requirements.txt # bokeh @@ -202,7 +200,7 @@ pandas==2.3.3 # via -r hail/python/requirements.txt parsimonious==0.11.0 # via -r hail/python/requirements.txt -pillow==12.2.0 +pillow==12.3.0 # via bokeh plotly==5.24.1 # via -r hail/python/requirements.txt @@ -213,7 +211,7 @@ propcache==0.5.2 # yarl py4j==0.10.9.7 # via pyspark -pyasn1==0.6.3 +pyasn1==0.6.4 # via # -c hail/python/hailtop/pinned-requirements.txt # pyasn1-modules @@ -257,7 +255,7 @@ pyyaml==6.0.3 # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt # bokeh -regex==2026.5.9 +regex==2026.7.10 # via parsimonious requests==2.34.2 # via @@ -277,11 +275,11 @@ rich==12.6.0 # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt # typer -s3transfer==0.19.0 +s3transfer==0.19.1 # via # -c hail/python/hailtop/pinned-requirements.txt # boto3 -scipy==1.15.3 +scipy==1.17.1 # via -r hail/python/requirements.txt setuptools==81.0.0 # via @@ -312,7 +310,7 @@ typer==0.24.2 # via # -c hail/python/hailtop/pinned-requirements.txt # -r hail/python/hailtop/requirements.txt -typing-extensions==4.15.0 +typing-extensions==4.16.0 # via # -c hail/python/hailtop/pinned-requirements.txt # aiohttp @@ -320,11 +318,8 @@ typing-extensions==4.15.0 # azure-core # azure-identity # azure-storage-blob - # cryptography # janus - # multidict - # pyjwt -tzdata==2026.2 +tzdata==2026.3 # via pandas urllib3==2.7.0 # via diff --git a/hail/python/pytest.ini b/hail/python/pytest.ini index 4cf822dca6c..5fd2da680ad 100644 --- a/hail/python/pytest.ini +++ b/hail/python/pytest.ini @@ -1,5 +1,7 @@ [pytest] asyncio_mode = auto +asyncio_default_fixture_loop_scope = session +asyncio_default_test_loop_scope = session addopts = --strict-markers testpaths = test diff --git a/hail/python/requirements.txt b/hail/python/requirements.txt index 14cfb2d5486..83aa5846aff 100644 --- a/hail/python/requirements.txt +++ b/hail/python/requirements.txt @@ -4,6 +4,7 @@ avro>=1.10,<1.12 bokeh>3.8.2,<4 +contourpy<1.3.3 # 1.3.3+ requires Python >=3.11; pin to keep compatible with Python 3.10 images decorator>=5,<6 Deprecated>=1.2.10,<1.3 numpy>=2,<3 diff --git a/hail/python/test/hail/conftest.py b/hail/python/test/hail/conftest.py index c620c10bd90..eb97a2016b1 100644 --- a/hail/python/test/hail/conftest.py +++ b/hail/python/test/hail/conftest.py @@ -1,4 +1,3 @@ -import asyncio import hashlib import logging import os @@ -17,15 +16,6 @@ log = logging.getLogger(__name__) -@pytest.fixture(scope="session") -def event_loop(): - loop = asyncio.get_event_loop() - try: - yield loop - finally: - loop.close() - - def pytest_collection_modifyitems(items): def digest(s): return int.from_bytes(hashlib.md5(str(s).encode('utf-8')).digest(), 'little') diff --git a/hail/python/test/hailtop/conftest.py b/hail/python/test/hailtop/conftest.py index 0b618863e42..08ba85b5a73 100644 --- a/hail/python/test/hailtop/conftest.py +++ b/hail/python/test/hailtop/conftest.py @@ -1,19 +1,9 @@ -import asyncio import hashlib import os import pytest -@pytest.fixture(scope="session") -def event_loop(): - loop = asyncio.get_event_loop() - try: - yield loop - finally: - loop.close() - - def pytest_collection_modifyitems(items): n_splits = int(os.environ.get('HAIL_RUN_IMAGE_SPLITS', '1')) split_index = int(os.environ.get('HAIL_RUN_IMAGE_SPLIT_INDEX', '-1')) diff --git a/monitoring/test/pytest.ini b/monitoring/test/pytest.ini index 2f4c80e3075..7e4076691e2 100644 --- a/monitoring/test/pytest.ini +++ b/monitoring/test/pytest.ini @@ -1,2 +1,4 @@ [pytest] asyncio_mode = auto +asyncio_default_fixture_loop_scope = session +asyncio_default_test_loop_scope = session diff --git a/web_common/pinned-requirements.txt b/web_common/pinned-requirements.txt index 3092b6382d1..6026045aa70 100644 --- a/web_common/pinned-requirements.txt +++ b/web_common/pinned-requirements.txt @@ -1,6 +1,6 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python-version 3.10 --python-platform linux web_common/requirements.txt --output-file=web_common/pinned-requirements.txt -aiohappyeyeballs==2.6.2 +# uv pip compile --python-version 3.11 --python-platform linux web_common/requirements.txt --output-file=web_common/pinned-requirements.txt +aiohappyeyeballs==2.7.1 # via # -c web_common/../gear/pinned-requirements.txt # -c web_common/../hail/python/dev/pinned-requirements.txt @@ -20,12 +20,6 @@ aiosignal==1.4.0 # -c web_common/../hail/python/dev/pinned-requirements.txt # -c web_common/../hail/python/pinned-requirements.txt # aiohttp -async-timeout==5.0.1 - # via - # -c web_common/../gear/pinned-requirements.txt - # -c web_common/../hail/python/dev/pinned-requirements.txt - # -c web_common/../hail/python/pinned-requirements.txt - # aiohttp attrs==26.1.0 # via # -c web_common/../gear/pinned-requirements.txt @@ -72,14 +66,13 @@ propcache==0.5.2 # -c web_common/../hail/python/pinned-requirements.txt # aiohttp # yarl -typing-extensions==4.15.0 +typing-extensions==4.16.0 # via # -c web_common/../gear/pinned-requirements.txt # -c web_common/../hail/python/dev/pinned-requirements.txt # -c web_common/../hail/python/pinned-requirements.txt # aiohttp # aiosignal - # multidict yarl==1.24.2 # via # -c web_common/../gear/pinned-requirements.txt