Skip to content

Commit 37af898

Browse files
authored
Merge pull request #197 from django-commons/uv
Uv
2 parents 72a7cc4 + a50a408 commit 37af898

File tree

23 files changed

+444
-354
lines changed

23 files changed

+444
-354
lines changed

.github/workflows/lint.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Lint
22

3-
permissions: read-all
3+
permissions:
4+
contents: read
45

56
on:
67
push:

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ jobs:
133133
'${{ github.ref_name }}'
134134
--repo '${{ github.repository }}'
135135
--generate-notes
136+
--prerelease
136137
- name: Upload artifact signatures to GitHub Release
137138
env:
138139
GITHUB_TOKEN: ${{ github.token }}

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Test
22

3-
permissions: read-all
3+
permissions:
4+
contents: read
45

56
on:
67
push:

doc/source/changelog.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ v3.1.0 (2024-03-xx)
1111
* Fixed `fish completion installs should respect XDG_CONFIG_HOME <https://github.com/django-commons/django-typer/issues/193>`_
1212
* Fixed `zsh completion installs should respect ZDOTDIR <https://github.com/django-commons/django-typer/issues/192>`_
1313
* Implemented `Support Django 5.2 <https://github.com/django-commons/django-typer/issues/188>`_
14+
* Implemented `Use intersphinx for external document references. <https://github.com/django-commons/django-typer/issues/187>`
1415
* Implemented `Switch poetry -> uv <https://github.com/django-commons/django-typer/issues/185>`_
15-
* Implemented `Require tests to pass before release action runs. <<https://github.com/django-commons/django-typer/issues/173>`_
16+
* Implemented `Require tests to pass before release action runs. <https://github.com/django-commons/django-typer/issues/173>`_
1617

1718

1819
v3.0.0 (2024-02-16)

doc/source/conf.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@
4848
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
4949
# ones.
5050
extensions = [
51+
'sphinxcontrib_django',
5152
'sphinx.ext.autodoc',
5253
'sphinx.ext.todo',
5354
'sphinxcontrib.typer',
5455
'sphinx_tabs.tabs',
55-
"sphinx.ext.viewcode"
56+
"sphinx.ext.viewcode",
57+
'sphinx.ext.intersphinx'
5658
]
5759

5860
# Add any paths that contain templates here, relative to this directory.
@@ -96,6 +98,17 @@
9698
autodoc_typehints = "description" # or signature
9799
autodoc_typehints_format = "short"
98100

101+
intersphinx_mapping = {
102+
"django": (
103+
"https://docs.djangoproject.com/en/stable",
104+
"https://docs.djangoproject.com/en/stable/_objects/",
105+
),
106+
"click": ("https://click.palletsprojects.com/en/stable", None),
107+
"rich": ("https://rich.readthedocs.io/en/stable", None),
108+
"python": ('https://docs.python.org/3', None)
109+
}
110+
111+
99112
def setup(app):
100113
# Register a sphinx.ext.autodoc.between listener to ignore everything
101114
# between lines that contain the word IGNORE

doc/source/extensions.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ Tutorial: Inheritance & Plugins
88

99
Adding to, or altering the behavior of, commands from upstream Django_ apps is a common use case.
1010
Doing so allows you to keep your CLI_ stable while adding additional behaviors by installing new
11-
apps in ``INSTALLED_APPS``. There are three main extension patterns you may wish to employ:
11+
apps in :setting:`INSTALLED_APPS`. There are three main extension patterns you may wish to employ:
1212

1313
1. Override the behavior of a command in an upstream app.
1414
2. Add additional subcommands or groups to a command in an upstream app.
1515
3. Hook implementations of custom logic into upstream command extension points.
1616
(`Inversion of Control <https://en.wikipedia.org/wiki/Inversion_of_control>`_)
1717

1818
The django-typer_ plugin mechanism supports all three of these use cases in a way that respects
19-
the precedence order of apps in the ``INSTALLED_APPS`` setting. In this tutorial we walk through
20-
an example of each using a :ref:`generic backup command <generic_backup>`. First we'll see how we
21-
might :ref:`use inheritance (1) <inheritance>` to override and change the behavior of a
19+
the precedence order of apps in the :setting:`INSTALLED_APPS` setting. In this tutorial we walk
20+
through an example of each using a :ref:`generic backup command <generic_backup>`. First we'll see
21+
how we might :ref:`use inheritance (1) <inheritance>` to override and change the behavior of a
2222
subcommand. Then we'll see how we can :ref:`add subcommands (2) <plugin>` to an upstream command
2323
using plugins. Finally we'll use pluggy_ to implement a hook system that allows us to
2424
:ref:`add custom logic (3) <hooks>` to an upstream command.
@@ -259,7 +259,7 @@ directory in the ``apps.py`` file of the media and my_app apps like this:
259259
Because we explicitly register our plugins we can call the package whatever we want.
260260
django-typer does not require it to be named ``plugins``. It is also important to
261261
do this inside ready() because conflicts are resolved in the order in which the extension
262-
modules are registered and ready() methods are called in ``INSTALLED_APPS`` order.
262+
modules are registered and ready() methods are called in :setting:`INSTALLED_APPS` order.
263263

264264
For plugins to work, we'll need to re-implement media from above as a composed extension
265265
like this:

doc/source/howto.rst

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@ decorator. This is like defining a group at the command root and is an extension
268268
Collect Results with @finalize
269269
------------------------------
270270

271-
Typer_ and Click_ have a ``results_callback`` mechanism on ``MultiCommands`` that allow a function
272-
hook to be registered to operate on the results of subroutines before the command exits. You may
273-
use this same ``results_callback`` mechanism directly through the Typer_ interface, but
274-
django-typer_ offers a more convenient class-aware way to do this with the
271+
Typer_ and :doc:`Click <click:index>` have a ``results_callback`` mechanism on ``MultiCommands``
272+
that allow a function hook to be registered to operate on the results of subroutines before the
273+
command exits. You may use this same ``results_callback`` mechanism directly through the Typer_
274+
interface, but django-typer_ offers a more convenient class-aware way to do this with the
275275
:func:`~django_typer.management.finalize` decorator.
276276

277277
For example lets say we have two subcommands that return strings, we could turn them into a csv
@@ -334,17 +334,19 @@ finalizers at higher levels in the command hierarchy.
334334
335335
.. tip::
336336

337-
Finalizers can be overridden just like groups and initializers using the :ref:`plugin pattern. <plugins>`
337+
Finalizers can be overridden just like groups and initializers using the
338+
:ref:`plugin pattern. <plugins>`
338339

339340

340341
Call Commands from Code
341342
-----------------------
342343

343344
There are two options for invoking a :class:`~django_typer.management.TyperCommand` from code
344-
without spawning off a subprocess. The first is to use Django_'s builtin call_command_ function.
345-
This function will work exactly as it does for normal BaseCommand_ derived commands. django-typer_
346-
however adds another mechanism that can be more efficient, especially if your options and
347-
arguments are already of the correct type and require no parsing:
345+
without spawning off a subprocess. The first is to use Django_'s builtin
346+
:func:`~django.core.management.call_command` function. This function will work exactly as it does
347+
for normal :class:`~django.core.management.BaseCommand` derived commands. django-typer_ however adds
348+
another mechanism that can be more efficient, especially if your options and arguments are already
349+
of the correct type and require no parsing:
348350

349351
Say we have this command, called ``mycommand``:
350352

@@ -378,7 +380,7 @@ Say we have this command, called ``mycommand``:
378380
379381
The rule of thumb is this:
380382

381-
- Use call_command_ if your options and arguments need parsing.
383+
- Use :func:`~django.core.management.call_command` if your options and arguments need parsing.
382384
- Use :func:`~django_typer.management.get_command` and invoke the command functions directly if
383385
your options and arguments are already of the correct type.
384386

@@ -411,15 +413,16 @@ You may also fetch a subcommand function directly by passing its path:
411413
Change Default Django Options
412414
-----------------------------
413415

414-
:class:`~django_typer.management.TyperCommand` classes preserve all of the functionality of BaseCommand_ derivatives.
415-
This means that you can still use class members like `suppressed_base_arguments
416-
<https://docs.djangoproject.com/en/5.0/howto/custom-management-commands/#django.core.management.BaseCommand.suppressed_base_arguments>`_
417-
to suppress default options.
416+
:class:`~django_typer.management.TyperCommand` classes preserve all of the functionality of
417+
:class:`~django.core.management.BaseCommand` derivatives. This means that you can still use class
418+
members like :attr:`~django.core.management.BaseCommand.suppressed_base_arguments` to suppress
419+
default options.
418420

419-
By default :class:`~django_typer.management.TyperCommand` suppresses ``--verbosity``. You can add
420-
it back by setting ``suppressed_base_arguments`` to an empty list. If you want to use verbosity you
421-
can simply redefine it or use one of django-typer_'s :ref:`provided type hints <types>` for the
422-
default BaseCommand_ options:
421+
By default :class:`~django_typer.management.TyperCommand` suppresses :option:`--verbosity`. You can
422+
add it back by setting :attr:`~django.core.management.BaseCommand.suppressed_base_arguments` to an
423+
empty list. If you want to use verbosity you can simply redefine it or use one of django-typer_'s
424+
:ref:`provided type hints <types>` for the default :class:`~django.core.management.BaseCommand`
425+
options:
423426

424427
.. tabs::
425428

@@ -631,28 +634,30 @@ and if it is not provided the function will be treated as a
631634

632635
.. note::
633636

634-
**Conflicting extensions are resolved in INSTALLED_APPS order.** For a detailed discussion
635-
about the utility of this pattern, see the tutorial on :ref:`Extending Commands <plugins>`.
637+
**Conflicting extensions are resolved in** :setting:`INSTALLED_APPS` **order.** For a detailed
638+
discussion about the utility of this pattern, see the tutorial on
639+
:ref:`Extending Commands <plugins>`.
636640

637641
.. warning::
638642

639643
Take care not to import any extension code during or before Django's bootstrap procedure. This
640-
may result in conflict override behavior that does not honor INSTALLED_APPS order.
644+
may result in conflict override behavior that does not honor :setting:`INSTALLED_APPS` order.
641645

642646
.. _configure-rich-exception-tracebacks:
643647

644-
Configure rich_ Stack Traces
645-
----------------------------
648+
Configure :doc:`rich <rich:index>` Stack Traces
649+
-----------------------------------------------
646650

647-
When rich_ is installed it may be `configured to display rendered stack traces
648-
<https://rich.readthedocs.io/en/stable/traceback.html>`_ for unhandled exceptions.
651+
When :doc:`rich <rich:index>` is installed it may be
652+
:doc:`configured to display rendered stack traces <rich:traceback>` for unhandled exceptions.
649653
These stack traces are information dense and can be very helpful for debugging. By default, if
650-
rich_ is installed django-typer_ will configure it to render stack traces. You can disable
651-
this behavior by setting the ``DT_RICH_TRACEBACK_CONFIG`` config to ``False``. You may also
652-
set ``DT_RICH_TRACEBACK_CONFIG`` to a dictionary holding the parameters to pass to
653-
`rich.traceback.install`.
654+
:doc:`rich <rich:index>` is installed django-typer_ will configure it to render stack traces. You
655+
can disable this behavior by setting the ``DT_RICH_TRACEBACK_CONFIG`` config to ``False``. You may
656+
also set ``DT_RICH_TRACEBACK_CONFIG`` to a dictionary holding the parameters to pass to
657+
:func:`rich.traceback.install`.
654658

655-
This provides a common hook for configuring rich_ that you can control on a per-deployment basis:
659+
This provides a common hook for configuring :doc:`rich <rich:index>` that you can control on a
660+
per-deployment basis:
656661

657662
.. code-block::
658663
:caption: settings.py
@@ -819,22 +824,21 @@ print, self.stdout and typer.echo
819824
---------------------------------
820825

821826
There are no unbreakable rules about how you should print output from your commands.
822-
You could use loggers, normal print statements or the BaseCommand_ stdout and
823-
stderr output wrappers. Django advises the use of ``self.stdout.write`` because the
824-
stdout and stderr streams can be configured by calls to call_command_ or
825-
:func:`~django_typer.management.get_command` which allows you to easily grab output from your
826-
commands for testing. Using the command's configured stdout and stderr
827-
output wrappers also means output will respect the ``--force-color`` and ``--no-color``
828-
parameters.
829-
830-
Typer_ and click_ provide `echo and secho <https://typer.tiangolo.com/tutorial/printing/>`_
831-
functions that automatically handle byte to string conversions and offer simple styling
832-
support. :class:`~django_typer.management.TyperCommand` provides
833-
:meth:`~django_typer.management.TyperCommand.echo` and
827+
You could use loggers, normal print statements or the :class:`~django.core.management.BaseCommand`
828+
stdout and stderr output wrappers. Django advises the use of ``self.stdout.write`` because the
829+
stdout and stderr streams can be configured by calls to :func:`~django.core.management.call_command`
830+
or :func:`~django_typer.management.get_command` which allows you to easily grab output from your
831+
commands for testing. Using the command's configured stdout and stderr output wrappers also means
832+
output will respect the :option:`--force-color` and :option:`--no-color` parameters.
833+
834+
Typer_ and :doc:`click <click:index>` provide `echo and secho
835+
<https://typer.tiangolo.com/tutorial/printing/>`_ functions that automatically handle byte to string
836+
conversions and offer simple styling support. :class:`~django_typer.management.TyperCommand`
837+
provides :meth:`~django_typer.management.TyperCommand.echo` and
834838
:meth:`~django_typer.management.TyperCommand.secho` wrapper functions for the Typer_ echo/secho
835839
functions. If you wish to use Typer_'s echo you should use these wrapper functions because they
836-
honor the command's ``--force-color`` and ``--no-color`` flags and the configured stdout/stderr
837-
streams:
840+
honor the command's :option:`--force-color` and :option:`--no-color` flags and the configured
841+
stdout/stderr streams:
838842

839843
.. tabs::
840844

@@ -854,9 +858,10 @@ streams:
854858
Toggle on/off result printing
855859
-----------------------------
856860

857-
Django's BaseCommand_ will print any truthy values returned from the handle() method. This may not
858-
always be desired behavior. By default :class:`~django_typer.management.TyperCommand` will do the
859-
same, but you may toggle this behavior off by setting the class field ``print_result`` to False.
861+
Django's :class:`~django.core.management.BaseCommand` will print any truthy values returned from the
862+
:meth:`~django.core.management.BaseCommand.handle` method. This may not always be desired behavior.
863+
By default :class:`~django_typer.management.TyperCommand` will do the same, but you may toggle this
864+
behavior off by setting the class field ``print_result`` to False.
860865

861866

862867
.. tabs::

doc/source/index.rst

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ Django Typer
77

88
Use static typing to define the CLI for your Django_ management commands with Typer_. Optionally
99
use the provided :class:`~django_typer.management.TyperCommand` class that inherits from
10-
BaseCommand_. This class maps the Typer_ interface onto a class based interface that Django
11-
developers will be familiar with. All of the BaseCommand_ functionality is inherited, so that
10+
:class:`~django.core.management.BaseCommand`. This class maps the Typer_ interface onto a class
11+
based interface that Django developers will be familiar with. All of the
12+
:class:`~django.core.management.BaseCommand` functionality is inherited, so that
1213
:class:`~django_typer.management.TyperCommand` can be a drop in replacement.
1314

1415
**django-typer makes it easy to:**
@@ -17,13 +18,13 @@ developers will be familiar with. All of the BaseCommand_ functionality is inher
1718
* Create subcommands and hierarchical groups of commands.
1819
* Use the full power of Typer_'s parameter types to validate and parse command line inputs.
1920
* Create beautiful and information dense help outputs.
20-
* Configure the rendering of exception stack traces using rich_.
21+
* Configure the rendering of exception stack traces using :doc:`rich <rich:index>`.
2122
* :ref:`Install shell tab-completion support <shellcompletions>` for bash_, zsh_, fish_ and
2223
powershell_.
2324
* :ref:`Create custom and portable shell tab-completions for your CLI parameters.
2425
<define-shellcompletions>`
2526
* Port existing commands (:class:`~django_typer.management.TyperCommand` is interface compatible
26-
with BaseCommand_).
27+
with :class:`~django.core.management.BaseCommand`).
2728
* Use either a Django-style class-based interface or the Typer-style interface to define
2829
commands.
2930
* Add plugins to upstream commands.
@@ -49,15 +50,15 @@ developers will be familiar with. All of the BaseCommand_ functionality is inher
4950
5051
pip install django-typer
5152
52-
rich_ is a powerful library for rich text and beautiful formatting in the terminal.
53+
:doc:`rich <rich:index>` is a powerful library for rich text and beautiful formatting in the terminal.
5354
It is not required, but highly recommended for the best experience:
5455

5556
.. code:: bash
5657
5758
pip install "django-typer[rich]"
5859
5960
60-
2. Optionally add ``django_typer`` to your ``INSTALLED_APPS`` setting:
61+
2. Optionally add ``django_typer`` to your :setting:`INSTALLED_APPS` setting:
6162

6263
.. code:: python
6364
@@ -82,9 +83,10 @@ developers will be familiar with. All of the BaseCommand_ functionality is inher
8283

8384
:big:`Basic Example`
8485

85-
:class:`~django_typer.management.TyperCommand` is a drop in extension to BaseCommand_. All of the
86-
documented features of BaseCommand_ work the same way! Or, you may also use an interface identical
87-
to Typer_'s. Simply import Typer_ from django_typer instead of typer.
86+
:class:`~django_typer.management.TyperCommand` is a drop in extension to
87+
:class:`~django.core.management.BaseCommand`. All of the documented features of
88+
:class:`~django.core.management.BaseCommand` work the same way! Or, you may also use an interface
89+
identical to Typer_'s. Simply import Typer_ from django_typer instead of typer.
8890

8991
.. tabs::
9092

doc/source/reference.rst

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,21 @@ django_typer
1818
:exclude-members: Typer, CommandGroup, TyperCommand, Context, CommandNode
1919
:show-inheritance:
2020

21+
.. autoclass:: django_typer.management.Context
22+
:members:
23+
2124
.. autoclass:: django_typer.management.Typer
22-
:members: callback, initialize, finalize, command, group, add_typer
25+
:members:
2326

2427
.. autoclass:: django_typer.management.TyperCommand
25-
:members: initialize, callback, finalize, command, group, echo, secho, print_help, get_subcommand
28+
:members:
29+
:special-members: __call__
30+
31+
.. autoclass:: django_typer.management.TyperParser
32+
:members:
2633

2734
.. autoclass:: django_typer.management.CommandNode
28-
:members: name, click_command, context, children, get_command, print_help
35+
:members:
2936

3037
.. autoclass:: django_typer.management.TyperCommandMeta
3138

doc/source/refs.rst

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11

2-
.. _Django: https://www.djangoproject.com/
2+
.. _Django: https://www.djangoproject.com
33
.. _GitHub: https://github.com/django-commons/django-typer
44
.. _PyPI: https://pypi.python.org/pypi/django-typer
5-
.. _Typer: https://typer.tiangolo.com/
6-
.. _click: https://click.palletsprojects.com/
7-
.. _rich: https://rich.readthedocs.io/
5+
.. _Typer: https://typer.tiangolo.com
86
.. _DRY: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
9-
.. _BaseCommand: https://docs.djangoproject.com/en/stable/howto/custom-management-commands/#command-objects
10-
.. _argparse: https://docs.python.org/3/library/argparse.html
117
.. _django-typer: https://pypi.python.org/pypi/django-typer
128
.. _powershell: https://learn.microsoft.com/en-us/powershell/scripting/overview
13-
.. _fish: https://fishshell.com/
14-
.. _zsh: https://www.zsh.org/
15-
.. _bash: https://www.gnu.org/software/bash/
16-
.. _Arguments: https://typer.tiangolo.com/tutorial/arguments/
17-
.. _Options: https://typer.tiangolo.com/tutorial/options/
18-
.. _call_command: https://docs.djangoproject.com/en/5.0/ref/django-admin/#running-management-commands-from-your-code
19-
.. _sphinxcontrib-typer: https://pypi.org/project/sphinxcontrib-typer/
20-
.. _pluggy: https://pluggy.readthedocs.io/
9+
.. _fish: https://fishshell.com
10+
.. _zsh: https://www.zsh.org
11+
.. _bash: https://www.gnu.org/software/bash
12+
.. _Arguments: https://typer.tiangolo.com/tutorial/arguments
13+
.. _Options: https://typer.tiangolo.com/tutorial/options
14+
.. _sphinxcontrib-typer: https://pypi.org/project/sphinxcontrib-typer
15+
.. _pluggy: https://pluggy.readthedocs.io
2116
.. _CLI: https://en.wikipedia.org/wiki/Command-line_interface

0 commit comments

Comments
 (0)