pip 22.2 added --dry-run, and --report writes the resolution as JSON. Combined, pip install --dry-run --report resolution.json -r requirements.txt resolves the full dependency graph, downloads nothing into the environment, and emits every selected distribution with its exact version, the URL it would come from, and whether it is a direct requirement.
This is the cheapest way to answer two questions that otherwise require a throwaway container: what would actually change, and which index each artefact comes from. Passing - as the report path writes the JSON to stdout.
The report format carries a version field and is documented as stable within a major version, so it is safe to parse in a script. Practical uses are a CI job that fails when a resolution pulls anything from an unexpected host, a pre-merge diff of the old and new resolution to review dependency churn, and confirming that a constraints file actually took effect. Note that a dry run still needs metadata, so it may build sdists that do not publish wheels.