Skip to content

literalinclude directives #239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 107 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This is a community resource. We welcome contributions in the form of issues and
* If you find a typo, feel free to [submit a pull request](https://github.com/pyOpenSci/python-package-guide/pulls) to modify the text directly. Or, if you are less comfortable with pull requests, feel free to open an issue.
* If you want to see a larger change to the content of the guide book, please submit an issue first!

## How this guide structured
## How this guide is structured

Most of this repository is structured for **Sphinx**, a documentation engine built in `Python`. We are using the Sphinx Book Theme and the `myST` syntax to create each page in this book.

Expand All @@ -31,18 +31,121 @@ To do so, follow these steps:
1. Install `nox`

```
pip install nox
python -m pip install nox
```
2. Build the documentation:

```
nox -s docs
python -m nox -s docs
```

This should create a local environment in a `.nox` folder, build the documentation (as specified in the `noxfile.py` configuration), and the output will be in `_build/html`.
The site can then be viewed locally by opening the top level `index.html` in your web browser. The exact location of this file will depend on you system, but the output of the following command could be copied into an address bar

```
echo "file://$(pwd)/_build/html/index.html"
```

To build live documentation that updates when you update local files, run the following command:

```
nox -s docs-live
python -m nox -s docs-live
```

When build like this, the output will tell you a localhost address where the site can be viewed, generally http://127.0.0.1:8000.

## Code examples

This guide uses the [literalinclude Sphinx directive](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-literalinclude)
whenever possible to keep code and prose separate. Code for use in the documentation is kept in the `examples/` folder.

### Referencing code in documentation

If an example is present elsewhere in the documentation that you want to use, you can copy the `literalinclude`
directive verbatim and the examples will stay in sync.

If you already see code in the examples folder that you can use for new documentation, a new `literalinclude` can be
made to extract it into the site. Only a relative path to the code is required for a working `literalinclude`, but you
should in almost all cases also provide a `:language:` and `:lines:`. The former makes code examples prettier, and the
later can protect your example from future modifications to the code.

**Pro tip**: As an alternative to `:lines:` there are also the `:start-after:`, `:start-at:`, `:end-before:`, and
`:end-at:` options. And if the example code is Python, `:pyobject:` can be an even more future-proof way to keep the
same documentation content even through code refactors.

If you need example code that doesn't yet exist in `examples/` [see creating code for documentation](#creating-code-for-documentation).

### Creating code for documentation

Whenever you come across a place that could benefit from a code block, instead of writing it in-line with a code fence
(`` ``` `` blocked text) you can write it as a file in its own format. Your example may even already exist; [see referencing code in documentation
](#referencing-code-in-documentation).

If you want to add a new example that doesn't fit into any of the existing example files, you can create a new file and
reference it in a `literalinclude` block. If it makes sense for that file to live within one of the existing example
projects please add it there; otherwise create a new folder in the `examples` directory.

If an existing example is incomplete or a new example makes sense to be added to an existing file, go ahead and add it,
but take care to not break the rest of the guide. Whenever possible, extend the example rather that rewrite it. So for
instance, add new functions to the end of the file, new methods after all existing ones in a class.

Example code is checked for correctness, so adding a new example may require adding additional tests for coverage, and
will require fixing any failing tests.

***⚠️ WARNING***: great care should be taken when modifying existing example code, especially any modification beyond
appending to the end of the file. All code examples are (potentially) shared examples. This makes for more consistent
examples in the guide but can mean action-at-a-distance when modifying the examples for one particular use case.
If you find yourself modifying existing examples try running this command and then checking those pages in a new build.
```bash
grep -lr '\.\./examples/path/to/modified\.py' documentation/
```

Example:

Instead of writing example code in markdown like this

````md
Here is an example Python function:

```python
def is_empty(x):
return not bool(len(x))
```
````

The python can be extracted into a `.py` file
```python
def is_empty(x):
return not bool(len(x))
```

````md
Here is an example Python function:

:::{literalinclude} ../examples/contributing_example.py
:language: python
:lines: 1-2
````

As another example, if you only need to show part of a `pyproject.toml`, we already have complete project definitions,
you need only to find the relevant part.

Instead of writing this
````md
Classifiers are just a list of plain strings
```toml
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
]
```
````

an example could be extracted from an existing toml file
```md
:::{literalinclude} ../examples/pure-hatch/pyproject.toml
:language: toml
:start-at: classifiers = [
:end-at: ]
```
38 changes: 38 additions & 0 deletions examples/pure-hatch/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "examplePy"
authors = [
{name = "Some Maintainer", email = "[email protected]"},
]
maintainers = [
{name = "All the contributors"},
]
description = "An example Python package used to support Python packaging tutorials"
keywords = ["pyOpenSci", "python packaging"]
readme = "README.md"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
]
dependencies = [
"dependency-package-name-1",
"dependency-package-name-2",
]

[project.optional-dependencies]
tests = [
"pytest",
"pytest-cov"
]
lint = [
"black",
"flake8"
]
docs = [
"sphinx",
"pydata-sphinx-theme"
]
24 changes: 24 additions & 0 deletions examples/pure-setuptools/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"

[project]
name = "examplePy"
authors = [
{name = "Some Maintainer", email = "[email protected]"},
]
maintainers = [
{name = "All the contributors"},
]
description = "An example Python package used to support Python packaging tutorials"
keywords = ["pyOpenSci", "python packaging"]
readme = "README.md"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
]
dependencies = [
"dependency-package-name-1",
"dependency-package-name-2",
]
102 changes: 23 additions & 79 deletions package-structure-code/pyproject-toml-python-package-metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ Below that table identifier are key/value pairs that
support configuration for that particular table.

- Below `[build-system]` is considered a table in the toml language.
- Within the build-system table below requires = is a key.
- The associated value for requires is an array containing the value "hatchling".
- Within the `build-system` table below `requires =` is a key.
- The associated value for `requires` is an array containing the value `"hatchling"`.

```toml
[build-system] # <- this is a table
requires = ["hatchling"] # requires = is a key and "hatchling" is a value contained within an array specified by square brackets [].

```
:::{literalinclude} ../examples/pure-hatch/pyproject.toml
:language: toml
:start-at: [build-system]
:end-at: requires = [
:::

### How the pyproject.toml is used when you build a package

Expand Down Expand Up @@ -160,11 +160,11 @@ what dependencies your package requires.
- **Authors:** these are the original authors of the package. Sometimes the authors are different from the maintainers. Other times they might be the same.
- **Maintainers:** you can choose to populate this or not. You can populate this using a list with a sub element for each author or maintainer name, email

```toml
authors = [
{name = "A. Random Developer", email = "[email protected]" }
]
```
:::{literalinclude} ../examples/pure-hatch/pyproject.toml
:language: toml
:start-at: authors = [
:end-at: ]
:::

- **dependencies:** dependencies are optional but we strongly suggest you include them in your pyproject.toml. Dependencies will be installed by pip when your project is installed creating a better user-experience.

Expand Down Expand Up @@ -194,21 +194,10 @@ To add dependencies to your build, add a `[project.optional-dependencies]` table

Then specify dependency groups as follows:

```
[project.optional-dependencies]
tests = [
"pytest,
"pytest-cov"
]
lint = [
"black",
"flake8"
]
docs = [
"sphinx",
"pydata-sphinx-theme
]
```
:::{literalinclude} ../examples/pure-hatch/pyproject.toml
:language: toml
:start-at: [project.optional-dependencies]
:::

Following the above example, you install dependencies like this:

Expand All @@ -232,32 +221,10 @@ You can also setup sets of recursive dependencies. [See this blog post for more.
Below is an example build configuration for a Python project. This example
package setup uses **hatchling** to build the [package's sdist and wheels](python-package-distribution-files-sdist-wheel).

```toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "examplePy"
authors = [
{name = "Some Maintainer", email = "[email protected]"},
]
maintainers = [
{name = "All the contributors"},
]
description = "An example Python package used to support Python packaging tutorials"
keywords = ["pyOpenSci", "python packaging"]
readme = "README.md"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
]
dependencies = [
"dependency-package-name-1",
"dependency-package-name-2",
]
```
:::{literalinclude} ../examples/pure-hatch/pyproject.toml
:language: toml
:end-before: [project.optional-dependencies]
:::

Notice that dependencies are specified in this file.

Expand All @@ -278,32 +245,9 @@ of values. It has two keys that specify the build backend API and containing pac
1. `requires =`
1. `build-back-end =`

```
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"

[project]
name = "examplePy"
authors = [
{name = "Some Maintainer", email = "[email protected]"},
]
maintainers = [
{name = "All the contributors"},
]
description = "An example Python package used to support Python packaging tutorials"
keywords = ["pyOpenSci", "python packaging"]
readme = "README.md"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
]
dependencies = [
"dependency-package-name-1",
"dependency-package-name-2",
]
```
:::{literalinclude} ../examples/pure-setuptools/pyproject.toml
:language: toml
:::

```{note}
[Click here to read about our packaging build tools including PDM, setuptools, Poetry and Hatch.](/package-structure-code/python-package-build-tools)
Expand Down
Loading