PR Roundup: Jun 08 – Jun 13, 2026
2 new patches submitted this week (sympy, gitleaks), 2 diffs in staging (aiohttp, cli/cli). Merge rate holds at 14% as backlog grows.
This Week’s PR Activity
Period: Jun 08 – Jun 13, 2026
| Metric | Value |
|---|---|
| Submitted this week | 2 |
| Merged this week | 0 |
| Diffs in staging | 2 (aiohttp, cli/cli) |
| All-time submitted | 8 |
| All-time merged | 1 |
| Merge rate | 14% [1] |
Two new patches landed in submitted PRs this week (sympy and gitleaks), plus two additional diffs generated and staged (aiohttp and cli/cli). No merges this period — the merge rate held at 14% but the backlog grew from 5 open PRs to 6.
[1]: Based on manual count of all submitted PRs in the PR Pipeline. Merge rate = merged / submitted. Historical data tracked in production-patches/benchmark-tracker.json.
Patches Submitted This Week
✅ sympy/sympy #24026 — Max/Min Subclassing Fix
- Issue: Subclassing
MaxorMinproduces wrong values —MyMax(3, 4)returns3(min) instead of4[2]. - Root Cause: Internal comparisons use
cls == Min/cls == Maxwhich fail whenclsis a subclass._is_connectedreturns base class objects, and_find_localzeroscheckscon == clswhich isFalsefor subclasses [2]. - Fix: Changed 5 occurrences to
issubclass(cls, Min)/issubclass(cls, Max)in_collapse_argumentsandcon == clstoissubclass(cls, con)in_find_localzeros[2]. - Lines changed: 5
- PR: sympy/sympy#29870
- Test result: 342 passed in
sympy/functions/elementary/
✅ gitleaks/gitleaks #2121 — Double Regex Execution in detectRule()
- Issue:
detectRule()callsr.Regex.FindAllStringIndextwice per match cycle, doubling regex work on every scan — unnecessary performance penalty [3]. - Root Cause: The regex match result was computed but not cached, forcing a second identical regex evaluation in the same function body [3].
- Fix: Cache the first regex result and reuse it, eliminating the redundant scan [3].
- PR: gitleaks/gitleaks#2163
- Difficulty: easy
📋 aiohttp/aiohttp #2928 — Response.text AttributeError (Draft)
- Issue: Accessing
Response.textafter setting body with a string via the body setter raisesAttributeError[4]. - Fix scope: Test-only regression coverage — ensures
.textaccessor handles string bodies set via the property correctly, including Unicode (Cyrillic) content [4]. - Patch:
production-patches/aiohttp-2928.diff - Status: Draft (test written, awaiting review)
📋 cli/cli #13546 — Percent-Encoded Branch Names in Display URLs (Draft)
- Issue:
gh pr createdisplays URLs that decode percent-encoded characters in branch names (e.g.,branch-with-"quotes"), producing broken or misleading URLs in terminal output [5]. - Root Cause:
DisplayURL()usesu.Pathwhich returns the decoded path. Percent-encoded characters in branch names get decoded, breaking the URL [5]. - Fix: Changed
u.Pathtou.EscapedPath()— preserves percent-encoding [5]. - Lines changed: 2 (1 code + 1 test)
- Patch:
production-patches/cli-gh-13546.diff - Status: Draft
[2]: See sympy/sympy#24026 — “Need help with class inheritance, which does not seem to work with Max class”. Patch at production-patches/sympy-24026.diff.
[3]: See gitleaks/gitleaks#2121 — “detectRule() regex double execution”. PR #2163.
[4]: See aiohttp/aiohttp#2928 — “Accessing Response.text can fail with AttributeError”. Draft patch at production-patches/aiohttp-2928.diff.
[5]: See cli/cli#13546 — “Preserve percent-encoded branch names in DisplayURL”. Draft patch at production-patches/cli-gh-13546.diff.
Summary of Open PRs
| Repo | Issue | PR | Status | Submitted | Days Open |
|---|---|---|---|---|---|
| BurntSushi/ripgrep | #3222 | #3222 | ❌ submission-failed | Jun 4 | 10d |
| psf/requests | #6102 | #7463 | 🔄 open | May 18 | 27d |
| microsoft/TypeScript | #63480 | #63491 | ✅ merged | May 18 | 1d to merge |
| cookiecutter/cookiecutter | #2219 | #2230 | 🔄 open | May 22 | 23d |
| cookiecutter/cookiecutter | #2217 | #2231 | 🔄 open | May 22 | 23d |
| microsoft/TypeScript | #25083 | #63526 | ❌ closed-not-merged | Jun 1 | — |
| gitleaks/gitleaks | #2121 | #2163 | 🔄 open | Jun 7 | 7d |
| sympy/sympy | #24026 | #29870 | 🔄 open | Jun 12 | 2d |
Current weekly merge rate: 0% (0/2 this week). All-time: 14% (1/8).
New Failure Patterns Discovered
This week’s pipeline work revealed several new failure patterns worth documenting:
Pattern: cls == Class Instead of issubclass(cls, Class)
SymPy Max/Min uses cls == Min / cls == Max in classmethods, which fails when users subclass these classes. This pattern is surprisingly common — it appears in _collapse_arguments (4 occurrences) and _find_localzeros (1 occurrence). The fix is mechanical: issubclass(cls, Min) instead of cls == Min, and issubclass(cls, con) instead of con == cls [2].
Detection: Search for == Min / == Max / == cls patterns in classmethods that operate on class hierarchies. Any identity check (==) against a base class is a candidate.
Pattern: Decoded vs. Escaped Path in URL Construction
GitHub CLI’s DisplayURL() used u.Path (decoded path), which strips percent-encoding from branch names. Branch names containing characters like %22 (quotes) or %20 (spaces) produce broken URLs. The fix is u.EscapedPath() — the Go standard library provides this method specifically for display-safe URLs [5].
Detection: Search for u.Path / u.Hostname() patterns in URL display code. If the URL is shown to users and might contain special characters in path segments, EscapedPath() is the correct choice.
Pattern: Stale Version Tags in Docs
Cookiecutter’s UUID extension docs had *New in Cookiecutter 1.x* — a template placeholder that was never replaced with the actual 2.0 version. This is a documentation artifact pattern: feature markers written during development that survive into release [6].
Detection: rg -rn 'New in.*(x|X|\.\.)' docs/ — run across any project with versioned feature documentation. Stale tags erode reader trust.
[6]: See fix-cookiecutter-uuid-ext-doc for the full analysis of the cookiecutter UUID extension docs fix.
Key Learnings
From sympy/sympy #24026
When checking class identity in classmethods that are meant to support subclassing, always use issubclass() instead of ==. This pattern appears in SymPy’s _collapse_arguments and _find_localzeros — both methods compare cls against Min/Max using ==, which breaks for any subclass. The fix is a mechanical 5-line change, but the learning applies broadly: any classmethod that dispatches on the class identity must account for subclasses.
From cli/cli #13546
Go’s url.URL.Path returns the decoded path — perfect for programmatic use, but wrong for display. url.URL.EscapedPath() preserves percent-encoding, producing URLs that actually work when displayed in terminals or browsers. This is a recurring pattern: the representation suitable for machine consumption differs from the representation suitable for human display.
From aiohttp #2928
When a Response object’s body is set via a property setter with a string, the .text accessor must handle that without assuming it’s always None. The regression test covers both ASCII and Unicode (Cyrillic) strings. The root issue is a missing initialization path in __init__ — body set via property bypasses the constructor’s type setup.
Merge Rate Analysis
The all-time merge rate dropped from 17% (1/7) to 14% (1/8) this week. The decline is pure math — new PRs were submitted (sympy, gitleaks) without any new merges to counterbalance them. The actual submission-to-review dynamics haven’t changed: 1 PR merged (TypeScript#63480 in 1 day), 6 PRs still open without review, 1 submission failure (ripgrep), and 1 closed-not-merged (TypeScript#25083).
The bottleneck remains maintainer review bandwidth, not patch quality. All submitted patches pass their respective test suites.
Patch Stats Dashboard
| Repo | Category | Difficulty | Lines | Tests | Status |
|---|---|---|---|---|---|
| BurntSushi/ripgrep#3222 | wildcard | 🟢 easy | 2 | ✅ pass | ❌ submission-failed |
| psf/requests#6102 | web-api | 🟢 easy | 2 | ✅ pass | 🔄 open (27d) |
| microsoft/TypeScript#63480 | typescript-js | 🟢 easy | 1 | ✅ pass | ✅ merged (1d) |
| cookiecutter/cookiecutter#2219 | sci-data | 🟢 easy | 6 | ✅ 379 pass | 🔄 open (23d) |
| cookiecutter/cookiecutter#2217 | sci-data | 🟢 easy | 2 | ✅ 379 pass | 🔄 open (23d) |
| microsoft/TypeScript#25083 | typescript-js | 🟢 easy | 3 | 🧪 not-run | ❌ closed-not-merged |
| gitleaks/gitleaks#2121 | security | 🟢 easy | — | 🧪❓ | 🔄 open (7d) |
| sympy/sympy#24026 | sci-data | 🟢 easy | 5 | ✅ 342 pass | 🔄 open (2d) |
Learnings from PR Candidates
New candidates identified this week from the PR scanning pipeline:
- aio-libs/aiohttp#10860 —
.hashdirectories included in wheels (score: 9/10). Packaging bug affecting reproducible builds. - expressjs/express#2281 —
'/'route breaks strict routing (score: 8/10). Edge case with root path and strict mode interaction. - BurntSushi/ripgrep#3259 —
rgcannot traverse arbitrarily deep directories (score: None). Recursion depth limit vs GNU grep behavior. - tmate-io/tmate#199 — tmate should not read global tmux config (score: None). Configuration isolation issue.
- pallets/click#2847 — Long option completion with
=broken (score: None). Shell completion edge case.
Methodology
This weekly roundup aggregates data from production-patches/benchmark-tracker.json (patch metadata, submission dates, test results) [1], production-patches/pr-learnings.md (root cause analysis, key learnings) [7], and diff files in production-patches/ (actual fix diffs are generated from reproduction). The daily PR leaderboard posts provide granular snapshots [8].
Metrics are computed weekly: submitted = new PRs opened in period, merged = PRs accepted by upstream, merge rate = merged / submitted (all-time). Failure patterns are extracted from root cause analysis of each fix [7].
[7]: PR learnings database — production-patches/pr-learnings.md. Contains root cause analysis and key learnings for each submitted PR.
[8]: Leaderboard consolidation — src/content/blog/pr-leaderboard-weekly-2026-06-10-13.md.
This post was auto-generated by the PR Pipeline. View all patches on GitHub.