Skip to content

Conversation

@waketzheng
Copy link
Contributor

@waketzheng waketzheng commented Aug 4, 2025

Description

Migrate from poetry to uv.

Support create virtual environment and install dependencies by:

  • Uv (recommended)
uv sync --all-extras --all-groups
pdm install --frozen-lockfile -G :all
  • Venv
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install --group=dev --group=contrib --group=test --group=docs -e ".[accel,asyncpg,aiomysql,asyncmy,psycopg,asyncodbc]"
poetry env use 3.13
$(poetry env activate)
poetry run pip install --upgrade pip
poetry run pip install --group=dev --group=contrib --group=test --group=docs -e ".[accel,asyncpg,aiomysql,asyncmy,psycopg,asyncodbc]"
# Or:
# poetry install --all-extras --all-groups --no-root && poetry run pip install -e .

Motivation and Context

I made a simple test which show that uv is much more quickly than poetry:

poetry env use python3.13
poetry shell
time make deps
# make deps  17.14s user 8.00s system 113% cpu 22.169 total
time poetry add falcon
# poetry add falcon  4.74s user 0.69s system 52% cpu 10.301 total
time make deps
# make deps  2.20s user 0.32s system 98% cpu 2.549 total

uv venv --python=3.13 --prompt=tortoise-orm-3.13
source .venv/bin/activate
time uv sync --all-groups --all-extras
# uv sync --all-groups --all-extras  13.55s user 6.78s system 96% cpu 21.032 total
rm -rf .venv
time uv sync --all-groups --all-extras
# uv sync --all-groups --all-extras  0.08s user 1.10s system 124% cpu 0.949 total
time uv add falcon
# uv add falcon  1.39s user 0.50s system 61% cpu 3.062 total
time uv sync --all-groups --all-extras
# uv sync --all-groups --all-extras  0.03s user 0.01s system 86% cpu 0.046 total

For people who change the default index url of uv (e.g.: export UV_DEFAULT_INDEX="https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"), run uv sync or make deps will change the source registry in uv.lock, in that case you can run the following script to rollback it back when contributing:

#!/usr/bin/env python
"""Auto change registry of uv.lock to be pypi.org

Usage::
    python3 <me>.py
"""

from __future__ import annotations

import functools
import re
import sys
from pathlib import Path

PYPI = "https://pypi.org/simple"
HOST = "https://files.pythonhosted.org"


def main() -> int | None:
    if "--help" in sys.argv:
        print(__doc__.replace("<me>", Path(__file__).stem))
        return None
    verbose = "--verbose" in sys.argv
    p = Path("uv.lock")
    if not p.exists():
        p = Path("..", p.name)
        if not p.exists():
            if verbose:
                print(f"{p.name} not found, skip.")
            return None
    text = p.read_text("utf-8")
    registry_pattern = r'(registry = ")(.*?)"'
    replace_registry = functools.partial(re.sub, registry_pattern, rf'\1{PYPI}"')
    registry_urls = {i[1] for i in re.findall(registry_pattern, text)}
    download_pattern = r'(url = ")(https?://.*?)(/packages/.*?\.)(gz|whl)"'
    replace_host = functools.partial(re.sub, download_pattern, rf'\1{HOST}\3\4"')
    download_hosts = {i[1] for i in re.findall(download_pattern, text)}
    if not registry_urls:
        raise ValueError(f"Failed to find pattern {registry_pattern!r} in {p}")
    if len(registry_urls) == 1:
        current_registry = registry_urls.pop()
        if current_registry == PYPI:
            if download_hosts == {HOST}:
                if verbose:
                    print(f"Registry of {p} is {PYPI}, no need to change.")
                return 0
        else:
            text = replace_registry(text)
            if verbose:
                print(current_registry, "-->", PYPI)
    else:
        # TODO: ask each one to confirm replace
        text = replace_registry(text)
        if verbose:
            for current_registry in sorted(registry_urls):
                print(current_registry, "-->", PYPI)
    if len(download_hosts) == 1:
        current_host = download_hosts.pop()
        if current_host != HOST:
            text = replace_host(text)
            if verbose:
                print(current_host, "-->", HOST)
    elif download_hosts:
        # TODO: ask each one to confirm replace
        text = replace_host(text)
        if verbose:
            for current_host in sorted(download_hosts):
                print(current_host, "-->", HOST)
    size = p.write_text(text, encoding="utf-8")
    if verbose:
        print(f"Updated {p} with {size} bytes.")
    if "--quiet" in sys.argv:
        return 0
    return 1


if __name__ == "__main__":
    sys.exit(main())

How Has This Been Tested?

make ci

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added the changelog accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@codspeed-hq
Copy link

codspeed-hq bot commented Aug 4, 2025

CodSpeed Performance Report

Merging #1987 will not alter performance

Comparing waketzheng:feat-uv (c16d32b) with develop (c4f601e)

🎉 Hooray! pytest-codspeed just leveled up to 4.0.0!

A heads-up, this is a breaking change and it might affect your current performance baseline a bit. But here's the exciting part - it's packed with new, cool features and promises improved result stability 🥳!
Curious about what's new? Visit our releases page to delve into all the awesome details about this new version.

Summary

✅ 16 untouched benchmarks

@coveralls
Copy link

coveralls commented Aug 5, 2025

Pull Request Test Coverage Report for Build 17096137820

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 1 of 1 (100.0%) changed or added relevant line in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall first build on feat-uv at 89.864%

Totals Coverage Status
Change from base Build 17090868824: 89.9%
Covered Lines: 6670
Relevant Lines: 7234

💛 - Coveralls

@henadzit
Copy link
Contributor

I just merged a fix for CI. Can you please rebase your branch?

@waketzheng waketzheng requested review from abondar and henadzit August 22, 2025 11:28
Copy link
Contributor

@henadzit henadzit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! uv is such an improvement!

@henadzit henadzit merged commit dc8042c into tortoise:develop Aug 24, 2025
10 of 15 checks passed
@waketzheng waketzheng deleted the feat-uv branch August 26, 2025 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants