PEP 723 is the standard that lets a single Python script declare its dependencies and required Python version in a comment block at the top of the file. A compatible runner reads the block and builds an environment before running. It removes the hidden "which packages did this script need?" problem, but it does not pin versions for you.
Why one-off scripts are a blind spot
Analytics teams write a lot of single files: a cleanup script, a quick export, a one-time backfill. They rarely get a requirements.txt. A year later nobody knows what the script imported, which versions it ran against, or whether any of them had advisories.
That matters for security because an unlisted dependency is an uninventoried dependency. If a vulnerability is published, you cannot answer "are we affected?" for code whose imports live only in someone's memory.
What the format looks like
The specification on packaging.python.org defines a block that starts with a line reading # /// script and ends with a line reading # ///. Every line in between is a comment holding TOML. For a script block, the fields are dependencies, a list of dependency specifiers, and requires-python, a version specifier.
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "pandas==2.2.3",
# "requests",
# ]
# ///
import pandas as pd
The version numbers above are only an example of the syntax. Choose the ones your script was tested with.
What the standard says, and what it leaves open
A few points from the specification are worth knowing:
- Tools that run the script must error if the listed dependencies cannot be provided.
- Tools may scan the file as text instead of parsing Python, so metadata-looking text inside a multi-line string may be handled differently by different tools.
- Only one block of a given type is allowed, and an unclosed block is ignored.
The standard does not say anything about hashes or lockfiles. A dependency list with loose ranges will resolve to whatever is newest at run time. For a script that touches production data, write exact versions, or keep a lock alongside it in your runner of choice.
A simple rule for analytics teams
- Every script that leaves a laptop gets a metadata block.
- Pin exact versions for anything that reads credentials or writes to shared storage.
- Record the block in review like any other code change, so a new dependency is visible in the diff.
- Retire scripts that nobody owns, rather than keeping them runnable.
This costs a minute per script and turns a pile of mystery files into something a scanner or a person can read.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how a dependency list becomes an inventory you can check against advisories.
Where Safeguard fits
Safeguard's dependency scanning and SBOM generation work from declared dependencies, so a script with an explicit list is easier to inventory than one without. You can try a free scan on a repository that holds your scripts.
Quick check
Does PEP 723 pin my dependencies?
No. It records what you list. If you write a loose range, the runner resolves it at run time. Use exact versions for anything sensitive.
Is the block executed as code?
No. It is a comment holding TOML that a tool reads. The script itself still runs normally once the environment exists.
Sources
Last reviewed: 19 October 2026.