pip's default upgrade strategy is only-if-needed, in effect since pip 10. pip install --upgrade requests upgrades requests and touches its dependencies only when the resolver cannot satisfy the new requirement with what is already installed. Running the command and then finding urllib3 still on a two-year-old release is the documented behaviour, not a failure.
This surprises people migrating from tools that upgrade transitively. The visible symptom is a security advisory that stays unfixed after the upgrade because the vulnerable package is a dependency, not the thing you named.
--upgrade-strategy eager upgrades every dependency to the newest compatible version, at the cost of pulling in far more change than you asked for. The more predictable path is to stop upgrading in place: regenerate a fully pinned requirements file with pip-tools or uv, then pip install -r it into a clean environment. Use pip install --dry-run --upgrade first to see exactly which distributions would change before committing to either strategy.