Skip to main content

Case Study

I Ran Refactron on the Requests Library. Here's What It Found.

ShrutiFebruary 15, 2026

The Requests library is one of the most downloaded Python packages in existence. Kenneth Reitz released the first version in 2011 with the explicit goal of making HTTP "for humans." Fourteen years later it has over 50,000 GitHub stars, ships inside major cloud SDKs, and gets installed roughly 400 million times a month.

It's also a relatively small codebase — around 15,000 lines of Python. Which makes it a more interesting test for Refactron than Django. Fewer lines means the findings are more concentrated. If something surfaces here, it's probably worth paying attention to.

Setup

git clone https://github.com/psf/requests
cd requests
pip install refactron
refactron analyze .

Ran in under 8 seconds. Small codebase, fast analysis.

What it found

Complexity in the core session logic. requests/sessions.py is where the most interesting findings landed. The send() method in particular has grown to handle a significant number of conditional paths — redirect handling, adapter resolution, environment proxy logic, certificate verification. Each individual branch makes sense in context. Taken together the function is doing a lot, and the complexity score reflects that.

This is a well-known pattern in mature HTTP libraries. The session layer has to be the integration point for everything, so it accumulates branches. Not broken, but the kind of function a new contributor will spend real time understanding before feeling confident touching it.

Unused imports in test files. A handful of imports in the test suite that aren't referenced in the files they live in. Minor, the kind of thing that accumulates over years of test additions and refactors. The autofix step handles these confidently — safe changes with no behavioral implications.

Long parameter lists in adapter methods. A few internal methods have parameter lists that have grown as new features were added over the years. Again, not broken — but a signal that the API surface has expanded incrementally without a corresponding restructuring pass.

The autofix run

refactron autofix . --verify --dry-run

Dry run first — shows what would change without writing anything.

For the unused imports in test files, Refactron was confident: clean removals with no downstream references, syntax check passes, import graph unchanged. These would apply safely.

For the complexity issues, it flagged and stopped. The send() method in sessions touches too many things for automated decomposition to be safe without deeper context about the intended behavior of each path. Refactron surfaces the information. The decision stays with the maintainers.

This is the right call. Requests is a public API with external consumers who depend on exact behavior. Automated structural changes without exhaustive context would be the wrong move, and the tool knows it.

What the output actually looks like

✓ Analyzing requests/

Files analyzed: 31
Issues found: 9

MEDIUM (4):
  High cyclomatic complexity
  sessions.py:457  — score: 14
  sessions.py:298  — score: 11

LOW (5):
  Unused imports
  tests/test_utils.py:3
  tests/test_hooks.py:7
  tests/test_structures.py:2

Clean, specific, actionable. No noise.

The takeaway

Requests is a codebase that's been maintained carefully for a long time. The findings Refactron surfaces are the expected residue of organic growth — complexity concentrating in integration points, minor cruft in test files, parameter lists that expanded without a corresponding cleanup pass.

None of this is alarming. All of it is useful orientation for anyone working in the codebase for the first time, or for a team using Requests as a dependency who wants to understand where the risk lives.

The more interesting implication is for codebases that haven't been maintained as carefully. If Refactron finds nine issues in one of the most scrutinised small Python libraries in existence, it will find considerably more in a three-year-old internal service that hasn't had a dedicated maintainer since the engineer who wrote it moved on.

That's the actual target. The open-source runs are a calibration exercise.

Try it on yours

pip install refactron
refactron analyze .

Nothing changes. See what's there.

Next in this series: FastAPI — modern codebase, different patterns, different findings.

RequestsCase StudyPythonCode Analysis
1624 views58 clicks