- Run all tests:
make testorpython3 -m unittest test - Run single test:
python3 -m unittest test.GPXTests.test_method_name - Run mypy (strict):
make mypy→mypy --strict . gpxinfo - Full verification:
make mypy-and-tests(runs mypy → gpxinfo → tests) - Build for PyPI:
make pypi-upload
master= latest release codedev= next release (send PRs here, not tomaster)- CI runs on
mainanddevbranches
- Single package library:
gpxpy/(not a monorepo) - Entry point:
gpxpy/__init__.pyexposesparse()and__version__ - Core modules:
gpx.py— GPX data model (GPX, GPXTrack, GPXTrackSegment, GPXTrackPoint, etc.)parser.py— XML parsing (GPXParser class)gpxfield.py— field definitions and timezone handlinggpxxml.py— XML serializationgeo.py— geographic calculations (distance, haversine, course)utils.py— helpers
py.typedmarker present → PEP 561 compliant (type checkers use inline types)gpxinfo— standalone CLI script in repo root (must also pass mypy)
- All tests in single file:
test.py(classGPXTests) - Test fixtures in
test_files/directory - No pytest — uses stdlib
unittest - lxml is optional; tests auto-detect and skip lxml-specific tests if unavailable
- mypy runs with
--strictflag - Both
.gpxpyandgpxinfoscript must pass - Type hints required on all new code
- XML parser: lxml preferred (2-3x faster), falls back to xml.etree.ElementTree
- GPX versions: supports 1.0 and 1.1; version auto-detected or forced via
parse(..., version="1.0") - No
pyproject.toml— uses legacysetup.py - No pre-commit hooks, no tox, no linting configured beyond mypy
- Defined in classifiers in setup.py