4.2 KiB
pm3py Refactor Progress
Design: 2026-03-18-refactor-design.md
Branch: merged to master
Started: 2026-03-18
Phase 1 — Create core/, normalize names, fix imports
Status: Complete
What was done
- Created
pm3py/core/sub-package - Moved all source modules into
core/:protocol.py,transport.py,client.py,hw.py,hf.py,lf.py— moved as-ishf_14a.py→hf_iso14a.py(renamed)hf_15.py→hf_iso15.py(renamed)hf_mf.py→hf_mfc.py(renamed)
- Normalized client attributes:
hf.a14→hf.iso14ahf.mf→hf.mfchf.iso15— unchanged
- Created
core/__init__.pyre-exporting:Proxmark3,FirmwareInfo,PM3Transport,PM3Error,PM3Response,PM3Status,Cmd - Updated
pm3py/__init__.pyto import from.core.* - Updated all 10 test files (imports + attribute references)
- 30/30 tests passing
Backward compatibility
from pm3py import Proxmark3still works (re-exported)- Breaking:
hf.a14→hf.iso14a,hf.mf→hf.mfc - Breaking: Direct imports like
from pm3py.hf_14a import ...→from pm3py.core.hf_iso14a import ...
Phase 2 — Extract sniff/
Status: Complete
Extracted sniff infrastructure from core/hf_iso15.py (615→130 lines) into two packages:
pm3py/trace/ — shared trace infrastructure (used by sniff, sim, reader):
trace.py—parse_tracelog(),TRACELOG_HDR_SIZE(protocol-agnostic)ndef.py— NDEF TLV/record decode (decode_ndef_annotation())decode_iso15.py— ISO 15693 command/response decoders, command tablesformat.py— ANSI color formatting,format_sniff_line()
pm3py/sniff/ — sniff orchestration (consumes trace/):
session.py—SniffSessionwithiso15()method (replacessniff_decoded())__init__.py— re-exports trace symbols for convenience
core/hf_iso15.py retains HF15Commands (scan/rdbl/wrbl/sniff) and re-exports trace symbols for backward compat. download_trace() and sniff_decoded() delegate to SniffSession.
65/65 tests passing (35 sniff/trace tests work through re-exports, no test changes needed).
Phase 3 — Scaffold transponders/
Status: Complete (scaffolded)
Created full directory tree per design:
transponders/hf/iso14443a3/nxp/— MIFARE Classic, Ultralight, NTAGtransponders/hf/iso14443a4/nxp/— DESFiretransponders/hf/iso15693/nxp/— ICODE SLIX2, NTAG 5transponders/hf/iso15693/st/— ST25TVtransponders/lf/atmel/— T55xxtransponders/lf/em/— EM4100, EM4x05
All directories have __init__.py. Model migration from sim worktree is a separate effort — the sim framework has ~7.8k LOC with deep inheritance chains (Transponder → Tag15693 → NxpIcodeTag → IcodeSlix2Tag, etc.) and auth mixins (NxpPasswordAuth, NxpAesAuth). Base class extraction needs to happen alongside model migration.
Phase 4 — Scaffold reader/ and sim/
Status: sim/ migrated, reader/ scaffolded
sim/ migration (complete)
Migrated full sim framework from .worktrees/sim-framework/ to pm3py/sim/:
- 43 source files, ~7.8k LOC
- 23 test files, 686 tests
- Import fixes: 4 source files (..protocol/..transport → ..core.), 1 source file (pm3py.hf_15 → pm3py.trace.ndef), 2 test files (flat → core.)
- Added sim Cmd entries to
core/protocol.py(EML_SETMEM, SIM_TABLE_*) - Added deps to venv:
pycryptodome,bitarray - 751 total tests passing (686 sim + 65 core)
reader/ (scaffolded)
Created directory trees per design:
reader/hf/nxp/— NXP reader ICs (CLRC663, PN5xx)reader/hf/st/— ST reader ICsreader/lf/reader/modes/— inventory, programming, access control workflows
All reader directories have __init__.py stubs.
Next Steps
- Reorganize transponder models from
sim/intotransponders/hierarchy (optional — sim/ works as-is) - Reader modes: implement inventory, programming, access workflows in
reader/modes/ - Unify
sim/trace_fmt.pywithtrace/package (dedup 15693 decoders, move 14443-A decoders) - Sniff: add
decode_iso14a.pyusing decoders fromsim/trace_fmt.py - Sim worktree cleanup: verify parity, then remove
.worktrees/sim-framework/