GH-92584: Remove distutils from the newtypes tutorial includes (#108024)

This commit is contained in:
Adam Turner 2023-08-22 19:42:51 +01:00 committed by GitHub
parent 13966da71b
commit e97b7bef4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 42 additions and 43 deletions

View file

@ -45,7 +45,7 @@ extension module :mod:`!custom`:
allows defining heap-allocated extension types using the allows defining heap-allocated extension types using the
:c:func:`PyType_FromSpec` function, which isn't covered in this tutorial. :c:func:`PyType_FromSpec` function, which isn't covered in this tutorial.
.. literalinclude:: ../includes/custom.c .. literalinclude:: ../includes/newtypes/custom.c
Now that's quite a bit to take in at once, but hopefully bits will seem familiar Now that's quite a bit to take in at once, but hopefully bits will seem familiar
from the previous chapter. This file defines three things: from the previous chapter. This file defines three things:
@ -194,36 +194,32 @@ This adds the type to the module dictionary. This allows us to create
>>> mycustom = custom.Custom() >>> mycustom = custom.Custom()
That's it! All that remains is to build it; put the above code in a file called That's it! All that remains is to build it; put the above code in a file called
:file:`custom.c` and: :file:`custom.c`,
.. literalinclude:: ../includes/newtypes/pyproject.toml
in a file called :file:`pyproject.toml`, and
.. code-block:: python .. code-block:: python
from distutils.core import setup, Extension from setuptools import Extension, setup
setup(name="custom", version="1.0", setup(ext_modules=[Extension("custom", ["custom.c"])])
ext_modules=[Extension("custom", ["custom.c"])])
in a file called :file:`setup.py`; then typing in a file called :file:`setup.py`; then typing
.. code-block:: shell-session .. code-block:: shell-session
$ python setup.py build $ python -m pip install .
at a shell should produce a file :file:`custom.so` in a subdirectory; move to in a shell should produce a file :file:`custom.so` in a subdirectory
that directory and fire up Python --- you should be able to ``import custom`` and and install it; now fire up Python --- you should be able to ``import custom``
play around with Custom objects. and play around with ``Custom`` objects.
That wasn't so hard, was it? That wasn't so hard, was it?
Of course, the current Custom type is pretty uninteresting. It has no data and Of course, the current Custom type is pretty uninteresting. It has no data and
doesn't do anything. It can't even be subclassed. doesn't do anything. It can't even be subclassed.
.. note::
While this documentation showcases the standard :mod:`!distutils` module
for building C extensions, it is recommended in real-world use cases to
use the newer and better-maintained ``setuptools`` library. Documentation
on how to do this is out of scope for this document and can be found in
the `Python Packaging User's Guide <https://packaging.python.org/tutorials/distributing-packages/>`_.
Adding data and methods to the Basic example Adding data and methods to the Basic example
============================================ ============================================
@ -232,7 +228,7 @@ Let's extend the basic example to add some data and methods. Let's also make
the type usable as a base class. We'll create a new module, :mod:`!custom2` that the type usable as a base class. We'll create a new module, :mod:`!custom2` that
adds these capabilities: adds these capabilities:
.. literalinclude:: ../includes/custom2.c .. literalinclude:: ../includes/newtypes/custom2.c
This version of the module has a number of changes. This version of the module has a number of changes.
@ -514,17 +510,21 @@ We rename :c:func:`!PyInit_custom` to :c:func:`!PyInit_custom2`, update the
module name in the :c:type:`PyModuleDef` struct, and update the full class module name in the :c:type:`PyModuleDef` struct, and update the full class
name in the :c:type:`PyTypeObject` struct. name in the :c:type:`PyTypeObject` struct.
Finally, we update our :file:`setup.py` file to build the new module: Finally, we update our :file:`setup.py` file to include the new module,
.. code-block:: python .. code-block:: python
from distutils.core import setup, Extension from setuptools import Extension, setup
setup(name="custom", version="1.0", setup(ext_modules=[
ext_modules=[ Extension("custom", ["custom.c"]),
Extension("custom", ["custom.c"]), Extension("custom2", ["custom2.c"]),
Extension("custom2", ["custom2.c"]), ])
])
and then we re-install so that we can ``import custom2``:
.. code-block:: shell-session
$ python -m pip install .
Providing finer control over data attributes Providing finer control over data attributes
============================================ ============================================
@ -535,7 +535,7 @@ version of our module, the instance variables :attr:`!first` and :attr:`!last`
could be set to non-string values or even deleted. We want to make sure that could be set to non-string values or even deleted. We want to make sure that
these attributes always contain strings. these attributes always contain strings.
.. literalinclude:: ../includes/custom3.c .. literalinclude:: ../includes/newtypes/custom3.c
To provide greater control, over the :attr:`!first` and :attr:`!last` attributes, To provide greater control, over the :attr:`!first` and :attr:`!last` attributes,
@ -682,7 +682,7 @@ To allow a :class:`!Custom` instance participating in a reference cycle to
be properly detected and collected by the cyclic GC, our :class:`!Custom` type be properly detected and collected by the cyclic GC, our :class:`!Custom` type
needs to fill two additional slots and to enable a flag that enables these slots: needs to fill two additional slots and to enable a flag that enables these slots:
.. literalinclude:: ../includes/custom4.c .. literalinclude:: ../includes/newtypes/custom4.c
First, the traversal method lets the cyclic GC know about subobjects that could First, the traversal method lets the cyclic GC know about subobjects that could
@ -806,7 +806,7 @@ increases an internal counter:
>>> print(s.increment()) >>> print(s.increment())
2 2
.. literalinclude:: ../includes/sublist.c .. literalinclude:: ../includes/newtypes/sublist.c
As you can see, the source code closely resembles the :class:`!Custom` examples in As you can see, the source code closely resembles the :class:`!Custom` examples in

View file

@ -0,0 +1,7 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "custom"
version = "1"

View file

@ -0,0 +1,8 @@
from setuptools import Extension, setup
setup(ext_modules=[
Extension("custom", ["custom.c"]),
Extension("custom2", ["custom2.c"]),
Extension("custom3", ["custom3.c"]),
Extension("custom4", ["custom4.c"]),
Extension("sublist", ["sublist.c"]),
])

View file

@ -187,13 +187,6 @@
>>> gc.enable() >>> gc.enable()
""" """
import os
import sys
from distutils.util import get_platform
PLAT_SPEC = "%s-%d.%d" % (get_platform(), *sys.version_info[:2])
src = os.path.join("build", "lib.%s" % PLAT_SPEC)
sys.path.append(src)
if __name__ == "__main__": if __name__ == "__main__":
import doctest, __main__ import doctest, __main__
doctest.testmod(__main__) doctest.testmod(__main__)

View file

@ -1,9 +0,0 @@
from distutils.core import setup, Extension
setup(name="noddy", version="1.0",
ext_modules=[
Extension("noddy", ["noddy.c"]),
Extension("noddy2", ["noddy2.c"]),
Extension("noddy3", ["noddy3.c"]),
Extension("noddy4", ["noddy4.c"]),
Extension("shoddy", ["shoddy.c"]),
])