Incrementally migrating over one million lines of code from Python 2 to Python 3

Bài tóm tắt Dropbox 2019 4. Điều chỉnh Độ khó: Trung bình

Dropbox · 2019 · 4. Điều chỉnh · Độ khó: Trung bình — bài gốc

Bài thứ hai của series; bài đầu kể build và rollout: Dropbox 2018.

Bối cảnh

  • App desktop Dropbox hơn 1 triệu dòng Python. Hack Week 2015 chạy được đăng nhập + sync trên Python 3 nhưng nhiều tính năng hỏng, phần lớn code bị bỏ. Hack Week 2016: port fork Python lên 3.5, nâng/fork dependency, thêm job CI chạy unit test và mypy ở chế độ Python 3, nên phần tương thích không bị trượt lại.
  • Đầu 2017 dự án được cấp người chính thức vì nâng Python chặn nhiều nâng cấp toolchain.

Thay đổi chính

  • Bật dần test và type check: mọi unit test ban đầu bị pytest.skip dưới Python 3, sửa từng file rồi bỏ skip; danh sách file không qua mypy Python 3 được xử lý từng file. Độ phủ type mypy toàn công ty tăng từ 35% lên 63% trong thời gian dự án.
  • Lỗi phổ biến nhất: khác biệt str/bytes/unicode, nhất là gọi str() lên byte string khi serialize ra "b'...'". Không dùng from __future__ import unicode_literals từng phần vì đổi kiểu literal theo file gây rối.
  • "Straddling": code viết cú pháp chạy cả 2 và 3 để vẫn phát bản Python 2 cho đa số user; Hydra chọn interpreter lúc khởi động để dogfood nội bộ và lùi về nhanh.
  • Giữ trạng thái lai khoảng 7 tháng (nội bộ rồi Beta), dựa vào pipeline crash report gộp; tìm ra cả bug của chính CPython. Sau đó mở cho kênh Stable và bỏ Python 2 khỏi binary.

Vì sao

  • Giữ tương thích hai phía suốt dự án cho phép phát triển tính năng song song và tăng dần độ tương thích trước khi chuyển.

Bài học cho SWE

  • Test và type checker biến migration thành danh sách việc làm song song được; CI ở chế độ mới chặn hồi quy.
  • Phần lớn lỗi Python 2→3 nằm ở xử lý chuỗi/bytes.
  • Giai đoạn chạy cả hai runtime càng dài thì càng cần telemetry crash tốt để quyết định chuyển.

Liên quan