Thanks for your interest in contributing. This repository contains the PythonNative library, CLI, templates, a demo app, and a Django site used for docs/demo hosting and E2E. Contributions should keep the code reliable, cross‑platform, and easy to use.
Development uses Python ≥ 3.9.
# create and activate a venv (recommended)
python3 -m venv .venv && source .venv/bin/activate
# install dev tools (lint/format/test)
pip install -e ".[dev]"
# install library (editable) and CLI
pip install -e .
# run tests
pytest -q
# format and lint
black src examples tests || true
ruff check .Common library and CLI entry points:
# CLI help
pn --help
# create a new sample app (template fetch is remote)
pn init my_app
# run the Hello World example
cd examples/hello-world && pn run androidsrc/pythonnative/– installable library and CLIpythonnative/– core cross‑platform UI components and utilitiescli/–pncommand
tests/– unit tests for the librarytemplates/– Android/iOS project templates and zipsexamples/– runnable example appshello-world/– minimal demo app using the library
README.md,pyproject.toml– repo docs and packaging
- Style: Black; lint: Ruff; typing where useful. Keep APIs stable.
- Prefer explicit, descriptive names; keep platform abstractions clean.
- Add/extend tests under
tests/for new behavior. - Do not commit generated artifacts or large binaries; templates live under
templates/.
Common commands:
pytest -q # run tests
ruff check . # lint
black src examples tests # formatThis project uses Conventional Commits. Use the form:
<type>(<scope>): <subject>
[optional body]
[optional footer(s)]
- Encoding: UTF‑8 is allowed and preferred across subjects and bodies.
- Keep the subject ≤ 72 chars; avoid emoji.
Accepted types (standard):
build– build system or external dependencies (e.g., requirements, packaging)chore– maintenance (no library behavior change)ci– continuous integration configuration (workflows, pipelines)docs– documentation onlyfeat– user‑facing feature or capabilityfix– bug fixperf– performance improvementsrefactor– code change that neither fixes a bug nor adds a featurerevert– revert of a previous commitstyle– formatting/whitespace (no code behavior)test– add/adjust tests only
Recommended scopes (match the smallest accurate directory/module):
-
Library/CLI scopes:
cli–src/pythonnative/cli/(thepncommand)core–src/pythonnative/pythonnative/package internalscomponents– UI view modules undersrc/pythonnative/pythonnative/(e.g.,button.py,label.py)utils– utilities likeutils.pytests–tests/
-
Templates and examples:
templates–templates/(Android/iOS templates, zips)examples–examples/(e.g.,hello-world/)
- Repo‑level and ops:
deps– dependency updates and version pinsdocker– containerization files (e.g.,Dockerfile)repo– top‑level files (README.md,CONTRIBUTING.md,.gitignore, licenses)mkdocs– documentation site (MkDocs/Material) configuration and content underdocs/workflows– CI pipelines (e.g.,.github/workflows/)
Note: Avoid redundant type==scope pairs (e.g., docs(docs)). Prefer a module scope (e.g., docs(core)) or docs(repo) for top‑level updates.
Examples:
build(deps): refresh pinned versions
chore(repo): add contributing guidelines
ci(workflows): add publish job
docs(core): clarify ListView data contract
feat(components): add MaterialSearchBar
fix(cli): handle missing Android SDK gracefully
perf(core): reduce allocations in list diffing
refactor(utils): extract path helpers
test(tests): cover ios template copy flow
Examples (no scope):
build: update packaging metadata
chore: update .gitignore patterns
docs: add project overview
Breaking changes:
- Use
!after the type/scope or aBREAKING CHANGE:footer.
feat(core)!: rename Page.set_root_view to set_root
BREAKING CHANGE: API renamed; update app code and templates.
- Comma‑separate scopes without spaces:
type(scope1,scope2): ... - Prefer a single scope when possible; use multiple only when the change genuinely spans tightly related areas.
Scope ordering (house style):
- Put the most impacted scope first (e.g.,
repo), then any secondary scopes. - For extra consistency, alphabetize the remaining scopes after the primary.
- Keep it to 1–3 scopes max.
Example:
feat(templates,cli): add ios template and wire pn init
- PR title: use Conventional Commit format.
- Example:
feat(cli): add init subcommand - Imperative mood; no trailing period; ≤ 72 chars;
!for breaking changes.
- Example:
- PR description: include brief sections: What, Why, How (brief), Testing, Risks/Impact, Docs/Follow‑ups.
- Link issues with keywords (e.g.,
Closes #123).
- Link issues with keywords (e.g.,
- Merging: prefer “Squash and merge” with “Pull request title and description”.
- Keep PRs focused; avoid unrelated changes in the same PR.
Recommended PR template:
What
- Short summary of the change
Why
- Motivation/user value
How (brief)
- Key implementation notes or decisions
Testing
- Local/CI coverage; links to tests if relevant
Risks/Impact
- Compat, rollout, perf, security; mitigations
Docs/Follow-ups
- Docs updated or TODO next steps
Closes #123
BREAKING CHANGE: <details if any>
Co-authored-by: Name <email>
- Tests: added/updated;
pytestpasses. - Lint/format:
ruff check .,blackpass. - Docs: update
README.mdand any Django docs pages if behavior changes. - Templates: update
templates/if generator output changes. - No generated artifacts committed.
- The library version is tracked in
pyproject.toml(project.version). Use SemVer. - Workflow:
- Contributors: branch off
main(ordevif used) and open PRs. - Maintainer (release): bump version, tag, and publish to PyPI.
- Tag on
main:git tag -a vX.Y.Z -m "Release vX.Y.Z" && git push --tags.
- Contributors: branch off
- Use lowercase kebab‑case; concise (≤ 40 chars).
- Prefix conventions:
feature/<scope>-<short-desc>fix/<issue-or-bug>-<short-desc>chore/<short-desc>docs/<short-desc>ci/<short-desc>refactor/<scope>-<short-desc>test/<short-desc>perf/<short-desc>build/<short-desc>release/vX.Y.Zhotfix/<short-desc>
Examples:
feature/cli-init
fix/core-threading-deadlock-123
docs/contributing
ci/publish-pypi
build/lock-versions
refactor/utils-paths
test/templates-android
release/v0.2.0
hotfix/cli-regression
- Avoid bundling secrets or credentials in templates or code.
- Prefer runtime configuration via environment variables for Django and CI.
By contributing, you agree that your contributions are licensed under the repository’s MIT License.