Files
wehub-resource-sync 09e9f3545f
Test / Code Quality (push) Has been cancelled
Test / Test (macos-latest, Python 3.10) (push) Has been cancelled
Test / Test (macos-latest, Python 3.11) (push) Has been cancelled
Test / Test (macos-latest, Python 3.12) (push) Has been cancelled
Test / Test (macos-latest, Python 3.13) (push) Has been cancelled
Test / Test (macos-latest, Python 3.14) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.10) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.11) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.12) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.13) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.14) (push) Has been cancelled
Test / Test (windows-latest, Python 3.10) (push) Has been cancelled
Test / Test (windows-latest, Python 3.11) (push) Has been cancelled
Test / Test (windows-latest, Python 3.12) (push) Has been cancelled
Test / Test (windows-latest, Python 3.13) (push) Has been cancelled
Test / Test (windows-latest, Python 3.14) (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
dependency-audit / pip-audit (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:30:13 +08:00

112 lines
4.0 KiB
Python

"""Guard the click-group / package-attribute shadowing fix from P3.T0.
Before P3.T0, ``cli/__init__.py`` did ``from .download import download`` and
similar for 15 other command groups. Because the click group was bound at the
package level under the SAME name as the source module, ``import
notebooklm.cli.download`` returned the click ``Group`` object instead of the
module — tests that wanted to patch a symbol inside the module had to use a
``get_cli_module()`` helper that called ``importlib`` to bypass the shadow.
P3.T0 renamed the source modules to ``*_cmd.py`` (e.g. ``download_cmd``) so
the click groups can keep their historical public names without overwriting
the module's package attribute. This test asserts that, for each of the 16
renamed modules:
1. ``importlib.import_module("notebooklm.cli.<name>_cmd")`` returns a real
module (``inspect.ismodule`` is ``True``).
2. The click group is still reachable at its historical public path
``notebooklm.cli.<name>`` (for the 12 groups exported under their original
name from ``cli/__init__.py``; ``chat``, ``doctor``, ``notebook`` and
``session`` use ``register_*`` helpers instead of a top-level click group
so they are exempt from check 2).
If this test fails for check 1, someone re-introduced shadowing in
``cli/__init__.py`` (e.g. added ``from .download import download`` instead of
``from .download_cmd import download``). If it fails for check 2, the public
re-export under the historical click-group name was dropped — that breaks the
``notebooklm`` console script's import block in ``notebooklm_cli.py`` and any
downstream tooling that imports the click groups by their public names.
"""
from __future__ import annotations
import importlib
import inspect
import click
import pytest
# The 16 modules renamed in P3.T0.
RENAMED_MODULES = (
"agent",
"artifact",
"chat",
"doctor",
"download",
"generate",
"label",
"language",
"note",
"notebook",
"profile",
"research",
"session",
"share",
"skill",
"source",
)
# Of those 16, the click groups still re-exported under their historical names
# from ``cli/__init__.py`` (`__all__`). ``chat``/``doctor``/``notebook`` and
# ``session`` instead expose ``register_*`` helpers, so the click group is
# attached at registration time rather than re-exported as a top-level name.
CLICK_GROUPS_PUBLIC = (
"agent",
"artifact",
"download",
"generate",
"label",
"language",
"note",
"profile",
"research",
"share",
"skill",
"source",
)
@pytest.mark.parametrize("name", RENAMED_MODULES)
def test_cmd_module_imports_as_real_module(name: str) -> None:
"""``notebooklm.cli.<name>_cmd`` must resolve to a real module, not a click group."""
mod = importlib.import_module(f"notebooklm.cli.{name}_cmd")
assert inspect.ismodule(mod), (
f"notebooklm.cli.{name}_cmd is {type(mod).__name__}, not a module — "
f"someone may have re-introduced package-attribute shadowing."
)
# Belt-and-braces: not a click Group either.
assert not isinstance(mod, click.Command), (
f"notebooklm.cli.{name}_cmd is a click Command — shadowing is back."
)
@pytest.mark.parametrize("public_name", CLICK_GROUPS_PUBLIC)
def test_click_group_public_alias_preserved(public_name: str) -> None:
"""The click group is still reachable under its historical public name.
``from notebooklm.cli import download`` (etc.) must continue to return the
click ``Group`` so ``notebooklm_cli.py`` and external importers don't
break. ``cli/__init__.py`` aliases each group to its pre-rename name via
``from .<X>_cmd import <X>``.
"""
cli_pkg = importlib.import_module("notebooklm.cli")
obj = getattr(cli_pkg, public_name, None)
assert obj is not None, (
f"notebooklm.cli.{public_name} is missing — the historical "
f"click-group re-export in cli/__init__.py was dropped."
)
assert isinstance(obj, click.Command), (
f"notebooklm.cli.{public_name} resolved to {type(obj).__name__}, "
f"expected a click.Command (Group)."
)