diff --git a/.github/scripts/release/README.md b/.github/scripts/release/README.md index 9288dc3..4d5a1ea 100644 --- a/.github/scripts/release/README.md +++ b/.github/scripts/release/README.md @@ -16,8 +16,7 @@ ignored and overwritten. `GITHUB_TOKEN`. This needs the repository setting *Actions -> General -> Allow GitHub Actions to create and approve pull requests*. No PAT is needed; an optional `RELEASE_PR_TOKEN` secret is used for the PR step when present. -3. Merging that PR is the only way to change `main`. The maintainer merges it after checking - that its source branch is `release`; repository settings alone protect `main` (below). +3. Merging that PR is the only way to change `main`, and the maintainer does it (below). 4. On push to `main`, `pages.yml` deploys `docs/guide/` to GitHub Pages. ## What is dropped on release @@ -40,10 +39,5 @@ It refuses to run while `release` is checked out. ## Protecting main - .github/scripts/release/protect-main.sh # print what would be applied - .github/scripts/release/protect-main.sh --apply # apply via gh api (needs admin) - -The settings (the maintainer's decision, 2026-10-03): a pull request is required with no -approving review, direct push, force-push and deletion are blocked, the branch is not locked, and -only administrators may merge. No workflow checks the source branch; the maintainer does, when -merging the release PR. +The maintainer manages `main`'s protection in the repository settings, by hand; `main` is locked. +No script or agent creates or changes those settings. The maintainer merges the release PR. diff --git a/.github/scripts/release/protect-main.sh b/.github/scripts/release/protect-main.sh deleted file mode 100755 index 4bc6514..0000000 --- a/.github/scripts/release/protect-main.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash -# Print (default) or apply (--apply) branch protection for main. -# Usage: protect-main.sh [--apply] [--repo OWNER/NAME] [--branch main] -set -eu -APPLY=0; REPO=""; BRANCH=main -while [ $# -gt 0 ]; do - case "$1" in - --apply) APPLY=1; shift ;; - --repo) REPO="$2"; shift 2 ;; - --branch) BRANCH="$2"; shift 2 ;; - *) echo "unknown argument: $1" >&2; exit 2 ;; - esac -done -[ -n "$REPO" ] || REPO="{owner}/{repo}" # gh expands these placeholders from the current repo - -BODY='{ - "required_status_checks": null, - "enforce_admins": false, - "required_pull_request_reviews": {"required_approving_review_count": 0}, - "restrictions": {"users": [], "teams": [], "apps": []}, - "allow_force_pushes": false, - "allow_deletions": false, - "lock_branch": false -}' -CMD="gh api --method PUT repos/$REPO/branches/$BRANCH/protection --input -" - -if [ "$APPLY" -eq 1 ]; then - printf '%s' "$BODY" | gh api --method PUT "repos/$REPO/branches/$BRANCH/protection" --input - - echo "applied protection to $BRANCH" -else - echo "[dry run] would run: $CMD" - echo "$BODY" - echo "Re-run with --apply to apply (needs admin). 'restrictions' with empty lists means only" - echo "administrators may merge; it is accepted for organisation repositories only." -fi diff --git a/LICENSE b/LICENSE index 6a14d04..57bc88a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,202 @@ -MIT License - -Copyright (c) 2023-2024 BREW (b-re-w), Jong-uk Lee (rnoro5122) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/README.md b/README.md index a178167..c6d7b81 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ English | [한국어](https://github.com/thisisthepy/pythonx-compose/blob/main/d # pythonx-compose -**Write Compose user interfaces in Python — with Compose's own widgets, spelled the Python way.** +**Build Compose Multiplatform UIs in Python: Python Declarative UI Framework** -[](https://github.com/thisisthepy/pythonx-compose/blob/main/LICENSE) +[](https://github.com/thisisthepy/pythonx-compose/blob/main/LICENSE) [](https://github.com/thisisthepy/pythonx-compose/blob/main/pyproject.toml) [](https://github.com/thisisthepy/pythonx-compose/blob/main/pyproject.toml) [](#-status) @@ -19,7 +19,7 @@ English | [한국어](https://github.com/thisisthepy/pythonx-compose/blob/main/d ## Why -Jetpack Compose and Compose Multiplatform are a superb way to build UI — if you write Kotlin. +Jetpack Compose and Compose Multiplatform are a superb way to build UI, if you write Kotlin. `pythonx-compose` is for people who write Python. It does not reimplement Compose and it does not invent a new widget set: it takes the real `androidx.compose.*` API, which [python-multiplatform](https://github.com/thisisthepy/python-multiplatform) exposes to Python under @@ -55,7 +55,9 @@ proofs are still pending. See [Status](#-status). `Alignment.Horizontal.End` is `Alignment.End`. - **`@Composable` stays.** Screens are decorated Python functions. - **A real package.** `pythonx/` is ordinary Python source that imports `androidx.compose.*` and - reshapes it. The binder never renames anything — renaming is this package's job. + reshapes it. The binder never renames a namespace. Since python-multiplatform #131 it serves + `snake_case` names and keywords itself, by this package's rule; this package keeps the module + grouping and the `snake_case`-only surface. - **One manifest.** [`pythonx-map.toml`](https://github.com/thisisthepy/pythonx-compose/blob/main/pythonx/compose/pythonx-map.toml) says which `pythonx.compose.*` module stands for which Kotlin package. It lives inside the package and ships in the wheel. The runtime and the `.pyi` generator read the same file, so what your editor completes is what the interpreter @@ -86,16 +88,23 @@ Each module is a real file whose `__init__.py` calls one re-export rule; names r ## 🚀 Quick start > [!NOTE] -> `pythonx-compose` is **pre-alpha**. The first alpha, `0.1.0a1`, is released to PyPI when the -> maintainer tags it; a pre-release needs `pip install --pre pythonx-compose`. +> `pythonx-compose` is an **alpha**. `0.1.0a1` is on [PyPI](https://pypi.org/project/pythonx-compose/); +> as a pre-release it installs with uv (or ppp, or tcl): + +```bash +uv add --prerelease allow pythonx-compose +# or, with pypackpack, into a package of a ppp workspace: +ppp core add "pythonx-compose==0.1.0a1" +# or, with toolchain-lite: +tcl install pythonx-compose +``` From a clone, to run the tests: ```bash git clone https://github.com/thisisthepy/pythonx-compose cd pythonx-compose -python3 -m pip install pytest # inside a virtual environment -python3 -m pytest tests -q +uv run --with pytest --with mypy pytest tests -q ``` What runs today, from the repository root: @@ -155,15 +164,15 @@ standalone desktop toolkit. | `pythonx` as a real on-disk package re-exporting `androidx.compose.*` by one rule | ✅ implemented and tested | | `Modifier` chains with snake_case methods, overload dispatch, `Dp` as a number | ✅ implemented and tested against the binder's layer | | `Column`, `Row`, `Spacer` from `material3` as well as `layout` | ✅ implemented and tested | -| Method keyword arguments in `snake_case` | ✅ implemented and tested — module functions and methods (methods need python-multiplatform's `describe_member`) | -| The empty `Modifier` | 🟡 partial — `Modifier.padding(16)` from the class needs an app-supplied factory against real Compose | -| `Alignment` / `Arrangement` | ✅ implemented and tested — `Alignment.Center`, `Arrangement.spaced_by(8)`, and grouped `Alignment.Horizontal.End` beside `Alignment.End` | -| Material 3 widgets (`Text`, `Button`, `Card`, `TextField`, …) | 🟡 partial — re-exported by rule; render proofs per widget pending (#9) | +| Method keyword arguments in `snake_case` | ✅ implemented and tested: module functions and methods (methods need python-multiplatform's `describe_member`) | +| The empty `Modifier` | 🟡 partial: `Modifier.padding(16)` from the class needs an app-supplied factory against real Compose | +| `Alignment` / `Arrangement` | ✅ implemented and tested: `Alignment.Center`, `Arrangement.spaced_by(8)`, and grouped `Alignment.Horizontal.End` beside `Alignment.End` | +| Material 3 widgets (`Text`, `Button`, `Card`, `TextField`, …) | 🟡 partial: re-exported by rule; render proofs per widget pending (#9) | | Type stubs (`.pyi`) from real Compose 1.11.1, `py.typed` | ✅ implemented and checked with mypy; many types are still `Any` (#12) | -| Distribution (`pythonx-compose`) | 🟡 partial — the wheel carries the manifest, the re-export rule, the stubs and `py.typed` | -| Declared app root (`@app`) and Pythonic state (`state`), no update call | 🟡 partial — binder path tested against a fake host shaped after python-multiplatform #38; real Compose is the E2E module (#11, #19); numbers and strings round-trip through `state` | -| `TextField(state=...)` with `TextFieldState` (`pythonx.compose.foundation.text.input`) | 🟡 partial — tested against a fake host shaped after python-multiplatform #73; the input-method (IME) composing proof is python-multiplatform E2E #26 (#10) | -| `DefaultIcons` (`Icons.Default`), written `DefaultIcons.Add` | 🟡 partial — tested against a fake host shaped after python-multiplatform #37/#38; `Icon(DefaultIcons.Add, …)` is drawn in python-multiplatform's render test | +| Distribution (`pythonx-compose`) | 🟡 partial: the wheel carries the manifest, the re-export rule, the stubs and `py.typed` | +| Declared app root (`@app`) and Pythonic state (`state`), no update call | 🟡 partial: binder path tested against a fake host shaped after python-multiplatform #38; real Compose is the E2E module (#11, #19); numbers and strings round-trip through `state` | +| `TextField(state=...)` with `TextFieldState` (`pythonx.compose.foundation.text.input`) | 🟡 partial: tested against a fake host shaped after python-multiplatform #73; the input-method (IME) composing proof is python-multiplatform E2E #26 (#10) | +| `DefaultIcons` (`Icons.Default`), written `DefaultIcons.Add` | 🟡 partial: tested against a fake host shaped after python-multiplatform #37/#38; `Icon(DefaultIcons.Add, …)` is drawn in python-multiplatform's render test | | Colour schemes | ⏳ planned | | `remember_saveable`, coroutine scopes | ⏳ planned | @@ -171,15 +180,15 @@ The full list is on the guide's [Status page](https://thisisthepy.github.io/pyth ## 📖 Documentation -- **Guide** — [`docs/guide/`](https://thisisthepy.github.io/pythonx-compose/), bilingual (English / 한국어) -- **Korean README** — [`docs/locale/README_ko.md`](https://github.com/thisisthepy/pythonx-compose/blob/main/docs/locale/README_ko.md) +- **Guide**: [`docs/guide/`](https://thisisthepy.github.io/pythonx-compose/), bilingual (English / 한국어) +- **Korean README**: [`docs/locale/README_ko.md`](https://github.com/thisisthepy/pythonx-compose/blob/main/docs/locale/README_ko.md) ## 🔌 Ecosystem | Repository | Role | |---|---| | [python-multiplatform](https://github.com/thisisthepy/python-multiplatform) | The binder: CPython embedded in Kotlin Multiplatform, exposing Kotlin to Python under Kotlin names | -| **pythonx-compose** | Compose, restructured for Python — this repository | +| **pythonx-compose** | Compose, restructured for Python (this repository) | | [toolchain](https://github.com/thisisthepy/toolchain) | Gradle build plugin for Python Multiplatform apps | | [pypackpack](https://github.com/thisisthepy/pypackpack) | Distributing Python projects across platforms | | [torchnative](https://github.com/thisisthepy/torchnative) | Run the real PyTorch ecosystem on device | @@ -200,4 +209,4 @@ useful. Please open an issue before large changes. ## License -[MIT](https://github.com/thisisthepy/pythonx-compose/blob/main/LICENSE) © 2023–2024 BREW (b-re-w), Jong-uk Lee (rnoro5122) +[Apache License 2.0](https://github.com/thisisthepy/pythonx-compose/blob/main/LICENSE) © 2023–2024 BREW (b-re-w), Jong-uk Lee (rnoro5122) diff --git a/docs/guide/assets/style.css b/docs/guide/assets/style.css index 932d708..3d0beb1 100644 --- a/docs/guide/assets/style.css +++ b/docs/guide/assets/style.css @@ -1,4 +1,4 @@ -/* pythonx-compose guide — shared thisisthepy family tokens, accent #7c4dff. */ +/* pythonx-compose guide: shared thisisthepy family tokens, accent #7c4dff. */ :root { --bg: #fbfbfa; --fg: #16181d; --muted: #5b6270; --line: #e6e6e3; --code-bg: #f3f3f1; --radius: 10px; --maxw: 72rem; @@ -146,7 +146,7 @@ a.card:hover { text-decoration: none; border-color: var(--accent); } ul.clean { padding-left: 1.1rem; margin: 0 0 1rem; } ul.clean li { margin: 0.3rem 0; } -.not li::marker { content: "— "; color: var(--muted); } +.not li::marker { content: "– "; color: var(--muted); } /* Tables */ .table-wrap { overflow-x: auto; margin: 1rem 0 1.5rem; border: 1px solid var(--line); border-radius: var(--radius); } diff --git a/docs/guide/concepts.html b/docs/guide/concepts.html index 3619414..be1e719 100644 --- a/docs/guide/concepts.html +++ b/docs/guide/concepts.html @@ -32,14 +32,14 @@
python-multiplatform — the binder — embeds CPython in a Kotlin Multiplatform app and exposes Kotlin declarations to Python under their Kotlin names: androidx.compose.material3 is androidx.compose.material3. It never renames a namespace.
python-multiplatform — 바인더 — 는 Kotlin Multiplatform 앱에 CPython 을 임베딩하고, Kotlin 선언을 Kotlin 이름 그대로 파이썬에 노출합니다: androidx.compose.material3 는 androidx.compose.material3 입니다. 네임스페이스 이름을 절대 바꾸지 않습니다.
pythonx-compose — this package — is real Python on disk. Its modules import those androidx.compose.* modules and restructure them into pythonx.compose.*.
pythonx-compose — 이 패키지 — 는 디스크에 있는 실제 파이썬입니다. 이 패키지의 모듈이 androidx.compose.* 를 import 해 pythonx.compose.* 로 재구성합니다.
python-multiplatform, the binder, embeds CPython in a Kotlin Multiplatform app and exposes Kotlin declarations to Python under their Kotlin names: androidx.compose.material3 is androidx.compose.material3. It never renames a namespace. Since python-multiplatform #131 it does serve snake_case names and keywords on its own callables and proxies, by the rule this package wrote.
python-multiplatform(바인더)는 Kotlin Multiplatform 앱에 CPython 을 임베딩하고, Kotlin 선언을 Kotlin 이름 그대로 파이썬에 노출합니다: androidx.compose.material3 는 androidx.compose.material3 입니다. 네임스페이스 이름을 절대 바꾸지 않습니다. 다만 python-multiplatform #131 부터는 이 패키지가 정한 규칙대로 자신의 함수와 프록시에서 snake_case 이름과 키워드를 제공합니다.
pythonx-compose, this package, is real Python on disk. Its modules import those androidx.compose.* modules and restructure them into pythonx.compose.*.
pythonx-compose(이 패키지)는 디스크에 있는 실제 파이썬입니다. 이 패키지의 모듈이 androidx.compose.* 를 import 해 pythonx.compose.* 로 재구성합니다.
Expose the original Kotlin declarations and parameters with Pythonic names. A name that starts upper-case — a type, an object, a composable — keeps its Kotlin spelling. Every other name is reached by its snake_case spelling only; the camelCase spelling is not a second name. An explicit overload keeps its type suffix.
Kotlin 의 원래 선언과 매개변수를 파이썬다운 이름으로 노출합니다. 대문자로 시작하는 이름 — 타입, 객체, 컴포저블 — 은 Kotlin 표기를 유지합니다. 그 밖의 이름은 snake_case 표기로만 접근하며, camelCase 표기가 또 하나의 이름이 되지는 않습니다. 명시적 오버로드는 타입 접미사를 유지합니다.
Expose the original Kotlin declarations and parameters with Pythonic names. A name that starts upper-case (a type, an object, a composable) keeps its Kotlin spelling. Every other name is reached by its snake_case spelling only; the camelCase spelling is not a second name. An explicit overload keeps its type suffix. Turning a Kotlin name or keyword into snake_case is the binder's work since python-multiplatform #131 (its python_name is this package's rule, and a test pins that the two agree). This package decides what the pythonx surface lists: snake_case only, with no camelCase second name.
Kotlin 의 원래 선언과 매개변수를 파이썬다운 이름으로 노출합니다. 대문자로 시작하는 이름(타입, 객체, 컴포저블)은 Kotlin 표기를 유지합니다. 그 밖의 이름은 snake_case 표기로만 접근하며, camelCase 표기가 또 하나의 이름이 되지는 않습니다. 명시적 오버로드는 타입 접미사를 유지합니다. Kotlin 이름과 키워드를 snake_case 로 바꾸는 일은 python-multiplatform #131 부터 바인더가 합니다(바인더의 python_name 은 이 패키지의 규칙이며, 둘이 일치함을 테스트가 확인합니다). pythonx 표면에 무엇을 나열할지는 이 패키지가 정하며, snake_case 만 나열하고 camelCase 두 번째 이름은 두지 않습니다.
| Kotlin | Python |
|---|