Files
transformers/tests/cli/conftest.py
Dhruv SharmaandTarek Ziade 326ae42d30 Fix CLI compatibility with huggingface_hub 1.22 (#47059) (#47064)
* Fix CLI compatibility with huggingface_hub 1.22 (#47059)

Since huggingface_hub 1.22.0, typer_factory returns a click command group (HFCliTyperGroup) instead of a typer.Typer.

tests/cli drove the app with typer.testing.CliRunner, whose invoke() calls typer get_command() and reads ._add_completion from the group, raising AttributeError in every CLI test. Drive the app with click.testing.CliRunner instead, which invokes the click group natively.

Separately, the serve --reasoning option declared its default as the enum member ReasoningMode.AUTO; click validates defaults against the string choices and rejects it, which breaks transformers serve at runtime under hub 1.22. Use the enum value as the default instead (runtime comparisons are unaffected since ReasoningMode is a str enum).

Signed-off-by: Dhruv Sharma <dhruv7477@gmail.com>

* Use hub-canonical optional enum pattern for serve --reasoning

The previous string default failed the ty check (invalid-parameter-default: str not assignable to ReasoningMode). huggingface_hub own CLI never declares enum-member defaults - every enum option there is declared as SomeEnum | None = None, since the hub click converter does not coerce enum defaults. Mirror that pattern: reasoning defaults to None, which is behaviorally identical to AUTO (neither the ON nor OFF branch fires), and the help text states the effective default.

Signed-off-by: Dhruv Sharma <dhruv7477@gmail.com>

* Clean up comments in conftest.py

Removed outdated comments regarding `typer_factory` behavior based on reviewer's suggestions.

* Keep 'auto' as the serve --reasoning default

Apply the review suggestion: the default stays ReasoningMode.AUTO.value so
the CLI help keeps showing [default: auto]. The type-ignore is required
because ty rejects a str default on a ReasoningMode-annotated parameter,
and the hub CLI framework rejects any union annotation except T | None.
Also sorts the conftest import block (ruff I001 from the previous push).

Signed-off-by: Dhruv Sharma <dhruv7477@gmail.com>

* Make the cli test fixture compatible with huggingface_hub < 1.22

The fixture drives whatever `typer_factory` returned: with hub >= 1.22
the app is already a click command group and is invoked natively; with
older hubs it is a `typer.Typer`, converted via `typer.main.get_command`
before invoking. No change to the supported huggingface_hub range.

Verified against both huggingface_hub 1.21.0 and 1.22.0 (74 passed each).

Signed-off-by: Dhruv Sharma <dhruv7477@gmail.com>

---------

Signed-off-by: Dhruv Sharma <dhruv7477@gmail.com>
Co-authored-by: Tarek Ziade <tarek@ziade.org>
2026-07-07 09:15:18 +00:00

48 lines
1.3 KiB
Python

# Copyright 2025 The HuggingFace Team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import pytest
import typer
import typer.main
from click.testing import CliRunner
import transformers.cli.transformers
@pytest.fixture
def cli():
app = transformers.cli.transformers.app
if isinstance(app, typer.Typer):
app = typer.main.get_command(app)
def _cli_invoke(*args):
runner = CliRunner()
old_out_close = sys.stdout.close
old_err_close = sys.stderr.close
def _noop(*a, **k):
return None
sys.stdout.close = _noop
sys.stderr.close = _noop
try:
return runner.invoke(app, list(args), catch_exceptions=False)
finally:
sys.stdout.close = old_out_close
sys.stderr.close = old_err_close
return _cli_invoke