| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,19 +26,19 @@ jobs: | |||
| 26 | 26 | needs: coverage | |
| 27 | 27 | runs-on: ubuntu-latest | |
| 28 | 28 | timeout-minutes: 30 | |
| 29 | - # GitHub-hosted Android emulators grow unstable after ~15 minutes of | ||
| 30 | - # sustained Maestro driving and start reporting "device offline" / | ||
| 31 | - # "device not found" mid-run (the emulator VM, not the app, dies). | ||
| 32 | - # The full suite reliably crosses that threshold around the ~35th | ||
| 33 | - # flow. Sharding the run into a few balanced groups, each on its | ||
| 34 | - # own freshly booted emulator, keeps every session well under the | ||
| 29 | + # GitHub-hosted Android emulators grow unstable after roughly ten | ||
| 30 | + # minutes of sustained Maestro driving and start reporting "device | ||
| 31 | + # offline" / "device not found" mid-run (the emulator VM, not the | ||
| 32 | + # app, dies). Sharding the run into a few balanced groups, each on | ||
| 33 | + # its own freshly booted emulator, keeps every session under the | ||
| 35 | 34 | # limit, and parallelizes the Android pass as a bonus. Groups are | |
| 36 | - # sized so none exceeds ~15 flows; ``components`` (28 flows after | ||
| 37 | - # the gesture/animated additions) crossed the ceiling at ~flow 26, | ||
| 38 | - # so it runs as two halves, and ``hooks`` (22 flows after the async | ||
| 39 | - # hook additions) now takes ~10 minutes of driving on its own, so | ||
| 40 | - # it gets a dedicated emulator. ``fail-fast: false`` so one shard's | ||
| 41 | - # failure still lets the others report. | ||
| 35 | + # sized so none exceeds ~12 heavy flows: ``components`` (35 flows | ||
| 36 | + # after the graphics additions) dropped offline at ~11.5 minutes | ||
| 37 | + # when split in two, so it runs as three parts; ``hooks`` (23 quick | ||
| 38 | + # flows, ~10 minutes of driving) gets a dedicated emulator; the | ||
| 39 | + # remaining categories are grouped to similar totals. | ||
| 40 | + # ``fail-fast: false`` so one shard's failure still lets the others | ||
| 41 | + # report. | ||
| 42 | 42 | strategy: | |
| 43 | 43 | fail-fast: false | |
| 44 | 44 | matrix: | |
@@ -47,12 +47,14 @@ jobs: | |||
| 47 | 47 | suites: components-a | |
| 48 | 48 | - name: components-b | |
| 49 | 49 | suites: components-b | |
| 50 | + - name: components-c | ||
| 51 | + suites: components-c | ||
| 50 | 52 | - name: hooks | |
| 51 | 53 | suites: hooks | |
| 52 | 54 | - name: nav-gestures-layout-styling | |
| 53 | 55 | suites: navigation gestures layout styling | |
| 54 | 56 | - name: anim-misc | |
| 55 | - suites: animations misc | ||
| 57 | + suites: animations assets misc | ||
| 56 | 58 | - name: inbox | |
| 57 | 59 | suites: inbox | |
| 58 | 60 | ||
@@ -162,12 +164,14 @@ jobs: | |||
| 162 | 164 | suites: components-a | |
| 163 | 165 | - name: components-b | |
| 164 | 166 | suites: components-b | |
| 167 | + - name: components-c | ||
| 168 | + suites: components-c | ||
| 165 | 169 | - name: hooks | |
| 166 | 170 | suites: hooks | |
| 167 | 171 | - name: nav-gestures-layout-styling | |
| 168 | 172 | suites: navigation gestures layout styling | |
| 169 | 173 | - name: anim-misc | |
| 170 | - suites: animations misc | ||
| 174 | + suites: animations assets misc | ||
| 171 | 175 | - name: inbox | |
| 172 | 176 | suites: inbox | |
| 173 | 177 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,11 @@ | |||
| 1 | 1 | # AGENTS.md | |
| 2 | 2 | ||
| 3 | 3 | Follow Chicago Manual of Style (CMOS) grammar in the documentation, but use straight apostrophes and quotation marks, avoid em dashes, and use contractions where appropriate. | |
| 4 | + | ||
| 5 | + ## RFCs | ||
| 6 | + | ||
| 7 | + Major changes are designed in `rfcs/` before they're implemented. Read `rfcs/README.md` for the rules, and read the accepted RFCs before proposing a change that overlaps one of them. In short: | ||
| 8 | + | ||
| 9 | + - Write an RFC (copy `rfcs/0000-template.md`) before adding or removing public API, changing the Python-to-native wire contract, changing a project convention apps depend on, or touching Python, Swift, Kotlin, and the browser preview at once. | ||
| 10 | + - Keep the RFC honest: update it as the implementation changes, list removals explicitly, and land it with status `Implemented` in the same pull request as the code when the plan was agreed on informally. | ||
| 11 | + - Bug fixes, behavior-preserving refactors, and single-layer additions don't need one. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -88,6 +88,7 @@ Unsolicited pull requests for issues that are already assigned or already have a | |||
| 88 | 88 | - Prefer explicit, descriptive names; keep platform abstractions clean. | |
| 89 | 89 | - Python never imports platform code. Everything that touches `UIView` or `android.view.View` lives in Swift (`PythonNativeKit`) or Kotlin (the `pythonnative` Gradle module) and is reached through `pythonnative.bridge`; see `docs/concepts/bridge.md` for the protocol. Bump `PROTOCOL_VERSION` on both sides when the wire format changes. | |
| 90 | 90 | - Add/extend tests under `tests/` for new behavior. Native changes get XCTest / JUnit coverage next to the code they touch. | |
| 91 | + - Design large changes in an RFC first. Anything that adds or removes public API, changes the Python-to-native wire contract, changes a convention apps depend on, or spans Python, Swift, Kotlin, and the browser preview gets a document under `rfcs/` (see [`rfcs/README.md`](https://github.com/pythonnative/pythonnative/blob/main/rfcs/README.md)). The RFC lands with the implementation and records what shipped, including removals. | ||
| 91 | 92 | - Commit source, reviewed generated contracts, dependency locks, and vendored dependencies as described in [Generated source and vendored dependencies](#generated-source-and-vendored-dependencies). Don't commit local build outputs or caches. | |
| 92 | 93 | - Docstrings: Google style throughout. Ruff is configured with the Google | |
| 93 | 94 | convention (`pydocstyle.convention = "google"`) and enforces the `D` rule | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,6 +36,7 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app | |||
| 36 | 36 | - **Incremental reconciliation:** State changes update affected component subtrees. Versioned bridge commits validate operations and acknowledge revisions; events and controlled text inputs carry identities that prevent stale updates. | |
| 37 | 37 | - **Native lists and navigation:** UIKit collection views and Android recycler views recycle cells for fixed or variable row sizes, grids, sections, and horizontal lists. Native navigation containers present logical screen roots while providers and component state remain in the shared Python tree. | |
| 38 | 38 | - **Animation and gestures:** Serialized animation graphs support timing, springs, decay, arithmetic, interpolation, and native scroll and gesture bindings. Swift and Kotlin recognize mobile gestures and update supported animation bindings without Python work on every frame. | |
| 39 | + - **Assets and graphics:** Drop images, fonts, and SVGs under `app/assets/` and reference them by path. Density variants, bundled fonts, a vector `Icon` set, `Svg` drawing, gradients, and blur render natively on both platforms and in the browser preview. | ||
| 39 | 40 | - **Device APIs:** Python facades expose camera, location, notifications, storage, permissions, and other native services. Test permissions and platform behavior on your deployment targets. | |
| 40 | 41 | - **Native extension SDK:** Python dataclasses and protocols define contracts; `pn codegen` generates props and module adapters for Swift and Kotlin. Plugins package native sources and resources, and builds verify matching contracts at startup. | |
| 41 | 42 | - **Development tools:** `pn start` serves the browser preview and connected mobile dev clients. Fast Refresh preserves compatible component state, while diagnostics report errors and invalid hook usage. Changes to native inputs trigger a rebuild. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,40 @@ | |||
| 1 | + # Assets | ||
| 2 | + | ||
| 3 | + Files under `app/assets/` are bundled into the iOS app, the Android APK, | ||
| 4 | + and the browser preview, and are addressed from Python by relative path: | ||
| 5 | + | ||
| 6 | + ```python | ||
| 7 | + import pythonnative as pn | ||
| 8 | + | ||
| 9 | + logo = pn.asset("images/logo.png") # Asset("images/logo.png") | ||
| 10 | + pn.Image(source=logo, style=pn.style(width=120, height=40)) | ||
| 11 | + config = pn.asset("data/config.json").read_text() | ||
| 12 | + ``` | ||
| 13 | + | ||
| 14 | + The [Assets guide](../guides/assets.md) covers density variants, fonts, | ||
| 15 | + icons, and how the folder is bundled and synced. | ||
| 16 | + | ||
| 17 | + ::: pythonnative.assets | ||
| 18 | + options: | ||
| 19 | + show_root_heading: false | ||
| 20 | + show_root_toc_entry: false | ||
| 21 | + members_order: source | ||
| 22 | + filters: ["!^_"] | ||
| 23 | + | ||
| 24 | + ## Fonts | ||
| 25 | + | ||
| 26 | + Bundled `.ttf` and `.otf` files are parsed at build time so `font_family` | ||
| 27 | + can refer to them by family name. | ||
| 28 | + | ||
| 29 | + ::: pythonnative.assets.fonts | ||
| 30 | + options: | ||
| 31 | + show_root_heading: false | ||
| 32 | + show_root_toc_entry: false | ||
| 33 | + members_order: source | ||
| 34 | + filters: ["!^_"] | ||
| 35 | + | ||
| 36 | + ## Next steps | ||
| 37 | + | ||
| 38 | + - Measure and prefetch images with [`Images`](images.md). | ||
| 39 | + - Draw bundled vectors with [`Svg`][pythonnative.components.Svg] and | ||
| 40 | + [`Icon`][pythonnative.Icon]: see [Graphics](graphics.md). | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,44 @@ | |||
| 1 | + # Graphics | ||
| 2 | + | ||
| 3 | + Vector drawing and visual effects: [`Icon`][pythonnative.Icon] for the | ||
| 4 | + bundled Lucide icon set, [`Svg`][pythonnative.components.Svg] with the shape | ||
| 5 | + classes in `pythonnative.svg` (below), and the | ||
| 6 | + [`LinearGradient`][pythonnative.components.LinearGradient] and | ||
| 7 | + [`BlurView`][pythonnative.components.BlurView] containers. The component | ||
| 8 | + factories themselves are documented on the [Components](components.md) page. | ||
| 9 | + | ||
| 10 | + ```python | ||
| 11 | + import pythonnative as pn | ||
| 12 | + from pythonnative import svg | ||
| 13 | + | ||
| 14 | + pn.Icon("heart", color="#DC2626") | ||
| 15 | + | ||
| 16 | + pn.Svg( | ||
| 17 | + svg.Circle(cx=12, cy=12, r=10, fill="#FDE68A"), | ||
| 18 | + svg.Path(d="M8 13 q4 5 8 0", stroke="#B45309", stroke_width=2, fill="none"), | ||
| 19 | + style=pn.style(width=48, height=48), | ||
| 20 | + ) | ||
| 21 | + | ||
| 22 | + pn.LinearGradient(pn.Text("Hi"), colors=["#6366F1", "#EC4899"], style=pn.style(padding=16)) | ||
| 23 | + ``` | ||
| 24 | + | ||
| 25 | + See the [Assets guide](../guides/assets.md) for the drawing model and | ||
| 26 | + platform notes. | ||
| 27 | + | ||
| 28 | + ## Icons | ||
| 29 | + | ||
| 30 | + ::: pythonnative.icons | ||
| 31 | + options: | ||
| 32 | + show_root_heading: false | ||
| 33 | + show_root_toc_entry: false | ||
| 34 | + members_order: source | ||
| 35 | + filters: ["!^_"] | ||
| 36 | + | ||
| 37 | + ## SVG shapes and parsing | ||
| 38 | + | ||
| 39 | + ::: pythonnative.svg | ||
| 40 | + options: | ||
| 41 | + show_root_heading: false | ||
| 42 | + show_root_toc_entry: false | ||
| 43 | + members_order: source | ||
| 44 | + filters: ["!^_"] | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,43 @@ | |||
| 1 | 1 | # Images | |
| 2 | 2 | ||
| 3 | - `Image` loads and decodes images with the platform's native image loader. Each | ||
| 4 | - platform caches responses and cancels obsolete requests when a source changes | ||
| 5 | - or a component unmounts. Python doesn't download or decode image bytes. | ||
| 3 | + `Image` loads and decodes images with the platform's native image loader. | ||
| 4 | + Each platform caches responses and cancels obsolete requests when a source | ||
| 5 | + changes or a component unmounts. Python doesn't download or decode image | ||
| 6 | + bytes. | ||
| 6 | 7 | ||
| 7 | - Use `Image(source=...)` for bundled resources, files, or remote images. Supply | ||
| 8 | - layout constraints when an image must reserve space before its content loads. | ||
| 8 | + Sources can be a bundled [`Asset`][pythonnative.Asset], an `https` URL, a | ||
| 9 | + file path, or a `data:` URI. `default_source` shows a local image while a | ||
| 10 | + remote one loads (and keeps it if the load fails); `blur_radius` blurs the | ||
| 11 | + decoded bitmap. Supply layout constraints when an image must reserve space | ||
| 12 | + before its content loads. | ||
| 13 | + | ||
| 14 | + ```python | ||
| 15 | + pn.Image( | ||
| 16 | + source="https://example.com/photo.jpg", | ||
| 17 | + default_source=pn.asset("images/placeholder.png"), | ||
| 18 | + blur_radius=4, | ||
| 19 | + style=pn.style(width=200, height=120), | ||
| 20 | + ) | ||
| 21 | + ``` | ||
| 22 | + | ||
| 23 | + ## Images module | ||
| 24 | + | ||
| 25 | + [`Images`][pythonnative.Images] measures, prefetches, and clears the | ||
| 26 | + cache of the same pipeline: | ||
| 27 | + | ||
| 28 | + ```python | ||
| 29 | + size = await pn.Images.get_size(pn.asset("images/hero.png")) | ||
| 30 | + await pn.Images.prefetch("https://example.com/photo.jpg") | ||
| 31 | + pn.Images.clear_cache() | ||
| 32 | + ``` | ||
| 33 | + | ||
| 34 | + ::: pythonnative.native_modules.images | ||
| 35 | + options: | ||
| 36 | + show_root_heading: false | ||
| 37 | + show_root_toc_entry: false | ||
| 38 | + members_order: source | ||
| 39 | + filters: ["!^_"] | ||
| 40 | + | ||
| 41 | + ## Next steps | ||
| 42 | + | ||
| 43 | + - Bundle images, fonts, and vectors: [Assets guide](../guides/assets.md). | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments