Skip to content

Commit 11756dc

Browse files
Convert packaging lesson to use pyproject.toml instead (#235)
* Convert packaging lesson to use pyproject.toml instead * Update ch04packaging/03Packaging.ipynb.py Co-authored-by: David Pérez-Suárez <[email protected]> --------- Co-authored-by: David Pérez-Suárez <[email protected]>
1 parent 14fa606 commit 11756dc

File tree

1 file changed

+89
-49
lines changed

1 file changed

+89
-49
lines changed

ch04packaging/03Packaging.ipynb.py

Lines changed: 89 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -82,22 +82,38 @@
8282
# %autoreload 2
8383

8484
# %% [markdown]
85-
# ### Using setuptools
85+
# ### Using pyproject.toml
8686

8787
# %% [markdown]
88+
# Since June 2020, python's recommendation for creating a package is to specify package information in a `pyproject.toml` file.
89+
# Older projects used a `setup.py` or `setup.cfg` file instead - and in fact the new `pyproject.toml` file in many ways mirrors this old format.
90+
# A lot of projects and packages have not yet switched over from `setup.py` to `pyproject.toml`, so don't be surprised to see a mixture of the two formats when you're looking at other people's packages.
91+
92+
# %% [markdown]
93+
# For our `greetings` package, right now we are adding only the name of the package and its version number.
94+
# This information is included in the `project` section of our `pyproject.toml` file.
95+
#
96+
# But we also need to tell users how to build the package from these specifications.
97+
# This information is specified in the `build-system` section of our `toml` file.
98+
# In this case, we'll be using `setuptools` to build our package, so we list it in the `requires` field.
99+
# We also need `setuptools_scm[toml]` so that `setuptools` can understand the settings we give it in our `.toml` file, and `wheel` to make the package distribution.
88100
#
89-
# To make python code into a package, we need to write a `setup.py` file. For now we are adding only the name of the package and its version number.
101+
# Finally, we can set specific options for `setuptools` using additional sections in `pyproject.toml`: in this case, we will tell `setuptools` that it needs to find **and include** all of the files in our `greetings` folder.
90102

91103
# %%
92-
# %%writefile greetings_repo/setup.py
104+
# %%writefile greetings_repo/pyproject.toml
105+
106+
[project]
107+
name = "Greetings"
108+
version = "0.1.0"
109+
110+
[build-system]
111+
requires = ["setuptools", "setuptools_scm[toml]>=6.2", "wheel"]
93112

94-
from setuptools import setup, find_packages
113+
[tool.setuptools.packages.find]
114+
include = ["greetings*"]
95115

96-
setup(
97-
name="Greetings",
98-
version="0.1.0",
99-
packages=find_packages(),
100-
)
116+
[tool.setuptools_scm]
101117

102118

103119
# %% [markdown]
@@ -109,7 +125,7 @@
109125

110126
# %% [markdown]
111127
#
112-
# And the package will be then available to use everywhere on the system. But so far this package doesn't contain anythin and there's nothing we can run! We need to add some files first.
128+
# And the package will be then available to use everywhere on the system. But so far this package doesn't contain anything and there's nothing we can run! We need to add some files first.
113129
#
114130

115131
# %% [markdown]
@@ -256,20 +272,25 @@ def process():
256272
# %% [markdown]
257273
# This allows us to create a command to execute part of our library. In this case when we execute `greet` on the terminal, we will be calling the `process` function under `greetings/command.py`.
258274
#
275+
# We can encode this into our package information by specifying the `project.scripts` field in our `pyproject.toml` file.
259276

260277
# %%
261-
# %%writefile greetings_repo/setup.py
278+
# %%writefile greetings_repo/pyproject.toml
262279

263-
from setuptools import setup, find_packages
280+
[project]
281+
name = "Greetings"
282+
version = "0.1.0"
264283

265-
setup(
266-
name="Greetings",
267-
version="0.1.0",
268-
packages=find_packages(),
269-
entry_points={
270-
'console_scripts': [
271-
'greet = greetings.command:process'
272-
]})
284+
[project.scripts]
285+
greet = "greetings.command:process"
286+
287+
[build-system]
288+
requires = ["setuptools", "setuptools_scm[toml]>=6.2", "wheel"]
289+
290+
[tool.setuptools.packages.find]
291+
include = ["greetings*"]
292+
293+
[tool.setuptools_scm]
273294

274295
# %% language="bash"
275296
# cd greetings_repo
@@ -294,7 +315,7 @@ def process():
294315
# ### Specify dependencies
295316

296317
# %% [markdown]
297-
# Let's give some live to our output using ascii art
318+
# Let's give some life to our output using ascii art
298319

299320
# %%
300321
# %%writefile greetings_repo/greetings/command.py
@@ -324,23 +345,29 @@ def process():
324345
process()
325346

326347
# %% [markdown]
327-
# We use the setup.py file to specify the packages we depend on using `install_requires`:
348+
# We use the `dependencies` field of the `project` section in our `pyproject.toml` file to specify the packages we depend on.
349+
# We provide the names of the packages as a list of strings.
328350

329351
# %%
330-
# %%writefile greetings_repo/setup.py
352+
# %%writefile greetings_repo/pyproject.toml
353+
354+
[project]
355+
name = "Greetings"
356+
version = "0.1.0"
357+
dependencies = [
358+
"art",
359+
]
331360

332-
from setuptools import setup, find_packages
361+
[project.scripts]
362+
greet = "greetings.command:process"
333363

334-
setup(
335-
name="Greetings",
336-
version="0.1.0",
337-
packages=find_packages(),
338-
install_requires=['art', 'pyyaml'],
339-
entry_points={
340-
'console_scripts': [
341-
'greet = greetings.command:process'
342-
]}
343-
)
364+
[build-system]
365+
requires = ["setuptools", "setuptools_scm[toml]>=6.2", "wheel"]
366+
367+
[tool.setuptools.packages.find]
368+
include = ["greetings*"]
369+
370+
[tool.setuptools_scm]
344371

345372
# %% [markdown]
346373
# When installing the package now, pip will also install the dependencies automatically.
@@ -569,23 +596,36 @@ def test_greeter(fixture):
569596
# pytest --doctest-modules
570597

571598
# %% [markdown]
572-
# Finally, if we don't want to include the tests when we distribute our software for our users, you can include that using the `exclude` option on `find_packages` on `setup.py`.
599+
# Finally, we typically don't want to include the tests when we distribute our software for our users.
600+
# We can make sure they are not included using the `exclude` option on when telling `setuptools` to find packages.
601+
#
602+
# Additionally, we can make sure that our README and LICENSE are included in our package metadata by declaring them in the `readme` and `license` fields under the `project` section.
603+
# If you're using a particularly common or standard license, you can even provide the name of the license, rather than the file, and your package builder will take care of the rest!
573604

574605
# %%
575-
# %%writefile greetings_repo/setup.py
576-
577-
from setuptools import setup, find_packages
578-
579-
setup(
580-
name="Greetings",
581-
version="0.1.0",
582-
packages=find_packages(exclude=['*.test']),
583-
install_requires=['art', 'pyyaml'],
584-
entry_points={
585-
'console_scripts': [
586-
'greet = greetings.command:process'
587-
]}
588-
)
606+
# %%writefile greetings_repo/pyproject.toml
607+
608+
[project]
609+
name = "Greetings"
610+
version = "0.1.0"
611+
readme = "README.md"
612+
license = { file = "LICENSE.md" }
613+
dependencies = [
614+
"art",
615+
"pyyaml",
616+
]
617+
618+
[project.scripts]
619+
greet = "greetings.command:process"
620+
621+
[build-system]
622+
requires = ["setuptools", "setuptools_scm[toml]>=6.2", "wheel"]
623+
624+
[tool.setuptools.packages.find]
625+
include = ["greetings*"]
626+
exclude = ["tests*"]
627+
628+
[tool.setuptools_scm]
589629

590630
# %% [markdown]
591631
# ### Developer Install

0 commit comments

Comments
 (0)