Skip to content

Commit

Permalink
pythonGH-92584: Remove distutils from the newtypes tutorial includes (p…
Browse files Browse the repository at this point in the history
  • Loading branch information
AA-Turner authored Aug 22, 2023
1 parent 13966da commit e97b7be
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 43 deletions.
54 changes: 27 additions & 27 deletions Doc/extending/newtypes_tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ extension module :mod:`!custom`:
allows defining heap-allocated extension types using the
: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
from the previous chapter. This file defines three things:
Expand Down Expand Up @@ -194,36 +194,32 @@ This adds the type to the module dictionary. This allows us to create
>>> mycustom = custom.Custom()
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
from distutils.core import setup, Extension
setup(name="custom", version="1.0",
ext_modules=[Extension("custom", ["custom.c"])])
from setuptools import Extension, setup
setup(ext_modules=[Extension("custom", ["custom.c"])])
in a file called :file:`setup.py`; then typing

.. 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
that directory and fire up Python --- you should be able to ``import custom`` and
play around with Custom objects.
in a shell should produce a file :file:`custom.so` in a subdirectory
and install it; now fire up Python --- you should be able to ``import custom``
and play around with ``Custom`` objects.

That wasn't so hard, was it?

Of course, the current Custom type is pretty uninteresting. It has no data and
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
============================================
Expand All @@ -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
adds these capabilities:

.. literalinclude:: ../includes/custom2.c
.. literalinclude:: ../includes/newtypes/custom2.c


This version of the module has a number of changes.
Expand Down Expand Up @@ -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
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
from distutils.core import setup, Extension
setup(name="custom", version="1.0",
ext_modules=[
Extension("custom", ["custom.c"]),
Extension("custom2", ["custom2.c"]),
])
from setuptools import Extension, setup
setup(ext_modules=[
Extension("custom", ["custom.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
============================================
Expand All @@ -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
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,
Expand Down Expand Up @@ -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
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
Expand Down Expand Up @@ -806,7 +806,7 @@ increases an internal counter:
>>> print(s.increment())
2
.. literalinclude:: ../includes/sublist.c
.. literalinclude:: ../includes/newtypes/sublist.c


As you can see, the source code closely resembles the :class:`!Custom` examples in
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions Doc/includes/newtypes/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "custom"
version = "1"
8 changes: 8 additions & 0 deletions Doc/includes/newtypes/setup.py
Original file line number Diff line number Diff line change
@@ -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"]),
])
File renamed without changes.
7 changes: 0 additions & 7 deletions Doc/includes/test.py → Doc/includes/newtypes/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,6 @@
>>> 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__":
import doctest, __main__
doctest.testmod(__main__)
9 changes: 0 additions & 9 deletions Doc/includes/setup.py

This file was deleted.

0 comments on commit e97b7be

Please sign in to comment.