fix(version): fall back to pyproject in source checkouts

Keep importlib.metadata as the primary source for installed packages, but avoid PackageNotFoundError when nanobot is imported directly from a source tree.

Made-with: Cursor
This commit is contained in:
Xubin Ren 2026-04-08 15:45:24 +00:00 committed by Xubin Ren
parent 1700166945
commit 715f2a79be
2 changed files with 63 additions and 2 deletions

View File

@ -2,9 +2,29 @@
nanobot - A lightweight AI agent framework
"""
from importlib.metadata import version as _pkg_version
from importlib.metadata import PackageNotFoundError, version as _pkg_version
from pathlib import Path
import tomllib
__version__ = _pkg_version("nanobot-ai")
def _read_pyproject_version() -> str | None:
"""Read the source-tree version when package metadata is unavailable."""
pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml"
if not pyproject.exists():
return None
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
return data.get("project", {}).get("version")
def _resolve_version() -> str:
try:
return _pkg_version("nanobot-ai")
except PackageNotFoundError:
# Source checkouts often import nanobot without installed dist-info.
return _read_pyproject_version() or "0.1.5"
__version__ = _resolve_version()
__logo__ = "🐈"
from nanobot.nanobot import Nanobot, RunResult

View File

@ -0,0 +1,41 @@
from __future__ import annotations
import subprocess
import sys
import textwrap
from pathlib import Path
import tomllib
def test_source_checkout_import_uses_pyproject_version_without_metadata() -> None:
repo_root = Path(__file__).resolve().parents[1]
expected = tomllib.loads((repo_root / "pyproject.toml").read_text(encoding="utf-8"))["project"][
"version"
]
script = textwrap.dedent(
f"""
import sys
import types
sys.path.insert(0, {str(repo_root)!r})
fake = types.ModuleType("nanobot.nanobot")
fake.Nanobot = object
fake.RunResult = object
sys.modules["nanobot.nanobot"] = fake
import nanobot
print(nanobot.__version__)
"""
)
proc = subprocess.run(
[sys.executable, "-S", "-c", script],
capture_output=True,
text=True,
check=False,
)
assert proc.returncode == 0, proc.stderr
assert proc.stdout.strip() == expected