Skip to content

Commit

Permalink
Deprecate help command alias and @expects_obj decorator (#192)
Browse files Browse the repository at this point in the history
* chore: deprecate `help` alias for `--help` argument
* chore: deprecate the `@expects_obj` decorator
  • Loading branch information
neithere authored Oct 2, 2023
1 parent ac40391 commit 5905bfd
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 14 deletions.
12 changes: 12 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ Backwards incompatible changes:
Note: the `pre_call` hack was scheduled to be removed but due to requests it
will remain until a replacement is implemented.

Deprecated:

- The `@expects_obj` decorator. Rationale: it used to support the old,
"un-pythonic" style of usage, which essentially lies outside the scope of
Argh. If you are not using the mapping of function arguments onto CLI, then
you aren't reducing the amount of code compared to vanilla Argparse.

- The `add_help_command` argument in `dispatch()`.
Rationale: it doesn't add much to user experience; it's not much harder to
type ``--help`` than it is to type ``help``; moreover, the option can be
added anywhere, unlike its positional counterpart.

Enhancements:

- Added type annotations to existing Argh code (#185 → #189).
Expand Down
6 changes: 6 additions & 0 deletions docs/source/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ wrapping the function into the :func:`~argh.decorators.expects_obj` decorator::
This way arguments cannot be defined in the Natural Way but the
:class:`~argh.decorators.arg` decorator works as usual.

.. deprecated:: 0.30
The `@expects_obj` decorator will removed in v0.31 or a later version.
Please consider using the main feature Argh offers — the mapping of
function signature to CLI. Otherwise you are basically using vanilla
Argparse.

.. note::

In both cases — ``**kwargs``-only and `@expects_obj` — the arguments
Expand Down
22 changes: 17 additions & 5 deletions src/argh/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Command decorators
~~~~~~~~~~~~~~~~~~
"""
import warnings
from typing import Callable, List, Optional

from argh.constants import (
Expand Down Expand Up @@ -80,11 +81,8 @@ def arg(*args, **kwargs) -> Callable:
required if they can be easily guessed (e.g. you don't have to specify type
or action when an `int` or `bool` default value is supplied).
Typical use cases:
- In combination with :func:`expects_obj` (which is not recommended);
- in combination with ordinary function signatures to add details that
cannot be expressed with that syntax (e.g. help message).
Typical use case: in combination with ordinary function signatures to add
details that cannot be expressed with that syntax (e.g. help message).
Usage::
Expand Down Expand Up @@ -183,10 +181,18 @@ def wrapper(func: Callable):
return wrapper


# TODO: deprecated — remove in v0.31+
def expects_obj(func: Callable) -> Callable:
"""
Marks given function as expecting a namespace object.
.. deprecated:: 0.30
Will removed in v0.31 or a later version.
Please consider using the main feature Argh offers — the mapping of
function signature to CLI. Otherwise you are basically using vanilla
Argparse.
Usage::
@arg("bar")
Expand All @@ -202,5 +208,11 @@ def foo(bar, quux=123):
In most cases you don't need this decorator.
"""
warnings.warn(
DeprecationWarning(
"The @expects_obj decorator is deprecated. Please update "
'your code to use the standard approach AKA "Natural Way".'
)
)
setattr(func, ATTR_EXPECTS_NAMESPACE_OBJECT, True)
return func
23 changes: 20 additions & 3 deletions src/argh/dispatching.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import argparse
import io
import sys
import warnings
from types import GeneratorType
from typing import IO, Any, Callable, Dict, Iterator, List, Optional

Expand Down Expand Up @@ -69,7 +70,7 @@ def get_function(self) -> Callable:
def dispatch(
parser: argparse.ArgumentParser,
argv: Optional[List[str]] = None,
add_help_command: bool = True,
add_help_command: bool = False,
completion: bool = True,
output_file: IO = sys.stdout,
errors_file: IO = sys.stderr,
Expand Down Expand Up @@ -99,7 +100,16 @@ def dispatch(
if `True`, converts first positional argument "help" to a keyword
argument so that ``help foo`` becomes ``foo --help`` and displays usage
information for "foo". Default is `True`.
information for "foo". Default is `False`.
.. versionchanged:: 0.30
The default value is now ``False`` instead of ``True``.
.. deprecated:: 0.30
This argument will be removed in v.0.31. The user is expected to
use ``--help`` instead of ``help``.
:param output_file:
Expand Down Expand Up @@ -147,7 +157,14 @@ def dispatch(
if argv is None:
argv = sys.argv[1:]

if add_help_command:
# TODO: remove in v0.31+/v1.0
if add_help_command: # pragma: nocover
warnings.warn(
DeprecationWarning(
"The argument `add_help_command` in `dispatch()` is deprecated. "
"The user is expected to type `--help` instead of `help`."
)
)
if argv and argv[0] == "help":
argv.pop(0)
argv.append("--help")
Expand Down
1 change: 1 addition & 0 deletions tests/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def func():
assert attr == "STUB"


# TODO: deprecated — remove in v0.31+
def test_expects_obj():
@argh.expects_obj
def func(args):
Expand Down
8 changes: 2 additions & 6 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,19 +500,14 @@ def alias1():
assert run(p, "alias3").out == "ok\n"


def test_help_alias():
def test_help():
p = DebugArghParser()

# assert the commands don't fail

assert run(p, "--help", exit=True) == 0
assert run(p, "greet --help", exit=True) == 0
assert run(p, "greet hello --help", exit=True) == 0

assert run(p, "help", exit=True) == 0
assert run(p, "help greet", exit=True) == 0
assert run(p, "help greet hello", exit=True) == 0


def test_arg_order():
"""Positional arguments are resolved in the order in which the @arg
Expand Down Expand Up @@ -573,6 +568,7 @@ def whiner_iterable():
)


# TODO: deprecated — remove in v0.31+
def test_custom_argparse_namespace():
@argh.expects_obj
def cmd(args):
Expand Down

0 comments on commit 5905bfd

Please sign in to comment.