← Back to all products

Python 2 to 3 Migration Kit

$29

Incremental Python 2->3 (and legacy 3.x) migration playbook with the str/bytes boundary done right, 12 runnable before/after examples, a gotchas guide, and a per-module checklist.

📁 6 files🏷 v1.0.0 (updated 2026-08-02)
PythonMarkdownJSON

📄 Product Preview

Try the interactive reader and demo tools below, or get the full product with all content unlocked.

📖 Interactive Reader (Free Preview) 📦 Download Free Sample

📁 File Structure 6 files

python2to3-migration-kit/ ├── GOTCHAS.md ├── README.md ├── examples/ │ ├── before_after.py │ └── strbytes_examples.py └── tools/ └── checklist.md

📖 Documentation Preview README excerpt

Python 2 → 3 Migration Kit

A pragmatic kit for the migration nobody wants but many still face: moving a Python

2 codebase (or a legacy Python 3.4/3.6 one) to modern Python 3.11+. It's the map an

agent or engineer needs to do it incrementally and safely, not with a big-bang

rewrite that breaks everything at once.

The strategy: run on both, then drop 2

Big-bang migrations fail. This kit uses the proven incremental path:

1. Get to a 2and3 state — code that runs under both Python 2.7 and 3 using

__future__, six, and modernized idioms. Ship this; nothing breaks.

2. Add CI on Python 3 alongside Python 2 — catch regressions per commit.

3. Flip the default runtime to 3; keep 2 in CI briefly as a safety net.

4. Drop Python 2 — remove six, __future__, and 2-only shims.

What's inside

  • MIGRATION-GUIDE.md — the full incremental playbook with the order to do things.
  • GOTCHAS.md — the bugs that bite: str/bytes, integer division, dict views,

print, iterators, relative imports, unicode, exception syntax, sorting.

  • examples/before_after.py — 12 real before/after snippets of the common breakages.
  • examples/strbytes_examples.py — the str/bytes boundary done right (the #1 source

of production bugs), runnable under Python 3.

  • tools/checklist.md — per-module migration checklist + tooling (2to3, pyupgrade,

python-modernize, caniusepython3).

The single biggest trap: str vs bytes

In Python 2, str was bytes and "just worked" with text most of the time. In

Python 3 they're strictly separate. 80% of migration bugs are a str where bytes

are needed (or vice versa) — file I/O, sockets, hashing, subprocess, base64.

examples/strbytes_examples.py shows the correct patterns.

Requirements

Python 3.8+ to run the examples. The kit's advice applies to any 2→3 or legacy-3

modernization.

License

MIT.

📄 Code Sample .py preview

examples/before_after.py"""12 common Python 2 -> 3 breakages, before and after. Illustrative.""" # 1. print statement -> function # BEFORE: print "hello", x # AFTER: def ex_print(x): print("hello", x) # 2. integer division # BEFORE (py2): 3 / 2 == 1 # AFTER: use // for floor division explicitly def ex_div(): return 3 // 2, 3 / 2 # (1, 1.5) # 3. dict.keys()/values()/items() are views (not lists) def ex_dict(d): return list(d.keys()) # wrap in list() if you need a list # 4. iterators: map/filter/zip return iterators def ex_map(xs): return list(map(str, xs)) # 5. exception syntax # BEFORE: except Exception, e: # AFTER: def ex_except(): try: 1 / 0 except ZeroDivisionError as e: return str(e) # 6. unicode literal -> str (all str is unicode in py3) def ex_unicode(): return "café" # no u"" needed # 7. xrange -> range def ex_range(n): return sum(range(n)) # 8. relative imports must be explicit: from . import sibling # 9. has_key removed: 'k' in d (not d.has_key('k')) def ex_has_key(d): return "k" in d # 10. sorting: no cmp=; use key= def ex_sort(xs): return sorted(xs, key=lambda p: p[1]) # 11. next(): use next(it) not it.next() def ex_next(it): return next(it)
Buy Now — $29 Back to Products