22
33from __future__ import annotations
44
5+ from abc import ABC , abstractmethod
56import functools
67import os
78import re
@@ -119,7 +120,7 @@ def setup(**attrs):
119120 _Command = monkey .get_unpatched (distutils .core .Command )
120121
121122
122- class Command (_Command ):
123+ class Command (_Command , ABC ):
123124 """
124125 Setuptools internal actions are organized using a *command design pattern*.
125126 This means that each action (or group of closely related actions) executed during
@@ -132,42 +133,25 @@ class Command(_Command):
132133 When creating a new command from scratch, custom defined classes **SHOULD** inherit
133134 from ``setuptools.Command`` and implement a few mandatory methods.
134135 Between these mandatory methods, are listed:
135-
136- .. method:: initialize_options(self)
137-
138- Set or (reset) all options/attributes/caches used by the command
139- to their default values. Note that these values may be overwritten during
140- the build.
141-
142- .. method:: finalize_options(self)
143-
144- Set final values for all options/attributes used by the command.
145- Most of the time, each option/attribute/cache should only be set if it does not
146- have any value yet (e.g. ``if self.attr is None: self.attr = val``).
147-
148- .. method:: run(self)
149-
150- Execute the actions intended by the command.
151- (Side effects **SHOULD** only take place when ``run`` is executed,
152- for example, creating new files or writing to the terminal output).
136+ :meth:`initialize_options`, :meth:`finalize_options` and :meth:`run`.
153137
154138 A useful analogy for command classes is to think of them as subroutines with local
155- variables called "options". The options are "declared" in `` initialize_options()` `
156- and "defined" (given their final values, aka "finalized") in `` finalize_options()` `,
139+ variables called "options". The options are "declared" in :meth:` initialize_options`
140+ and "defined" (given their final values, aka "finalized") in :meth:` finalize_options`,
157141 both of which must be defined by every command class. The "body" of the subroutine,
158- (where it does all the work) is the `` run()` ` method.
159- Between `` initialize_options()`` and `` finalize_options()` `, ``setuptools`` may set
142+ (where it does all the work) is the :meth:` run` method.
143+ Between :meth:` initialize_options` and :meth:` finalize_options`, ``setuptools`` may set
160144 the values for options/attributes based on user's input (or circumstance),
161145 which means that the implementation should be careful to not overwrite values in
162- `` finalize_options` ` unless necessary.
146+ :meth:` finalize_options` unless necessary.
163147
164148 Please note that other commands (or other parts of setuptools) may also overwrite
165149 the values of the command's options/attributes multiple times during the build
166150 process.
167- Therefore it is important to consistently implement `` initialize_options()` ` and
168- `` finalize_options()` `. For example, all derived attributes (or attributes that
151+ Therefore it is important to consistently implement :meth:` initialize_options` and
152+ :meth:` finalize_options`. For example, all derived attributes (or attributes that
169153 depend on the value of other attributes) **SHOULD** be recomputed in
170- `` finalize_options` `.
154+ :meth:` finalize_options`.
171155
172156 When overwriting existing commands, custom defined classes **MUST** abide by the
173157 same APIs implemented by the original class. They also **SHOULD** inherit from the
@@ -238,6 +222,33 @@ def reinitialize_command(
238222 vars (cmd ).update (kw )
239223 return cmd
240224
225+ @abstractmethod
226+ def initialize_options (self ) -> None :
227+ """
228+ Set or (reset) all options/attributes/caches used by the command
229+ to their default values. Note that these values may be overwritten during
230+ the build.
231+ """
232+ raise NotImplementedError
233+
234+ @abstractmethod
235+ def finalize_options (self ) -> None :
236+ """
237+ Set final values for all options/attributes used by the command.
238+ Most of the time, each option/attribute/cache should only be set if it does not
239+ have any value yet (e.g. ``if self.attr is None: self.attr = val``).
240+ """
241+ raise NotImplementedError
242+
243+ @abstractmethod
244+ def run (self ) -> None :
245+ """
246+ Execute the actions intended by the command.
247+ (Side effects **SHOULD** only take place when :meth:`run` is executed,
248+ for example, creating new files or writing to the terminal output).
249+ """
250+ raise NotImplementedError
251+
241252
242253def _find_all_simple (path ):
243254 """
0 commit comments