Skip to content

Remove Python 2 compatibility and add mypy type checking - #433

Draft
richardkiss with Copilot wants to merge 11 commits into
mainfrom
copilot/remove-python2-compatibility
Draft

Remove Python 2 compatibility and add mypy type checking#433
richardkiss with Copilot wants to merge 11 commits into
mainfrom
copilot/remove-python2-compatibility

Conversation

Copilot AI commented Feb 10, 2026

Copy link
Copy Markdown
Contributor

Drops Python 2 support, sets minimum version to Python 3.8, and introduces gradual type checking with mypy.

Compatibility Removal

  • Simplified Python 3 implementations: Removed conditional logic from intbytes.py, encoding/bytes32.py, ecdsa/intstream.py, ecdsa/rfc6979.py that provided Python 2 fallbacks for int.to_bytes(), int.from_bytes(), and int.bit_length()
  • Updated imports: Removed from __future__ import print_function from cmds modules; replaced urllib2/urllib compatibility layer with direct Python 3 imports
  • Fixed exceptions: Changed raise NotImplemented() to raise NotImplementedError() in base classes (TxIn, TxOut, Tx, SolutionChecker)

Type Annotations

Added type hints to core utility modules with Literal types for strict parameter validation:

# Before
def to_bytes(v, length, byteorder="big"):
    return v.to_bytes(length, byteorder=byteorder)

# After  
def to_bytes(v: int, length: int, byteorder: Literal["big", "little"] = "big") -> bytes:
    return v.to_bytes(length, byteorder=byteorder)

Annotated modules: intbytes, encoding/bytes32, encoding/hexbytes, ecdsa/intstream, ecdsa/rfc6979, merkle, bloomfilter

Configuration

  • setup.py: Added python_requires='>=3.8', classifiers for Python 3.8-3.13
  • tox.ini: Test environments now py38-py313 with coverage
  • mypy.ini: Gradual typing config (python_version=3.8, ignore_missing_imports=True, disallow_untyped_defs=False)
  • CI: Removed test-py27.yml, added mypy.yml workflow, updated test matrix to 3.8-3.13
  • Distribution: Added py.typed marker for PEP 561 compliance

Development

Created requirements-dev.txt with pytest, coverage, mypy dependencies.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • blockchain.info
    • Triggering command: /usr/bin/python python -m pytest tests/ -q (dns block)
    • Triggering command: /usr/bin/python python -m pytest tests/ -q --tb=no --global k/_temp/copilot-developer-action-main/dist/ripgrep/bin/linux-x64/rg user.name (dns block)
    • Triggering command: /usr/bin/python python -m pytest tests/ -q --tb=no origin de/node/bin/git (dns block)
  • blockexplorer.com
    • Triggering command: /usr/bin/python python -m pytest tests/ -q (dns block)
    • Triggering command: /usr/bin/python python -m pytest tests/ -q --tb=no --global k/_temp/copilot-developer-action-main/dist/ripgrep/bin/linux-x64/rg user.name (dns block)
    • Triggering command: /usr/bin/python python -m pytest tests/ -q --tb=no origin de/node/bin/git (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Summary

Remove all Python 2 compatibility code from the repository richardkiss/pycoin (branch: main) and add mypy static type checking to the codebase and CI. The PR should keep runtime behavior unchanged for Python 3.x users; it should simply stop maintaining Python 2 compatibility shims and add gradual type annotations and a mypy config and CI job. The changes should be small, reversible, and well-documented in the PR description.

Goals

  1. Remove Python 2 compatibility vestiges across the codebase (no behavioral changes for Python 3):

    • Remove references to and usage of six, future, and any custom compatibility modules.
    • Replace Python-2-specific aliases/usages: xrange -> range, iteritems()/itervalues()/iterkeys() -> items()/values()/keys(), long -> int, basestring -> str, unicode -> str, dict.iteritems -> dict.items, dict.iterkeys -> dict.keys, dict.itervalues -> dict.values.
    • Remove future imports that are unnecessary on Python 3 (except those that are still relevant; prefer to remove ones related to python2 compatibility like unicode_literals if present and adjust code accordingly).
    • Remove try/except blocks that provide alternate code paths for Python 2 (e.g., except NameError: define bytes/str shims) and instead rely on Python 3 builtins.
    • Update setup.py / setup.cfg / pyproject.toml:
      • Remove Python 2 trove classifiers.
      • Update python_requires to a sensible Python 3 only range (e.g., >=3.8) — choose 3.8 to 3.11 compatibility unless tests suggest otherwise.
      • Remove or update dependency pins that were only required for Python 2 compatibility (e.g., six) and move typing-only packages to dev dependencies.
    • Remove any code specifically marked as Python2-only or guarded by if sys.version_info[0] < 3 or similar.
  2. Add mypy to the project and progressively annotate the code.

    • Add a mypy configuration file (mypy.ini or setup.cfg [mypy]) at the repo root with sensible defaults for gradual typing:
      • strict optional False
      • disallow_untyped_defs False initially
      • plugins none
      • ignore_missing_imports True
      • files: src or top-level package(s) as appropriate
    • Add type annotations to all public functions and methods across the codebase. Prioritize public API surfaces, modules under the top-level package, and modules most used by tests.
    • Add typing imports (typing: Any, Optional, Union, Dict, List, Tuple, Iterable, Iterator, Callable) and use Python 3.8+ annotations (from future import annotations if needed), but since we're removing Python 2 support, we can safely use postponed evaluation of annotations by adding "from future import annotations" at top of modules where forward references are needed and Python 3.7+ supported. Prefer using current annotations (PEP 563) if target python allows.
    • Where complete typing is impractical in the timeframe, add precise typed stubs or use "# type: ignore[assignment]" or "-> Any" with TODO comments to follow up.
    • Add a py.typed marker file at the package root if the package should be typed for consumers.
  3. Add CI job and developer tooling to run mypy.

    • Create a GitHub Actions workflow .github/workflows/mypy.yml that runs on push and PR to main and runs mypy with the repository's configuration. Also run mypy in a reasonable Python matrix (e.g., 3.8, 3.10, 3.11) but at minimum 3.8+.
    • Add mypy and typing-related packages to dev-requirements or tests/requirements (e.g., mypy>=1.0, types-requests if necessary), and update any existing CI workflow to include type-check step.
    • Optionally add a pre-commit hook entry for mypy in .pre-commit-config.yaml if present.
  4. Run quick automated code modernizations where safe.

    • Replace "%"-style formatting in places flagged as Python2-compat if appropriate with f-strings for readability.
    • Replace explicit list(dict.keys()) usages where unnecessary.
    • Convert textual bytes/str conversions to Python 3 idioms.
    • Ensure explicit use of pathlib where previously os.path-based shims existed if small and safe.
    • All automated changes must preserve behavior and tests should pass.
  5. Testing and validation

    • Run the existing test suite (if present) and make minimal test fixes required by compatibility removals.
    • Ensure no tests are skipped because of removed Python 2 compatibility code.
    • Ensure linting and style do not degrade (optional: run flake8/ruff if available in CI).

Scope and Files to Change

  • Apply changes across the entire repository tree under the main branch (richardkiss/pycoin main).
  • Key targets (where to look and what to change):
    • setup.py, setup.cfg, pyproject.toml, requirements*.txt, dev-requirements
    • top-level package directory (likely pycoin or package name) — annotate public functions/methods
    • modules that import six, future, or define compatibility helpers
    • init.py files to add py.typed if appropriate
    • tests/ to update type hints where necessary for mypy
    • .github...

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 10 commits February 10, 2026 20:41
Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
…notations

Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
…v.txt

Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
… in MANIFEST.in

Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
… types, fix hash_f annotation

Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
…ting

Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
… 3.8

Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Copilot AI changed the title [WIP] Remove Python 2 compatibility and add mypy type checking Remove Python 2 compatibility and add mypy type checking Feb 10, 2026
Copilot AI requested a review from richardkiss February 10, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants