porting-py2-to-py3

porting-py2-to-py3 is a skill for Claude Code, Codex from fgmacedo/agent-skills. It costs 166 tokens per session (6,736 once invoked), scanned A, original, MIT.

A staged method for moving a Python 2.7 codebase to Python 3 while development continues. Python is a programming language, and the workflow covers tools, dependencies, tests, rollout, and rollback.

In plain words
What is it for?
Use it to choose a target Python version, update dependencies, convert code, handle changes that need human judgment, and switch interpreters only after the codebase is ready. It is intended for teams that must keep shipping during the migration.
Why use it?
It reduces the risk of a large, disruptive interpreter change by keeping the application working through small steps and CI checks. CI, or continuous integration, automatically builds and tests changes as they are made.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one.

Good fit Use it to choose a target Python version, update dependencies, convert code, handle changes that need human judgment, and switch interpreters only after the codebase is ready. It is intended for teams that must keep shipping during the migration.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/fgmacedo/agent-skills/porting-py2-to-py3
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add fgmacedo/agent-skills --skill porting-py2-to-py3
Clone the repo
git clone --depth 1 https://github.com/fgmacedo/agent-skills

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for porting-py2-to-py3

README.md
[![agentmods](https://agentmods.dev/badge/skills/fgmacedo/agent-skills/porting-py2-to-py3/github.svg)](https://agentmods.dev/skills/fgmacedo/agent-skills/porting-py2-to-py3)
Your own site
<a href="https://agentmods.dev/skills/fgmacedo/agent-skills/porting-py2-to-py3"><img src="https://agentmods.dev/badge/skills/fgmacedo/agent-skills/porting-py2-to-py3/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for porting-py2-to-py3

Your own site · 80×15
<a href="https://agentmods.dev/skills/fgmacedo/agent-skills/porting-py2-to-py3"><img src="https://agentmods.dev/badge/skills/fgmacedo/agent-skills/porting-py2-to-py3.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 166 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 6,736 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00166 $0.06736
Opus 5.5 $0.00066 $0.02694
Sonnet 5.5 $0.00033 $0.01347
Haiku 4.5 $0.00017 $0.00674

Measured 4d ago against content hash 03a929b8f286, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

porting-py2-to-py3 scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 4d ago.

The scan reads SKILL.md. This mod also ships 3 executable files (scripts/py2ism_census.py, scripts/py3_compile_gate.sh, scripts/uncovered_risk_lines.py), listed below but not scanned — reading those needs a real analyzer, not pattern matching.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

skills/porting-py2-to-py3/SKILL.md · 240 lines

How it starts

The opening of the file, as written. The whole thing — 240 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Porting Python 2 to Python 3

Core principle: the port lands on the main branch as Python-2-compatible commits, behind CI gates that only ratchet forward; the interpreter switch is the last, smallest step. Code changes are cheap. What is expensive is production risk, calendar (soak windows, other teams' reviews) and the attention of the team that keeps shipping on the same tree.

Before you start

  • Read references/target-version.md to choose the target. Default in late 2026: 3.13, with 3.14 as a go/no-go once the suite is green. Never pick an EOL version, and never assume a framework version "won't run" on a newer interpreter: measure it (Phase 0, step 5).
  • Read references/tooling.md for the converter, the interpreter flags, the pins of the last py2-compatible versions, and which tools are dead (do not recommend caniusepython3, pylint --py3k on pylint 2.x, futurize --stage2, or the future runtime).
  • Read references/catalog.md when fixing a specific idiom. It classifies every change as M (a tool rewrites it) or J (decide per site with the stated procedure).
  • references/case-studies.md has the tactics behind this workflow (Instagram, Dropbox, Yelp, Mercurial).
  • OPTIONAL PRE-PHASE: removing-dead-code (sibling skill). Every function, route, job and dependency removed is one fewer to port and verify.

Phase 0: safety net and measurements (on main)

Done when: the environment is reproducible, CI publishes coverage and fails on regression, golden tests exist for every persisted invariant, and the spike has answered which interpreter the current framework chain runs on.

  1. Freeze what production really runs. pip freeze inside the production image becomes a versioned lockfile. Base images maintained elsewhere often install unpinned packages that the repo never names (SQLAlchemy, DB drivers, memcache clients). Those are dependencies too. If the base image belongs to another team, build your own from python:2.7.18-slim plus the lockfile now: the py3 image needs the same layout, and the switch stops depending on their calendar.
  2. Pick the target version with the decision rule in references/target-version.md. Write it into the project's README and agent instructions file in the same PR.
  3. Coverage as a gate. Run the suite with coverage (5.5 on py2, 7.x on py3) in CI, publish the number, set fail_under to the current value. Single-source code has lines only one interpreter can execute (if six.PY2:, an except ImportError fallback for a backport), so exclude them per leg with # pragma: py2 only / # pragma: py3 only and the .coveragerc in references/tooling.md, section 5; otherwise the number is capped below 100 and the gate cannot ratchet to the end. Start collecting coverage from production or staging now (see removing-dead-code for the multi-service design); the window must be long before Phase 2 needs it.
  4. Golden tests for cross-version invariants. Record outputs under py2 as fixtures and assert byte-equality under both interpreters: IDs derived from hashes or sys.maxint, signed tokens, encrypted payloads, cache keys, serialized exports (JSON, CSV, XLSX, PDF), URLs built from user data, anything parsed by another system. These are the tests that catch b'...' leaks and rounding drift before a deploy does.
  5. One-day spike. Build a py3 image on the target with the py2-compatible framework chain pinned (references/tooling.md, section 6) and import the chain in isolation, since the application still has py2 syntax at this point: python3 -c "import flask, flask_sqlalchemy, sqlalchemy, <driver>, <rest layer>, <event loop lib>" (Django: django.setup() plus migrate against sqlite) plus a minimal app factory smoke test. Expect the ceiling to differ by stack: the Flask 1.1 chain runs on 3.13, Django 1.11 stops at 3.9 (references/tooling.md, section 6). Check wheels for the target with pip download --only-binary=:all: --python-version 3XY --platform manylinux2014_x86_64 -r requirements.txt before building; a C extension without a wheel for the target either builds from source in the image or forces a split pin (step 6). If the chain imports on the target, the cutover changes only the interpreter. If it does not, cut over on the newest version it runs on and make the framework upgrade the next project. One variable at a time. The -t tests stage of the compile gate only becomes meaningful after Phase 1.
  6. Dependency inventory. For every package: last version with 2.7, first without, whether the pinned version imports on the target, and whether a wheel exists for the target. Internal packages without py3 builds go to their owners now; they are the calendar risk. Archived upstreams get a fork (references/tooling.md, section 7). A package that cannot straddle both interpreters (its last py2 release has no build for the target: pandas 0.24, numpy 1.16, often psycopg2 2.8 and mysqlclient 1.4 without source builds) gets a split pin by environment marker, pkg==old; python_version<"3" and pkg==new; python_version>="3", code restricted to the API subset both versions share, and golden tests for its outputs. From this point: no new package without py3 support.
  7. Baseline the census. python3 scripts/py2ism_census.py SRC --save py2ism-baseline.json and add --check to CI. Teammates cannot add Python 2 idioms from now on.

Read the full file on GitHub · 240 lines

Files

What ships with it

7 files beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 4d ago Changed · +31 lines 03a929b8f286
  2. 5d ago First seen · 209 lines · 166 tokens per session scan A 1a07baf188f1

Subscribe to this mod's changes

porting-py2-to-py3 is a skill published in the GitHub repository fgmacedo/agent-skills (10 stars, last pushed 5d ago), licensed MIT. It adds 166 tokens to every session and 6,736 once invoked, about $0.0007 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-10-13.

Related

Other skills, from other repositories

temporal-python-testing

Test Temporal workflows with pytest, time-skipping, and mocking strategies. Covers unit testing, integration testing, replay testing, and local development setup. Use when implementing Temporal workflow tests or debugging test failures.

wshobson/agents · 45 tokens

test-corpus

The testdocuments submodule is a bucket-fetched fixture corpus that is not committed. This skill covers readtestfixture, missing fixtures, valid A/B controls, and submodule push order. Load before running Rust tests on a fresh clone, setting up an A/B control, adding a fixture-backed test, or diagnosing…

xberg-io/xberg · 68 tokens

python-providers

Create, modify, test, or package Python provider adapters under python/providers, including framework-specific dependencies, public imports, type inference, and provider metadata. Use for Python provider work only; use python-sdk for core SDK changes.

ComposioHQ/composio · 49 tokens

adk-verify-snippets

Checks that every Python code block in a Markdown file actually compiles and runs, by extracting each block to a temporary file, executing it in an isolated subprocess, and writing a pass/fail report with per-snippet coverage. Use when the user asks to verify, test, or validate the code samples in a README, a guide…

google/adk-python · 149 tokens

adk-setup

Sets up a local ADK Python development environment in a git clone of the open-source adk-python repository: a uv virtual environment, all dependency extras, pre-commit hooks, and a first unit-test run. Runs only when explicitly requested, never on its own. Use when asked to set up, bootstrap, or repair a development…

google/adk-python · 146 tokens

maintaining-python-tests

Maintains existing pytest and Django test suites without weakening correctness. Use when asked to reduce Python test runtime or CI work, investigate slow pytest families, remove stale migration tests, consolidate repeated setup, improve Python test ownership, or measure whether a test optimization worked after merge.…

PostHog/posthog-foss · 110 tokens