Skip to content

Problems with wheel_file_re #9769

@AlekseyLobanov

Description

@AlekseyLobanov

Description

Hello.

I found that performance of the current wheel_file_old may be really bad O(N^4) on some inputs. It may be not a serious problem but for end user it will be almost impossible to find and troubleshoot.

After performance fix I also found .dist-info extension is working as expected.

We can verify performance with this POC

import re
import time
from contextlib import contextmanager
import sys

wheel_file_old = re.compile(
    r"^(?P<namever>(?P<name>.+?)-(?P<ver>\d.*?))"
    r"(-(?P<build>\d.*?))?"
    r"-(?P<pyver>.+?)"
    r"-(?P<abi>.+?)"
    r"-(?P<plat>.+?)"
    r"\.whl|\.dist-info$",
    re.VERBOSE,
)
wheel_file_re_new= re.compile(
    r"^(?P<namever>(?P<name>[^-]+)-(?P<ver>[^-]*))"
    r"(-(?P<build>\d[^-]*))?"
    r"-(?P<pyver>[^-]+)"
    r"-(?P<abi>[^-]+)"
    r"-(?P<plat>[^-]+)"
    r"(?:\.whl|\.dist-info)$",
    re.VERBOSE,
)


@contextmanager
def duration(text):
    begin_at = time.monotonic()
    yield
    delta = time.monotonic() - begin_at
    print(f"{text:20} takes {delta:0.6f}s")


pattern = '0-0' + '-' * int(sys.argv[1])

with duration("Current (old) re"):
    wheel_file_old.match(pattern)
with duration("New re"):
    wheel_file_re_new.match(pattern)

Example output

➜ python poetry-poc.py 250
Current (old) re     takes 0.942238s
New re               takes 0.000003s

Workarounds

  • Performance issues should not be a problem for almost all valid wheel names
  • Do not use wheels with .dist-info extension

Poetry Installation Method

pip

Operating System

Ubtuntu

Poetry Version

2.0.0.dev0

Poetry Configuration

cache-dir = "/home/alex/.cache/pypoetry"
experimental.system-git-client = false
installer.max-workers = null
installer.no-binary = null
installer.only-binary = null
installer.parallel = true
keyring.enabled = true
requests.max-retries = 0
solver.lazy-wheel = true
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /home/alex/.cache/pypoetry/virtualenvs
virtualenvs.prefer-active-python = false
virtualenvs.prompt = "{project_name}-py{python_version}"

Python Sysconfig

any

Example pyproject.toml

any

Poetry Runtime Logs

any

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugSomething isn't working as expectedstatus/triageThis issue needs to be triaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions