Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ test-min = [
"pytest-xdist[psutil]",
"pytest-randomly",
"pytest-rerunfailures",
"profimp",
"tuna",
]
test = [
"scanpy[test-min]",
Expand Down
48 changes: 37 additions & 11 deletions tests/test_performance.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,65 @@
from __future__ import annotations

import json
import enum
import sys
from pathlib import Path
from subprocess import run
from tempfile import NamedTemporaryFile
from typing import TYPE_CHECKING, TypedDict, cast

if TYPE_CHECKING:
from collections.abc import Iterable, MutableSet
from typing import NotRequired

def descend(profimp_data, modules, path):
module = profimp_data["module"]

class TunaColor(enum.IntEnum):
Func = 0
Builtin = 1
Deprecated = 2


class TunaProf(TypedDict):
text: list[str]
value: float
color: TunaColor
children: NotRequired[list[TunaProf]]


def descend(
profile: TunaProf, modules: MutableSet[str], path: Iterable[str] = ()
) -> Iterable[str]:
[module] = profile["text"]
path = [*path, module]
if module in modules:
yield " → ".join(e for e in path if e is not None)
modules.remove(module)
for child in profimp_data["children"]:
for child in profile.get("children", []):
yield from descend(child, modules, path)


def get_import_paths(modules):
def get_import_paths(modules: Iterable[str]) -> Iterable[str]:
from tuna import read_import_profile

proc = run(
[sys.executable, "-m", "profimp.main", "import scanpy"],
[sys.executable, "-X", "importtime", "-c", "import scanpy"],
capture_output=True,
check=True,
)
data = json.loads(proc.stdout)
return descend(data, set(modules), [])
with NamedTemporaryFile() as f:
Path(f.name).write_bytes(proc.stderr)
data = cast("TunaProf", read_import_profile(f.name))
return descend(data, set(modules))


def test_deferred_imports(imported_modules):
def test_deferred_imports(imported_modules: frozenset[str]) -> None:
slow_to_import = {
"umap", # neighbors, tl.umap
"seaborn", # plotting
"sklearn.metrics", # neighbors
"pynndescent", # neighbors
"networkx", # diffmap, paga, plotting._utils
# TODO: 'matplotlib.pyplot',
# TODO (maybe): 'numba',
# TODO: "matplotlib.pyplot",
# TODO (maybe): "numba",
}
falsely_imported = slow_to_import & imported_modules

Expand Down