For installed packages, use stdlib importlib.metadata.requires. Python 3.8+ is required, but there is a backport importlib-metadata for older Python versions. This is the easy case, because installed packages have already generated the metadata (including dependency specs) at installation time. For local source trees which aren't necessarily installed, read on.
There is a way to do this in Python APIs via distutils (which setuptools wraps):
import distutils.core
dist = distutils.core.run_setup("setup.py")
for req in dist.install_requires:
print(req)
As a shell command that might look like:
python -c 'import distutils.core; print(*distutils.core.run_setup("setup.py").install_requires, sep="\n")'
It is also possible to use the CLI to generate egg-info and then read deps from that:
python setup.py egg_info
cat myproject.egg-info/requires.txt
However, distutils is deprecated and setuptools is trying to be a library only, so using setup.py in this way is quite neglected.
You might consider moving to declarative dependencies specified in pyproject.toml and then just reading the requirements directly with a simple TOML parser.
"attrs==21.4.0 ; python_version < '3.9'", "attrs>=22 ; python_version >= '3.9'"in the setup.py file, mirroring the requirements.txt file. If a new version is released that works universally it would be best to keep the setup.py file in sync with requirements.txt (which is used in CI).setup.pycommand for this as far as I know, and setuptools no longer wants to be in the business of providing a command line interface, so it won't ever happen. Maybeimportlib.metadata.requirescan help? However, it does require the package to be installed (there are some hackarounds to trick it into thinking a package is installed if you need)!=instead.