├── .github └── workflows │ ├── python-publish.yml │ └── release.yml ├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── Makefile ├── README.md ├── codegen ├── snippet-tests │ ├── input │ │ ├── Classes.pkl │ │ ├── EmptyOpenModule.pkl │ │ ├── Enums.pkl │ │ ├── ExplicitName.pkl │ │ ├── ExtendAbstractClass.pkl │ │ ├── ExtendModule.pkl │ │ ├── ExtendOpenClass.pkl │ │ ├── ExtendedSimple.pkl │ │ ├── Foo.pkl │ │ ├── HiddenProperties.pkl │ │ ├── Imports.pkl │ │ ├── Override.pkl │ │ ├── Override2.pkl │ │ ├── Simple.pkl │ │ ├── TypeAliased.pkl │ │ ├── UnionNameKeyword.pkl │ │ ├── Unions.pkl │ │ └── support │ │ │ ├── OpenModule.pkl │ │ │ ├── lib.pkl │ │ │ ├── lib2.pkl │ │ │ └── lib3.pkl │ ├── output │ │ ├── Classes_pkl.py │ │ ├── EmptyOpenModule_pkl.py │ │ ├── Enums_pkl.py │ │ ├── ExplicitlyCoolName_pkl.py │ │ ├── ExtendModule_pkl.py │ │ ├── ExtendingOpenClass_pkl.py │ │ ├── ExtendsAbstractClass_pkl.py │ │ ├── Foo_pkl.py │ │ ├── HiddenProperties_pkl.py │ │ ├── Imports_pkl.py │ │ ├── MyModule_pkl.py │ │ ├── Override2_pkl.py │ │ ├── TypeAliased_pkl.py │ │ ├── UnionNameKeyword_pkl.py │ │ ├── com_example_ExtendedSimple_pkl.py │ │ ├── com_example_Simple_pkl.py │ │ ├── lib3_pkl.py │ │ ├── override_pkl.py │ │ └── union_pkl.py │ ├── output_swift │ │ ├── Classes.pkl.swift │ │ ├── EmptyOpenModule.pkl.swift │ │ ├── Enums.pkl.swift │ │ ├── ExplicitlyCoolName.pkl.swift │ │ ├── ExtendModule.pkl.swift │ │ ├── ExtendingOpenClass.pkl.swift │ │ ├── ExtendsAbstractClass.pkl.swift │ │ ├── Foo.pkl.swift │ │ ├── HiddenProperties.pkl.swift │ │ ├── Imports.pkl.swift │ │ ├── MyModule.pkl.swift │ │ ├── Override2.pkl.swift │ │ ├── TypeAliased.pkl.swift │ │ ├── UnionNameKeyword.pkl.swift │ │ ├── com_example_ExtendedSimple.pkl.swift │ │ ├── com_example_Simple.pkl.swift │ │ ├── lib3.pkl.swift │ │ ├── override.pkl.swift │ │ └── union.pkl.swift │ └── test.pkl └── src │ ├── Generator.pkl │ ├── GeneratorSettings.pkl │ ├── PklProject │ ├── PklProject.deps.json │ ├── internal │ ├── ClassGen.pkl │ ├── Gen.pkl │ ├── PythonMapping.pkl │ ├── PythonNamespace.pkl │ ├── Type.pkl │ ├── TypeAliasGen.pkl │ ├── gatherer.pkl │ ├── typegen.pkl │ └── utils.pkl │ ├── python.pkl │ └── tests │ ├── ClassGen.pkl │ ├── fixtures │ ├── types.pkl │ ├── types2.pkl │ ├── types3.pkl │ └── types4.pkl │ ├── gatherer.pkl │ ├── typegen.pkl │ └── utils.pkl ├── generator-settings.pkl ├── pyproject.toml ├── scripts ├── download_binary.py ├── eval.py ├── foo.pkl ├── run_mod.sh └── run_py.sh ├── src ├── pkl │ ├── VERSION │ ├── __init__.py │ ├── binary_manager.py │ ├── evaluator_manager.py │ ├── evaluator_options.py │ ├── msgapi.py │ ├── parser.py │ ├── reader.py │ ├── server.py │ └── utils.py └── pkl_gen_python.py ├── tests ├── Fixtures │ ├── AnyType.pkl │ ├── ApiTypes.pkl │ ├── Classes.pkl │ ├── Collections.pkl │ ├── ExtendedModule.pkl │ ├── Generated │ │ ├── AnyType_pkl.py │ │ ├── ApiTypes_pkl.py │ │ ├── Classes_pkl.py │ │ ├── Collections_pkl.py │ │ ├── ExtendedModule_pkl.py │ │ ├── OpenModule_pkl.py │ │ ├── UnionTypes_pkl.py │ │ ├── pkl_python_example_Poly_pkl.py │ │ └── pkl_python_lib1_pkl.py │ ├── Generated_Swift │ │ ├── AnyType.pkl.swift │ │ ├── ApiTypes.pkl.swift │ │ ├── Classes.pkl.swift │ │ ├── Collections.pkl.swift │ │ ├── ExtendedModule.pkl.swift │ │ ├── OpenModule.pkl.swift │ │ ├── UnionTypes.pkl.swift │ │ ├── pkl_swift_example_Poly.pkl.swift │ │ └── pkl_swift_lib1.pkl.swift │ ├── OpenModule.pkl │ ├── Poly.pkl │ ├── UnionTypes.pkl │ ├── __init__.py │ └── lib1.pkl ├── __init__.py ├── _pkl │ ├── any.pkl │ ├── classes.pkl │ ├── collections.pkl │ ├── datasize.pkl │ ├── duration.pkl │ ├── dynamic.pkl │ ├── nullables.pkl │ ├── primitives.pkl │ ├── testfs │ │ ├── person.pkl │ │ └── subdir │ │ │ └── person.pkl │ ├── unions.pkl │ └── unknown_type.pkl ├── pkls │ ├── AppConfig.pkl │ ├── codegen.pkl │ ├── glob.pkl │ ├── myModule.pkl │ ├── types.pkl │ ├── with_log.pkl │ └── with_read.pkl ├── test_binary.py ├── test_evaluator_manager.py ├── test_fixtures.py ├── test_load.py ├── test_parser.py ├── test_readers.py ├── test_server.py ├── test_trace.py └── trace.pkl └── tox.ini /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Upload Python Package 10 | 11 | on: 12 | workflow_run: 13 | workflows: [Release] 14 | types: 15 | - completed 16 | 17 | permissions: 18 | contents: read 19 | 20 | jobs: 21 | deploy: 22 | 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v3 27 | - name: Set up Python 28 | uses: actions/setup-python@v3 29 | with: 30 | python-version: '3.x' 31 | - name: Install dependencies 32 | run: | 33 | python -m pip install --upgrade pip 34 | pip install build 35 | - name: Build package 36 | run: python -m build 37 | - name: Publish package 38 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 39 | with: 40 | user: __token__ 41 | password: ${{ secrets.PYPI_API_TOKEN }} 42 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*.*.*" 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v4 14 | 15 | - name: Package pkl 16 | run: make package 17 | 18 | - name: Get version from Makefile 19 | id: get_version 20 | run: | 21 | VERSION=$(make version) 22 | echo "VERSION=$VERSION" 23 | echo "VERSION=$VERSION" >> $GITHUB_ENV 24 | 25 | - name: Extract version from tag 26 | id: extract_tag_version 27 | run: | 28 | TAG_VERSION=${GITHUB_REF#refs/tags/v} 29 | echo "TAG_VERSION=$TAG_VERSION" >> $GITHUB_ENV 30 | 31 | - name: Compare versions 32 | run: | 33 | if [ "$TAG_VERSION" != "$VERSION" ]; then 34 | echo "Error: The tag version ($TAG_VERSION) does not match the Makefile version ($VERSION)" 35 | exit 1 36 | fi 37 | 38 | - name: Release 39 | uses: softprops/action-gh-release@v2 40 | if: startsWith(github.ref, 'refs/tags/') 41 | with: 42 | name: "Release v${{ env.VERSION }}" 43 | files: | 44 | output/pkl.python@${{ env.VERSION }} 45 | output/pkl.python@${{ env.VERSION }}.zip 46 | output/pkl.python@${{ env.VERSION }}.sha256 47 | output/pkl.python@${{ env.VERSION }}.zip.sha256 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__/ 3 | dist/ 4 | build/ 5 | *.egg-info/ 6 | .coverage/ 7 | .out/ 8 | 9 | src/pkl/bin/* 10 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v4.5.0 4 | hooks: 5 | - id: debug-statements 6 | - id: check-yaml 7 | - id: end-of-file-fixer 8 | - id: trailing-whitespace 9 | - repo: https://github.com/PyCQA/autoflake 10 | rev: v2.2.1 11 | hooks: 12 | - id: autoflake 13 | args: [--remove-all-unused-imports, --in-place] 14 | - repo: https://github.com/pycqa/isort 15 | rev: 5.13.2 16 | hooks: 17 | - id: isort 18 | name: isort (python) 19 | args: [--skip, codegen, --filter-files] 20 | - repo: https://github.com/psf/black 21 | rev: 23.12.1 22 | hooks: 23 | - id: black 24 | - repo: https://github.com/PyCQA/flake8 25 | rev: 6.1.0 # Use the latest flake8 version 26 | hooks: 27 | - id: flake8 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Jungwoo Yang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SNIPPET_INPUTS := $(shell find codegen/snippet-tests/input/*.pkl) 2 | FIXTURES_INPUTS := $(shell find tests/Fixtures/*.pkl) 3 | 4 | PACKAGE_DIR = ./codegen/src 5 | OUTPUT_DIR = output 6 | 7 | PROJECT_FILE := $(strip $(PACKAGE_DIR))/PklProject 8 | SUFFIXES := "" .sha256 .zip .zip.sha256 9 | 10 | PKL_BIN:=pkl_bin 11 | PKL_LATEST_RELEASE_URL=https://api.github.com/repos/apple/pkl/releases/latest 12 | PKL_DOWNLOAD_URL=$(shell curl -s $(PKL_LATEST_RELEASE_URL) | grep "browser_download_url.*pkl-linux-amd64" | cut -d : -f 2,3 | tr -d \") 13 | 14 | NAME = $(shell ./$(PKL_BIN) eval $(PROJECT_FILE) -x package.name) 15 | VERSION = $(shell ./$(PKL_BIN) eval $(PROJECT_FILE) -x package.version) 16 | #TARGETS = $(addprefix $(strip $(OUTPUT_DIR))/$(NAME)@$(VERSION),$(SUFFIXES)) 17 | 18 | #$(info PACKAGE_DIR is $(PACKAGE_DIR)) 19 | #$(info PROJECT_FILE is $(PROJECT_FILE)) 20 | #$(info NAME is $(NAME)) 21 | #$(info VERSION is $(VERSION)) 22 | #$(info SIGNATURE is $(SIGNATURE)) 23 | #$(info SUFFIXES is $(SUFFIXES)) 24 | #$(info TARGETS is $(TARGETS)) 25 | 26 | .PHONY: help 27 | help: 28 | @echo "Snippet tests:" 29 | @echo $(SNIPPET_INPUTS) | tr ' ' '\n' | sort 30 | 31 | @echo "Fixtures:" 32 | @echo $(FIXTURES_INPUTS) | tr ' ' '\n' | sort 33 | 34 | pkl_bin: 35 | @echo "Fetching latest release of pkl..." 36 | curl -L -o $(PKL_BIN) $(PKL_DOWNLOAD_URL) 37 | chmod +x $(PKL_BIN) 38 | ./$(PKL_BIN) --version 39 | 40 | .PHONY: build 41 | build: 42 | python -m build 43 | 44 | .PHONY: package 45 | package: pkl_bin 46 | ./$(PKL_BIN) project package $(PACKAGE_DIR) --output-path $(OUTPUT_DIR) 47 | 48 | $(TARGETS): pkl_package 49 | 50 | .PHONY: version 51 | version: pkl_bin 52 | @./$(PKL_BIN) eval $(PROJECT_FILE) -x package.version 53 | 54 | .PHONY: clean 55 | clean: 56 | rm -f $(PKL_BIN) 57 | rm -rf $(OUTPUT_DIR) 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!CAUTION] 2 | > 3 | > # THIS LIBRARY IS CURRENTLY PRE-RELEASE 4 | > 5 | > `pkl-python` is currently major version `v0`, and **breaking changes will happen** between versions. 6 | 7 | # pkl-python - Pkl Bindings for Python 8 | Python binding for [Apple's Pkl language](https://pkl-lang.org/index.html). 9 | 10 | ## Getting Started 11 | ### Installation 12 | 13 | ``` bash 14 | pip install pkl-python 15 | ``` 16 | 17 | ### Basic Usage 18 | Here's how you can start using `pkl-python` to load a PKL module: 19 | 20 | ```python 21 | import pkl 22 | 23 | config = pkl.load("path/to/pkl/example_module.pkl") 24 | config = pkl.loads("a: Int = 1 + 1") 25 | ``` 26 | 27 | ### Code Generation 28 | As Python is a dynamic language, codegen is not strictly necessary. 29 | However, codegen lets you expect contents of pkl files within Python modules. 30 | 31 | ``` 32 | pkl-gen-python path/to/pkl/example_module.pkl 33 | ``` 34 | 35 | ### TODO 36 | * [x] (codgen) pip binary installation 37 | * [ ] (codgen) gatherer depth-first ordering 38 | * [ ] (codgen) clean up code 39 | 40 | 41 | ## Advanced Features 42 | 43 | ```python 44 | import pkl 45 | 46 | config = pkl.load("./tests/types.pkl") 47 | config = pkl.load("./tests/types.pkl", expr="datasize") 48 | config = pkl.load(None, module_text="a: Int = 1 + 1") 49 | config = pkl.load("./tests/types.pkl", debug=True) 50 | ``` 51 | 52 | ### `pkl.load` Parameters Detail 53 | For details on the parameters, refer 54 | * [`pkl eval`](https://pkl-lang.org/main/current/pkl-cli/index.html#command-eval) 55 | * [Message Passing API](https://pkl-lang.org/main/current/bindings-specification/message-passing-api.html). 56 | 57 | ### Custom Readers 58 | It is possible to add module or resource or module readers: 59 | ```python 60 | from typing import List 61 | from dataclasses import dataclass 62 | 63 | import pkl 64 | from pkl import ( 65 | ModuleReader, ResourceReader, PathElement, 66 | ModuleSource, PreconfiguredOptions, PklError, 67 | ) 68 | 69 | class TestModuleReader(ModuleReader): 70 | def read(self, url) -> str: 71 | return "foo = 1" 72 | 73 | def list_elements(self, url: str) -> List[PathElement]: 74 | return [PathElement("foo.pkl", False)] 75 | 76 | opts = PreconfiguredOptions( 77 | moduleReaders=[TestModuleReader("customfs", True, True, True)] 78 | ) 79 | opts.allowedModules.append("customfs:") 80 | config = pkl.load("./tests/pkls/myModule.pkl", evaluator_options=opts) 81 | ``` 82 | 83 | ## Appendix 84 | 85 | ### Type Mappings 86 | 87 | While in pre-release they are subject to change. 88 | 89 | | Pkl type | TypeScript type | 90 | | ---------------- | -------------------------- | 91 | | Null | `None` | 92 | | Boolean | `bool` | 93 | | String | `str` | 94 | | Int | `int` | 95 | | Int8 | `int` | 96 | | Int16 | `int` | 97 | | Int32 | `int` | 98 | | UInt | `int` | 99 | | UInt8 | `int` | 100 | | UInt16 | `int` | 101 | | UInt32 | `int` | 102 | | Float | `float` | 103 | | Number | `float` | 104 | | List | `list` | 105 | | Listing | `list` | 106 | | Map | `dict` | 107 | | Mapping | `dict` | 108 | | Set | `set` | 109 | | Pair | `pkl.Pair` | 110 | | Dynamic | `dataclasses.dataclass` | 111 | | DataSize | `pkl.DataSize` | 112 | | Duration | `pkl.Duration` | 113 | | IntSeq | `pkl.IntSeq` | 114 | | Class | `dataclasses.dataclass` | 115 | | TypeAlias | `typing` | 116 | | Any | `typing.Any` | 117 | | Unions (A\|B\|C) | `typing.Union[A\|B\|C]` | 118 | | Regex | `pkl.Regex` | 119 | 120 | ## Contributing 121 | Contributions are welcome! If you'd like to contribute, please fork the repository and submit a pull request. For major changes, please open an issue first to discuss what you would like to change. 122 | 123 | ## License 124 | PKL is released under the MIT License. See the LICENSE file for more details. 125 | 126 | ## Contact 127 | For support or to contribute, please contact jwyang0213@gmail.com or visit our GitHub repository to report issues or submit pull requests. 128 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/Classes.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module Classes 17 | 18 | animals: Listing = new { 19 | new { name = "Uni" } 20 | new { name = "Wally" } 21 | new { name = "Mouse" } 22 | } 23 | 24 | open class Animal { 25 | name: String 26 | } 27 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/EmptyOpenModule.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | open module EmptyOpenModule 17 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/Enums.pkl: -------------------------------------------------------------------------------- 1 | /// City of tomorrow! 2 | city: City 3 | 4 | /// The animal 5 | animal: Animal 6 | 7 | /// Some dictionary or array type. 8 | dictOrArray: DictOrArray 9 | 10 | /// Bugs are cool. 11 | bug: BugBug 12 | 13 | horseOrBug: HorseOrBug 14 | 15 | /// City is one of these four fantastic cities 16 | typealias City = "San Francisco" | "London" | "Zurich" | "Cupertino" 17 | 18 | class Horse { 19 | neigh: Boolean 20 | } 21 | 22 | class Zebra { 23 | stripes: String 24 | } 25 | 26 | class Monkey { 27 | tail: String 28 | } 29 | 30 | /// Animal is either a horse, monkey, or zebra 31 | typealias Animal = Horse|Zebra|Monkey 32 | 33 | /// Either a dictionary or an array. 34 | typealias DictOrArray = Mapping|Listing 35 | 36 | typealias BugBug = "bug bug" | "bugBug" 37 | 38 | typealias HorseOrBug = Horse | "bug bug" | "bugBug" 39 | 40 | typealias MaybeHorseOrDefinitelyZebra = Horse? | Zebra 41 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/ExplicitName.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | @python.Module { name = "PythonExplicitName" } 17 | @python.Name { value = "ExplicitlyCoolName" } 18 | module ExplicitName 19 | 20 | import ".../src/python.pkl" 21 | 22 | @python.Name { value = "MyCoolProp" } 23 | myProp: SomethingFunny 24 | 25 | @python.Name { value = "SomethingVeryFunny" } 26 | class SomethingFunny { 27 | } 28 | 29 | @python.Name { value = "ConfigType" } 30 | typealias Type = "one"|"two" 31 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/ExtendAbstractClass.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module ExtendsAbstractClass 17 | 18 | abstract class A { 19 | b: String 20 | } 21 | 22 | class B extends A { 23 | b = "hi" 24 | c: String 25 | } 26 | 27 | a: A 28 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/ExtendModule.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | extends "support/OpenModule.pkl" 17 | 18 | bar: String 19 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/ExtendOpenClass.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module ExtendingOpenClass 17 | 18 | import "support/lib3.pkl" 19 | 20 | res1: MyClass 21 | 22 | res2: MyClass2 23 | 24 | open class MyOpenClass { 25 | myStr: String 26 | } 27 | 28 | class MyClass extends MyOpenClass { 29 | myStr = "mystr" 30 | myBoolean: Boolean 31 | } 32 | 33 | class MyClass2 extends lib3.GoGoGo { 34 | myBoolean: Boolean 35 | } 36 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/ExtendedSimple.pkl: -------------------------------------------------------------------------------- 1 | module com.example.ExtendedSimple 2 | 3 | import "Simple.pkl" 4 | 5 | /* 6 | class ExtendedSimple extends Simple.Person { 7 | eyeColor: String 8 | } 9 | */ 10 | class ExtendedSimpleClass extends Simple.Person { 11 | eyeColor: String 12 | } 13 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/Foo.pkl: -------------------------------------------------------------------------------- 1 | animals: Listing 2 | 3 | abstract class Being { 4 | exists: Boolean 5 | } 6 | 7 | open class Animal extends Being { 8 | name: String 9 | } 10 | 11 | class Bird extends Animal { 12 | flies: Boolean 13 | } 14 | 15 | class Dog extends Animal { 16 | barks: Boolean 17 | } 18 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/HiddenProperties.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module HiddenProperties 17 | 18 | hidden propA: String 19 | 20 | hidden propB: String 21 | 22 | propC: String = propA + propB 23 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/Imports.pkl: -------------------------------------------------------------------------------- 1 | import "Foo.pkl" 2 | 3 | foo: Foo 4 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/Override.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module `override` 17 | 18 | abstract class Foo { 19 | myProp: String 20 | } 21 | 22 | class Bar extends Foo { 23 | myProp = "Bar" 24 | } 25 | 26 | foo: Foo 27 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/Override2.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | open module Override2 17 | 18 | import "Override2.pkl" 19 | 20 | /// Doc comments 21 | foo: String 22 | 23 | class MySubclass extends Override2 { 24 | /// Different doc comments 25 | foo: String 26 | } 27 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/Simple.pkl: -------------------------------------------------------------------------------- 1 | module com.example.Simple 2 | 3 | /// This is truly a person. 4 | person: Person 5 | 6 | open class Person { 7 | /// The name of the person 8 | `the name`: String 9 | 10 | /// Some name that matches a keyword 11 | enum: String 12 | } 13 | 14 | class ThePerson extends Person { 15 | the: String 16 | } 17 | 18 | open class OpenClassExtendingOpenClass { 19 | someOtherProp: Boolean? 20 | } 21 | 22 | class ClassWithReallyLongConstructor { 23 | theProperty1: String 24 | 25 | theProperty2: String 26 | 27 | theProperty3: String 28 | 29 | theProperty4: String 30 | 31 | theProperty5: String 32 | 33 | theProperty6: String 34 | } 35 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/TypeAliased.pkl: -------------------------------------------------------------------------------- 1 | typealias StringyMap = Mapping 2 | 3 | myMap: StringyMap 4 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/UnionNameKeyword.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module UnionNameKeyword 17 | 18 | typealias Type = "one"|"two"|"three" 19 | 20 | type: Type 21 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/Unions.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module union 17 | 18 | /// A city 19 | city: City 20 | 21 | /// County 22 | county: County 23 | 24 | /// Noodles 25 | noodle: Noodles 26 | 27 | /// Account disposition 28 | disposition: AccountDisposition 29 | 30 | /// City; e.g. where people live 31 | typealias City = "San Francisco"|"London"|"上海" 32 | 33 | /// Locale that contains cities and towns 34 | typealias County = "San Francisco"|"San Mateo"|"Yolo" 35 | 36 | /// Noodles 37 | typealias Noodles = "拉面"|"刀切面"|"面线"|"意大利面" 38 | 39 | typealias AccountDisposition = ""|"icloud3"|"prod"|"shared" 40 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/support/OpenModule.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | open module MyModule 17 | 18 | foo: String 19 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/support/lib.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module lib 17 | 18 | open class MyClass { 19 | thing: String 20 | } 21 | 22 | typealias MyEnum = "one"|"two"|"three" 23 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/support/lib2.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module lib2 17 | 18 | typealias Cities = "London"|"San Francisco"|"Los Angeles" 19 | -------------------------------------------------------------------------------- /codegen/snippet-tests/input/support/lib3.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module lib3 17 | 18 | open class GoGoGo { 19 | duck: "quack" 20 | } 21 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/Classes_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `Classes`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class Animal: 12 | name: str 13 | 14 | _registered_identifier = "Classes#Animal" 15 | 16 | 17 | @dataclass 18 | class Classes: 19 | animals: List[Animal] 20 | 21 | _registered_identifier = "Classes" 22 | 23 | @classmethod 24 | def load_pkl(cls, source): 25 | # Load the Pkl module at the given source and evaluate it into `Classes.Module`. 26 | # - Parameter source: The source of the Pkl module. 27 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 28 | return config 29 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/EmptyOpenModule_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `EmptyOpenModule`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class EmptyOpenModule: 12 | _registered_identifier = "EmptyOpenModule" 13 | 14 | @classmethod 15 | def load_pkl(cls, source): 16 | # Load the Pkl module at the given source and evaluate it into `EmptyOpenModule.Module`. 17 | # - Parameter source: The source of the Pkl module. 18 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 19 | return config 20 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/Enums_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `Enums`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | City = Literal["San Francisco", "London", "Zurich", "Cupertino"] 11 | 12 | 13 | Animal = Union["Horse", "Zebra", "Monkey"] 14 | 15 | 16 | DictOrArray = Union[Dict[str, str], List[str]] 17 | 18 | 19 | BugBug = Literal["bug bug", "bugBug"] 20 | 21 | 22 | HorseOrBug = Union["Horse", Literal["bug bug", "bugBug"]] 23 | 24 | 25 | MaybeHorseOrDefinitelyZebra = Union[Optional["Horse"], "Zebra"] 26 | 27 | 28 | @dataclass 29 | class Monkey: 30 | tail: str 31 | 32 | _registered_identifier = "Enums#Monkey" 33 | 34 | 35 | @dataclass 36 | class Zebra: 37 | stripes: str 38 | 39 | _registered_identifier = "Enums#Zebra" 40 | 41 | 42 | @dataclass 43 | class Horse: 44 | neigh: bool 45 | 46 | _registered_identifier = "Enums#Horse" 47 | 48 | 49 | @dataclass 50 | class Enums: 51 | # City of tomorrow! 52 | city: City 53 | 54 | # The animal 55 | animal: Animal 56 | 57 | # Some dictionary or array type. 58 | dictOrArray: DictOrArray 59 | 60 | # Bugs are cool. 61 | bug: BugBug 62 | 63 | horseOrBug: HorseOrBug 64 | 65 | _registered_identifier = "Enums" 66 | 67 | @classmethod 68 | def load_pkl(cls, source): 69 | # Load the Pkl module at the given source and evaluate it into `Enums.Module`. 70 | # - Parameter source: The source of the Pkl module. 71 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 72 | return config 73 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/ExplicitlyCoolName_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `ExplicitName`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | ConfigType = Literal["one", "two"] 11 | 12 | 13 | @dataclass 14 | class SomethingVeryFunny: 15 | _registered_identifier = "ExplicitName#SomethingFunny" 16 | 17 | 18 | @dataclass 19 | class ExplicitName: 20 | MyCoolProp: SomethingVeryFunny 21 | 22 | _registered_identifier = "ExplicitName" 23 | 24 | @classmethod 25 | def load_pkl(cls, source): 26 | # Load the Pkl module at the given source and evaluate it into `ExplicitlyCoolName.Module`. 27 | # - Parameter source: The source of the Pkl module. 28 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 29 | return config 30 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/ExtendModule_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `ExtendModule`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | from . import MyModule_pkl 10 | 11 | 12 | @dataclass 13 | class ExtendModule(MyModule_pkl.MyModule): 14 | bar: str 15 | 16 | _registered_identifier = "ExtendModule" 17 | 18 | @classmethod 19 | def load_pkl(cls, source): 20 | # Load the Pkl module at the given source and evaluate it into `ExtendModule.Module`. 21 | # - Parameter source: The source of the Pkl module. 22 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 23 | return config 24 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/ExtendingOpenClass_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `ExtendingOpenClass`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | from . import lib3_pkl 10 | 11 | 12 | @dataclass 13 | class MyClass2(lib3_pkl.GoGoGo): 14 | myBoolean: bool 15 | 16 | _registered_identifier = "ExtendingOpenClass#MyClass2" 17 | 18 | 19 | @dataclass 20 | class MyOpenClass: 21 | myStr: str 22 | 23 | _registered_identifier = "ExtendingOpenClass#MyOpenClass" 24 | 25 | 26 | @dataclass 27 | class MyClass(MyOpenClass): 28 | myStr: str 29 | 30 | myBoolean: bool 31 | 32 | _registered_identifier = "ExtendingOpenClass#MyClass" 33 | 34 | 35 | @dataclass 36 | class ExtendingOpenClass: 37 | res1: MyClass 38 | 39 | res2: MyClass2 40 | 41 | _registered_identifier = "ExtendingOpenClass" 42 | 43 | @classmethod 44 | def load_pkl(cls, source): 45 | # Load the Pkl module at the given source and evaluate it into `ExtendingOpenClass.Module`. 46 | # - Parameter source: The source of the Pkl module. 47 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 48 | return config 49 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/ExtendsAbstractClass_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `ExtendsAbstractClass`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class A: 12 | b: str 13 | 14 | _registered_identifier = "ExtendsAbstractClass#A" 15 | 16 | 17 | @dataclass 18 | class B(A): 19 | b: str 20 | 21 | c: str 22 | 23 | _registered_identifier = "ExtendsAbstractClass#B" 24 | 25 | 26 | @dataclass 27 | class ExtendsAbstractClass: 28 | a: A 29 | 30 | _registered_identifier = "ExtendsAbstractClass" 31 | 32 | @classmethod 33 | def load_pkl(cls, source): 34 | # Load the Pkl module at the given source and evaluate it into `ExtendsAbstractClass.Module`. 35 | # - Parameter source: The source of the Pkl module. 36 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 37 | return config 38 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/Foo_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `Foo`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class Being: 12 | exists: bool 13 | 14 | _registered_identifier = "Foo#Being" 15 | 16 | 17 | @dataclass 18 | class Animal(Being): 19 | name: str 20 | 21 | _registered_identifier = "Foo#Animal" 22 | 23 | 24 | @dataclass 25 | class Dog(Animal): 26 | barks: bool 27 | 28 | _registered_identifier = "Foo#Dog" 29 | 30 | 31 | @dataclass 32 | class Bird(Animal): 33 | flies: bool 34 | 35 | _registered_identifier = "Foo#Bird" 36 | 37 | 38 | @dataclass 39 | class Foo: 40 | animals: List[Animal] 41 | 42 | _registered_identifier = "Foo" 43 | 44 | @classmethod 45 | def load_pkl(cls, source): 46 | # Load the Pkl module at the given source and evaluate it into `Foo.Module`. 47 | # - Parameter source: The source of the Pkl module. 48 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 49 | return config 50 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/HiddenProperties_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `HiddenProperties`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class HiddenProperties: 12 | propC: str 13 | 14 | _registered_identifier = "HiddenProperties" 15 | 16 | @classmethod 17 | def load_pkl(cls, source): 18 | # Load the Pkl module at the given source and evaluate it into `HiddenProperties.Module`. 19 | # - Parameter source: The source of the Pkl module. 20 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 21 | return config 22 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/Imports_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `Imports`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | from . import Foo_pkl 10 | 11 | 12 | @dataclass 13 | class Imports: 14 | foo: Foo_pkl.Foo 15 | 16 | _registered_identifier = "Imports" 17 | 18 | @classmethod 19 | def load_pkl(cls, source): 20 | # Load the Pkl module at the given source and evaluate it into `Imports.Module`. 21 | # - Parameter source: The source of the Pkl module. 22 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 23 | return config 24 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/MyModule_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `MyModule`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class MyModule: 12 | foo: str 13 | 14 | _registered_identifier = "MyModule" 15 | 16 | @classmethod 17 | def load_pkl(cls, source): 18 | # Load the Pkl module at the given source and evaluate it into `MyModule.Module`. 19 | # - Parameter source: The source of the Pkl module. 20 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 21 | return config 22 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/Override2_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `Override2`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class Override2: 12 | # Doc comments 13 | foo: str 14 | 15 | _registered_identifier = "Override2" 16 | 17 | 18 | @dataclass 19 | class MySubclass(Override2): 20 | # Different doc comments 21 | foo: str 22 | 23 | _registered_identifier = "Override2#MySubclass" 24 | 25 | @classmethod 26 | def load_pkl(cls, source): 27 | # Load the Pkl module at the given source and evaluate it into `Override2.Module`. 28 | # - Parameter source: The source of the Pkl module. 29 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 30 | return config 31 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/TypeAliased_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `TypeAliased`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | StringyMap = Dict[str, str] 11 | 12 | 13 | @dataclass 14 | class TypeAliased: 15 | myMap: StringyMap 16 | 17 | _registered_identifier = "TypeAliased" 18 | 19 | @classmethod 20 | def load_pkl(cls, source): 21 | # Load the Pkl module at the given source and evaluate it into `TypeAliased.Module`. 22 | # - Parameter source: The source of the Pkl module. 23 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 24 | return config 25 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/UnionNameKeyword_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `UnionNameKeyword`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | Type = Literal["one", "two", "three"] 11 | 12 | 13 | @dataclass 14 | class UnionNameKeyword: 15 | type: Type 16 | 17 | _registered_identifier = "UnionNameKeyword" 18 | 19 | @classmethod 20 | def load_pkl(cls, source): 21 | # Load the Pkl module at the given source and evaluate it into `UnionNameKeyword.Module`. 22 | # - Parameter source: The source of the Pkl module. 23 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 24 | return config 25 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/com_example_ExtendedSimple_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `com.example.ExtendedSimple`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | from . import com_example_Simple_pkl 10 | 11 | 12 | @dataclass 13 | class ExtendedSimpleClass(com_example_Simple_pkl.Person): 14 | eyeColor: str 15 | 16 | _registered_identifier = "com.example.ExtendedSimple#ExtendedSimpleClass" 17 | 18 | 19 | @dataclass 20 | class ExtendedSimple: 21 | _registered_identifier = "com.example.ExtendedSimple" 22 | 23 | @classmethod 24 | def load_pkl(cls, source): 25 | # Load the Pkl module at the given source and evaluate it into `com_example_ExtendedSimple.Module`. 26 | # - Parameter source: The source of the Pkl module. 27 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 28 | return config 29 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/com_example_Simple_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `com.example.Simple`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class ClassWithReallyLongConstructor: 12 | theProperty1: str 13 | 14 | theProperty2: str 15 | 16 | theProperty3: str 17 | 18 | theProperty4: str 19 | 20 | theProperty5: str 21 | 22 | theProperty6: str 23 | 24 | _registered_identifier = "com.example.Simple#ClassWithReallyLongConstructor" 25 | 26 | 27 | @dataclass 28 | class OpenClassExtendingOpenClass: 29 | someOtherProp: Optional[bool] 30 | 31 | _registered_identifier = "com.example.Simple#OpenClassExtendingOpenClass" 32 | 33 | 34 | @dataclass 35 | class Person: 36 | # The name of the person 37 | the_name: str 38 | 39 | # Some name that matches a keyword 40 | enum: str 41 | 42 | _registered_identifier = "com.example.Simple#Person" 43 | 44 | 45 | @dataclass 46 | class ThePerson(Person): 47 | the: str 48 | 49 | _registered_identifier = "com.example.Simple#ThePerson" 50 | 51 | 52 | @dataclass 53 | class Simple: 54 | # This is truly a person. 55 | person: Person 56 | 57 | _registered_identifier = "com.example.Simple" 58 | 59 | @classmethod 60 | def load_pkl(cls, source): 61 | # Load the Pkl module at the given source and evaluate it into `com_example_Simple.Module`. 62 | # - Parameter source: The source of the Pkl module. 63 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 64 | return config 65 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/lib3_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `lib3`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class GoGoGo: 12 | duck: Literal["quack"] 13 | 14 | _registered_identifier = "lib3#GoGoGo" 15 | 16 | 17 | @dataclass 18 | class lib3: 19 | _registered_identifier = "lib3" 20 | 21 | @classmethod 22 | def load_pkl(cls, source): 23 | # Load the Pkl module at the given source and evaluate it into `lib3.Module`. 24 | # - Parameter source: The source of the Pkl module. 25 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 26 | return config 27 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/override_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `override`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class Foo: 12 | myProp: str 13 | 14 | _registered_identifier = "override#Foo" 15 | 16 | 17 | @dataclass 18 | class Bar(Foo): 19 | myProp: str 20 | 21 | _registered_identifier = "override#Bar" 22 | 23 | 24 | @dataclass 25 | class override: 26 | foo: Foo 27 | 28 | _registered_identifier = "override" 29 | 30 | @classmethod 31 | def load_pkl(cls, source): 32 | # Load the Pkl module at the given source and evaluate it into `override.Module`. 33 | # - Parameter source: The source of the Pkl module. 34 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 35 | return config 36 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output/union_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `union`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any, Dict, List, Literal, Optional, Set, Union 6 | 7 | import pkl 8 | 9 | 10 | City = Literal["San Francisco", "London", "上海"] 11 | 12 | 13 | County = Literal["San Francisco", "San Mateo", "Yolo"] 14 | 15 | 16 | Noodles = Literal["拉面", "刀切面", "面线", "意大利面"] 17 | 18 | 19 | AccountDisposition = Literal["", "icloud3", "prod", "shared"] 20 | 21 | 22 | @dataclass 23 | class union: 24 | # A city 25 | city: City 26 | 27 | # County 28 | county: County 29 | 30 | # Noodles 31 | noodle: Noodles 32 | 33 | # Account disposition 34 | disposition: AccountDisposition 35 | 36 | _registered_identifier = "union" 37 | 38 | @classmethod 39 | def load_pkl(cls, source): 40 | # Load the Pkl module at the given source and evaluate it into `union.Module`. 41 | # - Parameter source: The source of the Pkl module. 42 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 43 | return config 44 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/Classes.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `Classes`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum Classes {} 5 | 6 | public protocol Classes_Animal: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var name: String { get } 8 | } 9 | 10 | extension Classes { 11 | public struct Module: PklRegisteredType, Decodable, Hashable { 12 | public static let registeredIdentifier: String = "Classes" 13 | 14 | public var animals: [any Animal] 15 | 16 | public init(animals: [any Animal]) { 17 | self.animals = animals 18 | } 19 | 20 | public static func ==(lhs: Module, rhs: Module) -> Bool { 21 | arrayEquals(arr1: lhs.animals, arr2: rhs.animals) 22 | } 23 | 24 | public func hash(into hasher: inout Hasher) { 25 | for x in self.animals { 26 | hasher.combine(x) 27 | } 28 | } 29 | 30 | public init(from decoder: Decoder) throws { 31 | let dec = try decoder.container(keyedBy: PklCodingKey.self) 32 | let animals = try dec.decode([PklSwift.PklAny].self, forKey: PklCodingKey(string: "animals")) 33 | .map { $0.value as! any Animal } 34 | self = Module(animals: animals) 35 | } 36 | } 37 | 38 | public typealias Animal = Classes_Animal 39 | 40 | public struct AnimalImpl: Animal { 41 | public static let registeredIdentifier: String = "Classes#Animal" 42 | 43 | public var name: String 44 | 45 | public init(name: String) { 46 | self.name = name 47 | } 48 | } 49 | 50 | /// Load the Pkl module at the given source and evaluate it into `Classes.Module`. 51 | /// 52 | /// - Parameter source: The source of the Pkl module. 53 | public static func loadFrom(source: ModuleSource) async throws -> Classes.Module { 54 | try await PklSwift.withEvaluator { evaluator in 55 | try await loadFrom(evaluator: evaluator, source: source) 56 | } 57 | } 58 | 59 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 60 | /// `Classes.Module`. 61 | /// 62 | /// - Parameter evaluator: The evaluator to use for evaluation. 63 | /// - Parameter source: The module to evaluate. 64 | public static func loadFrom( 65 | evaluator: PklSwift.Evaluator, 66 | source: PklSwift.ModuleSource 67 | ) async throws -> Classes.Module { 68 | try await evaluator.evaluateModule(source: source, as: Module.self) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/EmptyOpenModule.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `EmptyOpenModule`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum EmptyOpenModule {} 5 | 6 | public protocol EmptyOpenModule_Module: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | } 8 | 9 | extension EmptyOpenModule { 10 | public typealias Module = EmptyOpenModule_Module 11 | 12 | public struct ModuleImpl: Module { 13 | public static let registeredIdentifier: String = "EmptyOpenModule" 14 | 15 | public init() {} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/ExplicitlyCoolName.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `ExplicitName`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum ExplicitlyCoolName {} 5 | 6 | extension ExplicitlyCoolName { 7 | public enum ConfigType: String, CaseIterable, Decodable, Hashable { 8 | case one = "one" 9 | case two = "two" 10 | } 11 | 12 | public struct Module: PklRegisteredType, Decodable, Hashable { 13 | public static let registeredIdentifier: String = "ExplicitName" 14 | 15 | public var MyCoolProp: SomethingVeryFunny 16 | 17 | public init(MyCoolProp: SomethingVeryFunny) { 18 | self.MyCoolProp = MyCoolProp 19 | } 20 | 21 | enum CodingKeys: String, CodingKey { 22 | case MyCoolProp = "myProp" 23 | } 24 | } 25 | 26 | public struct SomethingVeryFunny: PklRegisteredType, Decodable, Hashable { 27 | public static let registeredIdentifier: String = "ExplicitName#SomethingFunny" 28 | 29 | public init() {} 30 | } 31 | 32 | /// Load the Pkl module at the given source and evaluate it into `ExplicitlyCoolName.Module`. 33 | /// 34 | /// - Parameter source: The source of the Pkl module. 35 | public static func loadFrom(source: ModuleSource) async throws -> ExplicitlyCoolName.Module { 36 | try await PklSwift.withEvaluator { evaluator in 37 | try await loadFrom(evaluator: evaluator, source: source) 38 | } 39 | } 40 | 41 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 42 | /// `ExplicitlyCoolName.Module`. 43 | /// 44 | /// - Parameter evaluator: The evaluator to use for evaluation. 45 | /// - Parameter source: The module to evaluate. 46 | public static func loadFrom( 47 | evaluator: PklSwift.Evaluator, 48 | source: PklSwift.ModuleSource 49 | ) async throws -> ExplicitlyCoolName.Module { 50 | try await evaluator.evaluateModule(source: source, as: Module.self) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/ExtendModule.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `ExtendModule`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum ExtendModule {} 5 | 6 | extension ExtendModule { 7 | public struct Module: MyModule.Module { 8 | public static let registeredIdentifier: String = "ExtendModule" 9 | 10 | public var bar: String 11 | 12 | public var foo: String 13 | 14 | public init(bar: String, foo: String) { 15 | self.bar = bar 16 | self.foo = foo 17 | } 18 | } 19 | 20 | /// Load the Pkl module at the given source and evaluate it into `ExtendModule.Module`. 21 | /// 22 | /// - Parameter source: The source of the Pkl module. 23 | public static func loadFrom(source: ModuleSource) async throws -> ExtendModule.Module { 24 | try await PklSwift.withEvaluator { evaluator in 25 | try await loadFrom(evaluator: evaluator, source: source) 26 | } 27 | } 28 | 29 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 30 | /// `ExtendModule.Module`. 31 | /// 32 | /// - Parameter evaluator: The evaluator to use for evaluation. 33 | /// - Parameter source: The module to evaluate. 34 | public static func loadFrom( 35 | evaluator: PklSwift.Evaluator, 36 | source: PklSwift.ModuleSource 37 | ) async throws -> ExtendModule.Module { 38 | try await evaluator.evaluateModule(source: source, as: Module.self) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/ExtendingOpenClass.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `ExtendingOpenClass`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum ExtendingOpenClass {} 5 | 6 | public protocol ExtendingOpenClass_MyOpenClass: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var myStr: String { get } 8 | } 9 | 10 | extension ExtendingOpenClass { 11 | public struct Module: PklRegisteredType, Decodable, Hashable { 12 | public static let registeredIdentifier: String = "ExtendingOpenClass" 13 | 14 | public var res1: MyClass 15 | 16 | public var res2: MyClass2 17 | 18 | public init(res1: MyClass, res2: MyClass2) { 19 | self.res1 = res1 20 | self.res2 = res2 21 | } 22 | } 23 | 24 | public struct MyClass: MyOpenClass { 25 | public static let registeredIdentifier: String = "ExtendingOpenClass#MyClass" 26 | 27 | public var myBoolean: Bool 28 | 29 | public var myStr: String 30 | 31 | public init(myBoolean: Bool, myStr: String) { 32 | self.myBoolean = myBoolean 33 | self.myStr = myStr 34 | } 35 | } 36 | 37 | public typealias MyOpenClass = ExtendingOpenClass_MyOpenClass 38 | 39 | public struct MyOpenClassImpl: MyOpenClass { 40 | public static let registeredIdentifier: String = "ExtendingOpenClass#MyOpenClass" 41 | 42 | public var myStr: String 43 | 44 | public init(myStr: String) { 45 | self.myStr = myStr 46 | } 47 | } 48 | 49 | public struct MyClass2: lib3.GoGoGo { 50 | public static let registeredIdentifier: String = "ExtendingOpenClass#MyClass2" 51 | 52 | public var myBoolean: Bool 53 | 54 | public var duck: String 55 | 56 | public init(myBoolean: Bool, duck: String) { 57 | self.myBoolean = myBoolean 58 | self.duck = duck 59 | } 60 | } 61 | 62 | /// Load the Pkl module at the given source and evaluate it into `ExtendingOpenClass.Module`. 63 | /// 64 | /// - Parameter source: The source of the Pkl module. 65 | public static func loadFrom(source: ModuleSource) async throws -> ExtendingOpenClass.Module { 66 | try await PklSwift.withEvaluator { evaluator in 67 | try await loadFrom(evaluator: evaluator, source: source) 68 | } 69 | } 70 | 71 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 72 | /// `ExtendingOpenClass.Module`. 73 | /// 74 | /// - Parameter evaluator: The evaluator to use for evaluation. 75 | /// - Parameter source: The module to evaluate. 76 | public static func loadFrom( 77 | evaluator: PklSwift.Evaluator, 78 | source: PklSwift.ModuleSource 79 | ) async throws -> ExtendingOpenClass.Module { 80 | try await evaluator.evaluateModule(source: source, as: Module.self) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/ExtendsAbstractClass.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `ExtendsAbstractClass`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum ExtendsAbstractClass {} 5 | 6 | public protocol ExtendsAbstractClass_A: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var b: String { get } 8 | } 9 | 10 | extension ExtendsAbstractClass { 11 | public struct Module: PklRegisteredType, Decodable, Hashable { 12 | public static let registeredIdentifier: String = "ExtendsAbstractClass" 13 | 14 | public var a: any A 15 | 16 | public init(a: any A) { 17 | self.a = a 18 | } 19 | 20 | public static func ==(lhs: Module, rhs: Module) -> Bool { 21 | lhs.a.isDynamicallyEqual(to: rhs.a) 22 | } 23 | 24 | public func hash(into hasher: inout Hasher) { 25 | hasher.combine(a) 26 | } 27 | 28 | public init(from decoder: Decoder) throws { 29 | let dec = try decoder.container(keyedBy: PklCodingKey.self) 30 | let a = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "a")) 31 | .value as! any A 32 | self = Module(a: a) 33 | } 34 | } 35 | 36 | public typealias A = ExtendsAbstractClass_A 37 | 38 | public struct B: A { 39 | public static let registeredIdentifier: String = "ExtendsAbstractClass#B" 40 | 41 | public var c: String 42 | 43 | public var b: String 44 | 45 | public init(c: String, b: String) { 46 | self.c = c 47 | self.b = b 48 | } 49 | } 50 | 51 | /// Load the Pkl module at the given source and evaluate it into `ExtendsAbstractClass.Module`. 52 | /// 53 | /// - Parameter source: The source of the Pkl module. 54 | public static func loadFrom(source: ModuleSource) async throws -> ExtendsAbstractClass.Module { 55 | try await PklSwift.withEvaluator { evaluator in 56 | try await loadFrom(evaluator: evaluator, source: source) 57 | } 58 | } 59 | 60 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 61 | /// `ExtendsAbstractClass.Module`. 62 | /// 63 | /// - Parameter evaluator: The evaluator to use for evaluation. 64 | /// - Parameter source: The module to evaluate. 65 | public static func loadFrom( 66 | evaluator: PklSwift.Evaluator, 67 | source: PklSwift.ModuleSource 68 | ) async throws -> ExtendsAbstractClass.Module { 69 | try await evaluator.evaluateModule(source: source, as: Module.self) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/Foo.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `Foo`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum Foo {} 5 | 6 | public protocol Foo_Animal: Foo_Being { 7 | var name: String { get } 8 | } 9 | 10 | public protocol Foo_Being: PklRegisteredType, DynamicallyEquatable, Hashable { 11 | var exists: Bool { get } 12 | } 13 | 14 | extension Foo { 15 | public struct Module: PklRegisteredType, Decodable, Hashable { 16 | public static let registeredIdentifier: String = "Foo" 17 | 18 | public var animals: [any Animal] 19 | 20 | public init(animals: [any Animal]) { 21 | self.animals = animals 22 | } 23 | 24 | public static func ==(lhs: Module, rhs: Module) -> Bool { 25 | arrayEquals(arr1: lhs.animals, arr2: rhs.animals) 26 | } 27 | 28 | public func hash(into hasher: inout Hasher) { 29 | for x in self.animals { 30 | hasher.combine(x) 31 | } 32 | } 33 | 34 | public init(from decoder: Decoder) throws { 35 | let dec = try decoder.container(keyedBy: PklCodingKey.self) 36 | let animals = try dec.decode([PklSwift.PklAny].self, forKey: PklCodingKey(string: "animals")) 37 | .map { $0.value as! any Animal } 38 | self = Module(animals: animals) 39 | } 40 | } 41 | 42 | public typealias Animal = Foo_Animal 43 | 44 | public struct AnimalImpl: Animal { 45 | public static let registeredIdentifier: String = "Foo#Animal" 46 | 47 | public var name: String 48 | 49 | public var exists: Bool 50 | 51 | public init(name: String, exists: Bool) { 52 | self.name = name 53 | self.exists = exists 54 | } 55 | } 56 | 57 | public typealias Being = Foo_Being 58 | 59 | public struct Bird: Animal { 60 | public static let registeredIdentifier: String = "Foo#Bird" 61 | 62 | public var flies: Bool 63 | 64 | public var name: String 65 | 66 | public var exists: Bool 67 | 68 | public init(flies: Bool, name: String, exists: Bool) { 69 | self.flies = flies 70 | self.name = name 71 | self.exists = exists 72 | } 73 | } 74 | 75 | public struct Dog: Animal { 76 | public static let registeredIdentifier: String = "Foo#Dog" 77 | 78 | public var barks: Bool 79 | 80 | public var name: String 81 | 82 | public var exists: Bool 83 | 84 | public init(barks: Bool, name: String, exists: Bool) { 85 | self.barks = barks 86 | self.name = name 87 | self.exists = exists 88 | } 89 | } 90 | 91 | /// Load the Pkl module at the given source and evaluate it into `Foo.Module`. 92 | /// 93 | /// - Parameter source: The source of the Pkl module. 94 | public static func loadFrom(source: ModuleSource) async throws -> Foo.Module { 95 | try await PklSwift.withEvaluator { evaluator in 96 | try await loadFrom(evaluator: evaluator, source: source) 97 | } 98 | } 99 | 100 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 101 | /// `Foo.Module`. 102 | /// 103 | /// - Parameter evaluator: The evaluator to use for evaluation. 104 | /// - Parameter source: The module to evaluate. 105 | public static func loadFrom( 106 | evaluator: PklSwift.Evaluator, 107 | source: PklSwift.ModuleSource 108 | ) async throws -> Foo.Module { 109 | try await evaluator.evaluateModule(source: source, as: Module.self) 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/HiddenProperties.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `HiddenProperties`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum HiddenProperties {} 5 | 6 | extension HiddenProperties { 7 | public struct Module: PklRegisteredType, Decodable, Hashable { 8 | public static let registeredIdentifier: String = "HiddenProperties" 9 | 10 | public var propC: String 11 | 12 | public init(propC: String) { 13 | self.propC = propC 14 | } 15 | } 16 | 17 | /// Load the Pkl module at the given source and evaluate it into `HiddenProperties.Module`. 18 | /// 19 | /// - Parameter source: The source of the Pkl module. 20 | public static func loadFrom(source: ModuleSource) async throws -> HiddenProperties.Module { 21 | try await PklSwift.withEvaluator { evaluator in 22 | try await loadFrom(evaluator: evaluator, source: source) 23 | } 24 | } 25 | 26 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 27 | /// `HiddenProperties.Module`. 28 | /// 29 | /// - Parameter evaluator: The evaluator to use for evaluation. 30 | /// - Parameter source: The module to evaluate. 31 | public static func loadFrom( 32 | evaluator: PklSwift.Evaluator, 33 | source: PklSwift.ModuleSource 34 | ) async throws -> HiddenProperties.Module { 35 | try await evaluator.evaluateModule(source: source, as: Module.self) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/Imports.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `Imports`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum Imports {} 5 | 6 | extension Imports { 7 | public struct Module: PklRegisteredType, Decodable, Hashable { 8 | public static let registeredIdentifier: String = "Imports" 9 | 10 | public var foo: Foo.Module 11 | 12 | public init(foo: Foo.Module) { 13 | self.foo = foo 14 | } 15 | } 16 | 17 | /// Load the Pkl module at the given source and evaluate it into `Imports.Module`. 18 | /// 19 | /// - Parameter source: The source of the Pkl module. 20 | public static func loadFrom(source: ModuleSource) async throws -> Imports.Module { 21 | try await PklSwift.withEvaluator { evaluator in 22 | try await loadFrom(evaluator: evaluator, source: source) 23 | } 24 | } 25 | 26 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 27 | /// `Imports.Module`. 28 | /// 29 | /// - Parameter evaluator: The evaluator to use for evaluation. 30 | /// - Parameter source: The module to evaluate. 31 | public static func loadFrom( 32 | evaluator: PklSwift.Evaluator, 33 | source: PklSwift.ModuleSource 34 | ) async throws -> Imports.Module { 35 | try await evaluator.evaluateModule(source: source, as: Module.self) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/MyModule.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `MyModule`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum MyModule {} 5 | 6 | public protocol MyModule_Module: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var foo: String { get } 8 | } 9 | 10 | extension MyModule { 11 | public typealias Module = MyModule_Module 12 | 13 | public struct ModuleImpl: Module { 14 | public static let registeredIdentifier: String = "MyModule" 15 | 16 | public var foo: String 17 | 18 | public init(foo: String) { 19 | self.foo = foo 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/Override2.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `Override2`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum Override2 {} 5 | 6 | public protocol Override2_Module: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var foo: String { get } 8 | } 9 | 10 | extension Override2 { 11 | public typealias Module = Override2_Module 12 | 13 | public struct ModuleImpl: Module { 14 | public static let registeredIdentifier: String = "Override2" 15 | 16 | /// Doc comments 17 | public var foo: String 18 | 19 | public init(foo: String) { 20 | self.foo = foo 21 | } 22 | } 23 | 24 | public struct MySubclass: Module { 25 | public static let registeredIdentifier: String = "Override2#MySubclass" 26 | 27 | /// Doc comments 28 | public var foo: String 29 | 30 | public init(foo: String) { 31 | self.foo = foo 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/TypeAliased.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `TypeAliased`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum TypeAliased {} 5 | 6 | extension TypeAliased { 7 | public struct Module: PklRegisteredType, Decodable, Hashable { 8 | public static let registeredIdentifier: String = "TypeAliased" 9 | 10 | public var myMap: StringyMap 11 | 12 | public init(myMap: StringyMap) { 13 | self.myMap = myMap 14 | } 15 | } 16 | 17 | public typealias StringyMap = [String: String] 18 | 19 | /// Load the Pkl module at the given source and evaluate it into `TypeAliased.Module`. 20 | /// 21 | /// - Parameter source: The source of the Pkl module. 22 | public static func loadFrom(source: ModuleSource) async throws -> TypeAliased.Module { 23 | try await PklSwift.withEvaluator { evaluator in 24 | try await loadFrom(evaluator: evaluator, source: source) 25 | } 26 | } 27 | 28 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 29 | /// `TypeAliased.Module`. 30 | /// 31 | /// - Parameter evaluator: The evaluator to use for evaluation. 32 | /// - Parameter source: The module to evaluate. 33 | public static func loadFrom( 34 | evaluator: PklSwift.Evaluator, 35 | source: PklSwift.ModuleSource 36 | ) async throws -> TypeAliased.Module { 37 | try await evaluator.evaluateModule(source: source, as: Module.self) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/UnionNameKeyword.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `UnionNameKeyword`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum UnionNameKeyword {} 5 | 6 | extension UnionNameKeyword { 7 | public enum `Type`: String, CaseIterable, Decodable, Hashable { 8 | case one = "one" 9 | case two = "two" 10 | case three = "three" 11 | } 12 | 13 | public struct Module: PklRegisteredType, Decodable, Hashable { 14 | public static let registeredIdentifier: String = "UnionNameKeyword" 15 | 16 | public var type: `Type` 17 | 18 | public init(type: `Type`) { 19 | self.type = type 20 | } 21 | } 22 | 23 | /// Load the Pkl module at the given source and evaluate it into `UnionNameKeyword.Module`. 24 | /// 25 | /// - Parameter source: The source of the Pkl module. 26 | public static func loadFrom(source: ModuleSource) async throws -> UnionNameKeyword.Module { 27 | try await PklSwift.withEvaluator { evaluator in 28 | try await loadFrom(evaluator: evaluator, source: source) 29 | } 30 | } 31 | 32 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 33 | /// `UnionNameKeyword.Module`. 34 | /// 35 | /// - Parameter evaluator: The evaluator to use for evaluation. 36 | /// - Parameter source: The module to evaluate. 37 | public static func loadFrom( 38 | evaluator: PklSwift.Evaluator, 39 | source: PklSwift.ModuleSource 40 | ) async throws -> UnionNameKeyword.Module { 41 | try await evaluator.evaluateModule(source: source, as: Module.self) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/com_example_ExtendedSimple.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `com.example.ExtendedSimple`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum com_example_ExtendedSimple {} 5 | 6 | extension com_example_ExtendedSimple { 7 | public struct Module: PklRegisteredType, Decodable, Hashable { 8 | public static let registeredIdentifier: String = "com.example.ExtendedSimple" 9 | 10 | public init() {} 11 | } 12 | 13 | public struct ExtendedSimple: com_example_Simple.Person { 14 | public static let registeredIdentifier: String = "com.example.ExtendedSimple#ExtendedSimple" 15 | 16 | public var eyeColor: String 17 | 18 | /// The name of the person 19 | public var theName: String 20 | 21 | /// Some name that matches a keyword 22 | public var `enum`: String 23 | 24 | public init(eyeColor: String, theName: String, `enum`: String) { 25 | self.eyeColor = eyeColor 26 | self.theName = theName 27 | self.`enum` = `enum` 28 | } 29 | 30 | enum CodingKeys: String, CodingKey { 31 | case eyeColor = "eyeColor" 32 | case theName = "the name" 33 | case `enum` = "enum" 34 | } 35 | } 36 | 37 | /// Load the Pkl module at the given source and evaluate it into `com_example_ExtendedSimple.Module`. 38 | /// 39 | /// - Parameter source: The source of the Pkl module. 40 | public static func loadFrom(source: ModuleSource) async throws -> com_example_ExtendedSimple.Module { 41 | try await PklSwift.withEvaluator { evaluator in 42 | try await loadFrom(evaluator: evaluator, source: source) 43 | } 44 | } 45 | 46 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 47 | /// `com_example_ExtendedSimple.Module`. 48 | /// 49 | /// - Parameter evaluator: The evaluator to use for evaluation. 50 | /// - Parameter source: The module to evaluate. 51 | public static func loadFrom( 52 | evaluator: PklSwift.Evaluator, 53 | source: PklSwift.ModuleSource 54 | ) async throws -> com_example_ExtendedSimple.Module { 55 | try await evaluator.evaluateModule(source: source, as: Module.self) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/com_example_Simple.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `com.example.Simple`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum com_example_Simple {} 5 | 6 | public protocol com_example_Simple_Person: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var theName: String { get } 8 | 9 | var `enum`: String { get } 10 | } 11 | 12 | public protocol com_example_Simple_OpenClassExtendingOpenClass: PklRegisteredType, DynamicallyEquatable, Hashable { 13 | var someOtherProp: Bool? { get } 14 | } 15 | 16 | extension com_example_Simple { 17 | public struct Module: PklRegisteredType, Decodable, Hashable { 18 | public static let registeredIdentifier: String = "com.example.Simple" 19 | 20 | /// This is truly a person. 21 | public var person: any Person 22 | 23 | public init(person: any Person) { 24 | self.person = person 25 | } 26 | 27 | public static func ==(lhs: Module, rhs: Module) -> Bool { 28 | lhs.person.isDynamicallyEqual(to: rhs.person) 29 | } 30 | 31 | public func hash(into hasher: inout Hasher) { 32 | hasher.combine(person) 33 | } 34 | 35 | public init(from decoder: Decoder) throws { 36 | let dec = try decoder.container(keyedBy: PklCodingKey.self) 37 | let person = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "person")) 38 | .value as! any Person 39 | self = Module(person: person) 40 | } 41 | } 42 | 43 | public typealias Person = com_example_Simple_Person 44 | 45 | public struct PersonImpl: Person { 46 | public static let registeredIdentifier: String = "com.example.Simple#Person" 47 | 48 | /// The name of the person 49 | public var theName: String 50 | 51 | /// Some name that matches a keyword 52 | public var `enum`: String 53 | 54 | public init(theName: String, `enum`: String) { 55 | self.theName = theName 56 | self.`enum` = `enum` 57 | } 58 | 59 | enum CodingKeys: String, CodingKey { 60 | case theName = "the name" 61 | case `enum` = "enum" 62 | } 63 | } 64 | 65 | public struct ThePerson: Person { 66 | public static let registeredIdentifier: String = "com.example.Simple#ThePerson" 67 | 68 | public var the: String 69 | 70 | /// The name of the person 71 | public var theName: String 72 | 73 | /// Some name that matches a keyword 74 | public var `enum`: String 75 | 76 | public init(the: String, theName: String, `enum`: String) { 77 | self.the = the 78 | self.theName = theName 79 | self.`enum` = `enum` 80 | } 81 | 82 | enum CodingKeys: String, CodingKey { 83 | case the = "the" 84 | case theName = "the name" 85 | case `enum` = "enum" 86 | } 87 | } 88 | 89 | public typealias OpenClassExtendingOpenClass = com_example_Simple_OpenClassExtendingOpenClass 90 | 91 | public struct OpenClassExtendingOpenClassImpl: OpenClassExtendingOpenClass { 92 | public static let registeredIdentifier: String = "com.example.Simple#OpenClassExtendingOpenClass" 93 | 94 | public var someOtherProp: Bool? 95 | 96 | public init(someOtherProp: Bool?) { 97 | self.someOtherProp = someOtherProp 98 | } 99 | } 100 | 101 | public struct ClassWithReallyLongConstructor: PklRegisteredType, Decodable, Hashable { 102 | public static let registeredIdentifier: String = "com.example.Simple#ClassWithReallyLongConstructor" 103 | 104 | public var theProperty1: String 105 | 106 | public var theProperty2: String 107 | 108 | public var theProperty3: String 109 | 110 | public var theProperty4: String 111 | 112 | public var theProperty5: String 113 | 114 | public var theProperty6: String 115 | 116 | public init( 117 | theProperty1: String, 118 | theProperty2: String, 119 | theProperty3: String, 120 | theProperty4: String, 121 | theProperty5: String, 122 | theProperty6: String 123 | ) { 124 | self.theProperty1 = theProperty1 125 | self.theProperty2 = theProperty2 126 | self.theProperty3 = theProperty3 127 | self.theProperty4 = theProperty4 128 | self.theProperty5 = theProperty5 129 | self.theProperty6 = theProperty6 130 | } 131 | } 132 | 133 | /// Load the Pkl module at the given source and evaluate it into `com_example_Simple.Module`. 134 | /// 135 | /// - Parameter source: The source of the Pkl module. 136 | public static func loadFrom(source: ModuleSource) async throws -> com_example_Simple.Module { 137 | try await PklSwift.withEvaluator { evaluator in 138 | try await loadFrom(evaluator: evaluator, source: source) 139 | } 140 | } 141 | 142 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 143 | /// `com_example_Simple.Module`. 144 | /// 145 | /// - Parameter evaluator: The evaluator to use for evaluation. 146 | /// - Parameter source: The module to evaluate. 147 | public static func loadFrom( 148 | evaluator: PklSwift.Evaluator, 149 | source: PklSwift.ModuleSource 150 | ) async throws -> com_example_Simple.Module { 151 | try await evaluator.evaluateModule(source: source, as: Module.self) 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/lib3.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `lib3`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum lib3 {} 5 | 6 | public protocol lib3_GoGoGo: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var duck: String { get } 8 | } 9 | 10 | extension lib3 { 11 | public typealias GoGoGo = lib3_GoGoGo 12 | 13 | public struct GoGoGoImpl: GoGoGo { 14 | public static let registeredIdentifier: String = "lib3#GoGoGo" 15 | 16 | public var duck: String 17 | 18 | public init(duck: String) { 19 | self.duck = duck 20 | } 21 | } 22 | 23 | public struct Module: PklRegisteredType, Decodable, Hashable { 24 | public static let registeredIdentifier: String = "lib3" 25 | 26 | public init() {} 27 | } 28 | 29 | /// Load the Pkl module at the given source and evaluate it into `lib3.Module`. 30 | /// 31 | /// - Parameter source: The source of the Pkl module. 32 | public static func loadFrom(source: ModuleSource) async throws -> lib3.Module { 33 | try await PklSwift.withEvaluator { evaluator in 34 | try await loadFrom(evaluator: evaluator, source: source) 35 | } 36 | } 37 | 38 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 39 | /// `lib3.Module`. 40 | /// 41 | /// - Parameter evaluator: The evaluator to use for evaluation. 42 | /// - Parameter source: The module to evaluate. 43 | public static func loadFrom( 44 | evaluator: PklSwift.Evaluator, 45 | source: PklSwift.ModuleSource 46 | ) async throws -> lib3.Module { 47 | try await evaluator.evaluateModule(source: source, as: Module.self) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/override.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `override`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum override {} 5 | 6 | public protocol override_Foo: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var myProp: String { get } 8 | } 9 | 10 | extension override { 11 | public struct Module: PklRegisteredType, Decodable, Hashable { 12 | public static let registeredIdentifier: String = "override" 13 | 14 | public var foo: any Foo 15 | 16 | public init(foo: any Foo) { 17 | self.foo = foo 18 | } 19 | 20 | public static func ==(lhs: Module, rhs: Module) -> Bool { 21 | lhs.foo.isDynamicallyEqual(to: rhs.foo) 22 | } 23 | 24 | public func hash(into hasher: inout Hasher) { 25 | hasher.combine(foo) 26 | } 27 | 28 | public init(from decoder: Decoder) throws { 29 | let dec = try decoder.container(keyedBy: PklCodingKey.self) 30 | let foo = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "foo")) 31 | .value as! any Foo 32 | self = Module(foo: foo) 33 | } 34 | } 35 | 36 | public typealias Foo = override_Foo 37 | 38 | public struct Bar: Foo { 39 | public static let registeredIdentifier: String = "override#Bar" 40 | 41 | public var myProp: String 42 | 43 | public init(myProp: String) { 44 | self.myProp = myProp 45 | } 46 | } 47 | 48 | /// Load the Pkl module at the given source and evaluate it into `override.Module`. 49 | /// 50 | /// - Parameter source: The source of the Pkl module. 51 | public static func loadFrom(source: ModuleSource) async throws -> override.Module { 52 | try await PklSwift.withEvaluator { evaluator in 53 | try await loadFrom(evaluator: evaluator, source: source) 54 | } 55 | } 56 | 57 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 58 | /// `override.Module`. 59 | /// 60 | /// - Parameter evaluator: The evaluator to use for evaluation. 61 | /// - Parameter source: The module to evaluate. 62 | public static func loadFrom( 63 | evaluator: PklSwift.Evaluator, 64 | source: PklSwift.ModuleSource 65 | ) async throws -> override.Module { 66 | try await evaluator.evaluateModule(source: source, as: Module.self) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /codegen/snippet-tests/output_swift/union.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `union`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum union {} 5 | 6 | extension union { 7 | /// City; e.g. where people live 8 | public enum City: String, CaseIterable, Decodable, Hashable { 9 | case sanFrancisco = "San Francisco" 10 | case london = "London" 11 | case 上海 = "上海" 12 | } 13 | 14 | /// Locale that contains cities and towns 15 | public enum County: String, CaseIterable, Decodable, Hashable { 16 | case sanFrancisco = "San Francisco" 17 | case sanMateo = "San Mateo" 18 | case yolo = "Yolo" 19 | } 20 | 21 | /// Noodles 22 | public enum Noodles: String, CaseIterable, Decodable, Hashable { 23 | case 拉面 = "拉面" 24 | case 刀切面 = "刀切面" 25 | case 面线 = "面线" 26 | case 意大利面 = "意大利面" 27 | } 28 | 29 | public enum AccountDisposition: String, CaseIterable, Decodable, Hashable { 30 | case empty = "" 31 | case icloud3 = "icloud3" 32 | case prod = "prod" 33 | case shared = "shared" 34 | } 35 | 36 | public struct Module: PklRegisteredType, Decodable, Hashable { 37 | public static let registeredIdentifier: String = "union" 38 | 39 | /// A city 40 | public var city: City 41 | 42 | /// County 43 | public var county: County 44 | 45 | /// Noodles 46 | public var noodle: Noodles 47 | 48 | /// Account disposition 49 | public var disposition: AccountDisposition 50 | 51 | public init(city: City, county: County, noodle: Noodles, disposition: AccountDisposition) { 52 | self.city = city 53 | self.county = county 54 | self.noodle = noodle 55 | self.disposition = disposition 56 | } 57 | } 58 | 59 | /// Load the Pkl module at the given source and evaluate it into `union.Module`. 60 | /// 61 | /// - Parameter source: The source of the Pkl module. 62 | public static func loadFrom(source: ModuleSource) async throws -> union.Module { 63 | try await PklSwift.withEvaluator { evaluator in 64 | try await loadFrom(evaluator: evaluator, source: source) 65 | } 66 | } 67 | 68 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 69 | /// `union.Module`. 70 | /// 71 | /// - Parameter evaluator: The evaluator to use for evaluation. 72 | /// - Parameter source: The module to evaluate. 73 | public static func loadFrom( 74 | evaluator: PklSwift.Evaluator, 75 | source: PklSwift.ModuleSource 76 | ) async throws -> union.Module { 77 | try await evaluator.evaluateModule(source: source, as: Module.self) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /codegen/snippet-tests/test.pkl: -------------------------------------------------------------------------------- 1 | amends "pkl:test" 2 | 3 | import "pkl:reflect" 4 | import "../src/Generator.pkl" 5 | 6 | facts { 7 | for (_, mod in import*("input/*.pkl")) { 8 | [reflect.Module(mod).name] { 9 | for (name, output in new Generator { moduleToGenerate = mod }.output.files!!) { 10 | read?("output/\(name)")?.text == output.text 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /codegen/src/Generator.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | /// Generates Python sources from Pkl 17 | @python.Module { name = "pkl_gen_python" } 18 | @ModuleInfo { minPklVersion = "0.24.0" } 19 | module pkl.python.Generator 20 | 21 | import "pkl:reflect" 22 | import "internal/gatherer.pkl" 23 | import "internal/PythonMapping.pkl" 24 | import "internal/PythonNamespace.pkl" 25 | import "internal/utils.pkl" 26 | import "python.pkl" 27 | 28 | /// The module that should be generated. 29 | moduleToGenerate: Module 30 | 31 | /// The indentation applied to rendered Python code. 32 | indent: String = " " 33 | 34 | // noinspection UnresolvedElement 35 | function getPythonModuleName(decl: reflect.TypeDeclaration): String? = 36 | decl.enclosingDeclaration 37 | .annotations 38 | .findOrNull((it) -> it.getClass().toString() == "pkl.python.python#Module") 39 | ?.name 40 | 41 | function gatherTypeAliases(decl: List): Mixin> = 42 | (acc) -> 43 | decl 44 | //.filter((it) -> it is reflect.TypeAlias && !isEnumLike(it)) 45 | .filter((it) -> it is reflect.TypeAlias) 46 | .fold(acc, (accum, it) -> accum.add(new PythonMapping.TypeAlias { 47 | pythonModuleName = getPythonModuleName(it) 48 | source = it 49 | seenMappings = accum 50 | })) 51 | 52 | function gatherClasses(decl: List): Mixin> = 53 | (acc) -> 54 | decl 55 | .filter((it) -> it is reflect.Class) 56 | .fold(acc, (accum, it) -> accum.add(new PythonMapping.Class { 57 | pythonModuleName = getPythonModuleName(it) 58 | source = it 59 | seenMappings = accum 60 | })) 61 | 62 | local allMappings: List = 63 | let (clazz = reflect.Module(moduleToGenerate).moduleClass) 64 | let (declarations = gatherer.gatherTypeDeclarations(clazz, List())) 65 | List() |> gatherClasses(declarations) |> gatherTypeAliases(declarations) 66 | 67 | local packages = allMappings 68 | .groupBy((it) -> it.namespaceName) 69 | .mapValues((namespace: String, _mappings: List) -> new PythonNamespace { 70 | namespaceName = namespace 71 | `module` = _mappings.first.source.enclosingDeclaration 72 | mappings = allMappings 73 | moduleMappings = _mappings 74 | indent = module.indent 75 | }) 76 | 77 | output { 78 | files { 79 | for (_, package in packages) { 80 | ...package.output.files!! 81 | } 82 | } 83 | text = throw("Generator.pkl only produces multiple-file output. Try running again with the -m flag.") 84 | } 85 | -------------------------------------------------------------------------------- /codegen/src/GeneratorSettings.pkl: -------------------------------------------------------------------------------- 1 | /// Settings used to configure code generation. 2 | @python.Module { name = "pkl_gen_python" } 3 | @python.Name { value = "GeneratorSettings" } 4 | module pkl.python.GeneratorSettings 5 | 6 | import "pkl:reflect" 7 | import "python.pkl" 8 | 9 | /// The set of modules to turn into Swift code. 10 | /// 11 | /// A module's dependencies are also included in code generation. 12 | /// Therefore, in most cases, it is only necessary to provide the entrypoint for code generation. 13 | inputs: Listing? 14 | 15 | /// The output path to write generated files into. 16 | /// 17 | /// Defaults to `.out`. Relative paths are resolved against the enclosing directory. 18 | outputPath: String? 19 | 20 | /// If [true], prints the filenames that would be created, but skips writing any files. 21 | dryRun: Boolean? 22 | 23 | /// The Generator.pkl script to use for code generation. 24 | /// 25 | /// This is an internal setting that's meant for development purposes. 26 | generateScript: String? 27 | 28 | output { 29 | local myModuleDirectory = 30 | let (myModuleUri = reflect.Module(module).uri) 31 | myModuleUri.replaceFirst("file://", "").split("/").dropLast(1).join("/") 32 | 33 | local function resolvePath(path: String): String = 34 | if (path.startsWith(Regex("\\w+:")) || path.startsWith("/")) path 35 | else myModuleDirectory + "/" + path 36 | 37 | value = (module) { 38 | when (module.inputs != null) { 39 | inputs = new { 40 | for (input in module.inputs!!) { 41 | resolvePath(input) 42 | } 43 | } 44 | } 45 | when (module.outputPath != null) { 46 | outputPath = resolvePath(module.outputPath!!) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /codegen/src/PklProject: -------------------------------------------------------------------------------- 1 | amends "pkl:Project" 2 | 3 | local github_base = "github.com/jw-y/pkl-python" 4 | local github_version = read("../../src/pkl/VERSION").text.trim() 5 | local github_tag = "v\(github_version)" 6 | 7 | package { 8 | name = "pkl.python" 9 | baseUri = "package://\(github_base)/\(name)" 10 | packageZipUrl = "https://\(github_base)/releases/download/\(github_tag)/\(name)@\(version).zip" 11 | version = github_version 12 | authors { 13 | "Jungwoo Yang " 14 | } 15 | sourceCodeUrlScheme = "https://\(github_base)/blob/\(version)/codegen/src%{path}#L%{line}-L%{endLine}" 16 | sourceCode = "https://\(github_base)" 17 | description = "Pkl bindings for the Python programming language" 18 | license = "Apache-2.0" 19 | exclude { 20 | "tests" 21 | "tests/**" 22 | } 23 | } 24 | 25 | tests { 26 | for (key, _ in import*("tests/*.pkl")) { 27 | key 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codegen/src/PklProject.deps.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "resolvedDependencies": {} 4 | } 5 | -------------------------------------------------------------------------------- /codegen/src/internal/Gen.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | @Unlisted 17 | abstract module pkl.python.internal.Gen 18 | 19 | import "PythonMapping.pkl" 20 | 21 | /// The generated contents for this particular mapping. 22 | mapping: PythonMapping 23 | 24 | /// All mappings 25 | mappings: List 26 | 27 | /// The Python source code 28 | contents: String 29 | 30 | /// Python source code to be put outside the extension, at the top level 31 | topLevelContents: String? 32 | 33 | /// The name of the namespace 34 | namespaceName: String 35 | 36 | /// The indentation applied to generated Python code. 37 | indent: String 38 | -------------------------------------------------------------------------------- /codegen/src/internal/PythonMapping.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | @Unlisted 17 | abstract module pkl.python.internal.PythonMapping 18 | 19 | import "PythonMapping.pkl" 20 | import "Type.pkl" 21 | import "pkl:reflect" 22 | import "utils.pkl" 23 | 24 | /// The Python module name, e.g. `AppConfig` 25 | /// 26 | /// This determines whether imports need to be generated or not. 27 | pythonModuleName: String? 28 | 29 | /// The name for the namespace (generated as an enum) 30 | fixed namespaceName: String = 31 | utils.getPythonNameAnnotation(source.enclosingDeclaration) 32 | ?? utils.normalizeName(source.enclosingDeclaration.name.replaceAll(".", "_")) 33 | 34 | /// The exposed simple name of this type (either the enum's name or the struct or protocol name). 35 | name: String 36 | 37 | /// All names exposed by this mapping 38 | /// 39 | /// For example, if there is both a protocol and a struct implementation, this includes both names. 40 | names: List 41 | 42 | seenMappings: List 43 | 44 | /// The source for this mapping 45 | source: reflect.TypeDeclaration 46 | 47 | /// The exposed Python type. 48 | type: Type 49 | 50 | /// The set of names already seen prior to creating mappings for this module. 51 | existingNames: List = seenMappings.flatMap((it) -> 52 | if (it.pythonModuleName == module.pythonModuleName) it.names 53 | else List() 54 | ) 55 | 56 | class TypeAlias extends PythonMapping { 57 | local self = this 58 | 59 | alias: reflect.TypeAlias = self.source as reflect.TypeAlias 60 | 61 | name = utils.toPythonName(self.source) 62 | 63 | names = List(name) 64 | 65 | type = new Type.Declared { 66 | typeName = name 67 | namespaceName = self.namespaceName 68 | pythonModuleName = self.pythonModuleName 69 | } 70 | } 71 | 72 | class Class extends PythonMapping { 73 | local self = this 74 | 75 | clazz: reflect.Class = self.source as reflect.Class 76 | 77 | names = List(inner.name).filterNonNull() as List 78 | 79 | type = (inner).type 80 | 81 | name = utils.toPythonName(clazz) 82 | 83 | inner: ClassInner = new ClassInner{ 84 | name = self.name 85 | clazz = self.clazz 86 | type = new Type.Declared { 87 | typeName = name 88 | namespaceName = self.namespaceName 89 | pythonModuleName = self.pythonModuleName 90 | } 91 | } 92 | } 93 | 94 | class ClassInner { 95 | name: String 96 | clazz: reflect.Class 97 | type: Type 98 | } 99 | -------------------------------------------------------------------------------- /codegen/src/internal/TypeAliasGen.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | @Unlisted 17 | module pkl.python.internal.TypeAliasGen 18 | 19 | extends "Gen.pkl" 20 | 21 | import "typegen.pkl" 22 | import "Type.pkl" 23 | import "pkl:reflect" 24 | 25 | typealiaz: reflect.TypeAlias = mapping.source as reflect.TypeAlias 26 | 27 | type: Type = typegen.generateType(typealiaz.referent, typealiaz, mappings) 28 | 29 | contents = "\(mapping.name) = \(type.renderForwardSafe(namespaceName))" 30 | -------------------------------------------------------------------------------- /codegen/src/internal/gatherer.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | @Unlisted 17 | module pkl.python.internal.gatherer 18 | 19 | import "pkl:reflect" 20 | import "typegen.pkl" 21 | 22 | /// Given a [reflect.TypeDeclaration], collect all referenced classes or typealiases. 23 | /// 24 | /// Looks in properties, super classes, class/typealias members of enclosing modules, and generic 25 | /// type arguments. 26 | /// 27 | /// This omits core built-in types. 28 | function gatherTypeDeclarations( 29 | decl: reflect.TypeDeclaration, 30 | seen: List 31 | ): List = 32 | if (seen.contains(decl)) seen 33 | else if (typegen.mappedTypes.containsKey(decl.reflectee)) seen 34 | else if (decl is reflect.Class) 35 | if (isAnnotationClass(decl) || isBuiltinClass(decl)) seen 36 | else 37 | seen.add(decl) 38 | |> gatherPropertiesDeclarations(decl) 39 | |> gatherSuperDeclarations(decl) 40 | |> gatherModuleClasses(decl) 41 | |> gatherModuleTypeAliases(decl) 42 | |> gatherModule(decl) 43 | else if (decl is reflect.TypeAlias) 44 | seen.add(decl) |> gatherTypeArguments(decl) 45 | else seen 46 | 47 | /// Tells if this class is part of the stdlib. 48 | function isBuiltinClass(clazz: reflect.Class): Boolean = clazz.enclosingDeclaration.uri.startsWith("pkl:") 49 | 50 | function gatherTypeDeclarationsFromType( 51 | type: reflect.Type, 52 | enclosingDeclaration: reflect.TypeDeclaration, 53 | seen: List 54 | ): List = 55 | if (type is reflect.DeclaredType) 56 | let (referent = type.referent) 57 | if (referent is reflect.Class && isBuiltinClass(referent)) 58 | // TODO: why is this false? 59 | // let (_ = trace(reflect.DeclaredType(type.referent) == type)) 60 | type.typeArguments.fold(seen, (acc, it) -> gatherTypeDeclarationsFromType(it, referent, acc)) 61 | else 62 | gatherTypeDeclarations(referent, seen) 63 | else if (type is reflect.NullableType) 64 | gatherTypeDeclarationsFromType(type.member, enclosingDeclaration, seen) 65 | else if (type is reflect.UnionType) 66 | type.members.fold(seen, (acc, t) -> gatherTypeDeclarationsFromType(t, enclosingDeclaration, acc)) 67 | else 68 | // Remaining types: ModuleType, StringLiteralType, FunctionType, TypeVariable, NothingType. 69 | // None of these have a reference to a TypeDeclaration. 70 | seen 71 | 72 | function gatherPropertiesDeclarations(clazz: reflect.Class) = 73 | (seen: List) -> 74 | clazz.properties.values.fold( 75 | seen, 76 | (acc, p) -> gatherTypeDeclarationsFromType(p.type, clazz, acc) 77 | ) 78 | 79 | function gatherSuperDeclarations(clazz: reflect.Class) = 80 | (seen: List) -> 81 | let (superclass = clazz.superclass) 82 | if (superclass == null) 83 | seen 84 | else 85 | gatherTypeDeclarations(superclass, seen) 86 | 87 | function gatherModuleClasses(clazz: reflect.Class) = 88 | (seen: List) -> 89 | if (clazz.superclass != reflect.Class(Module)) 90 | seen 91 | else 92 | clazz.enclosingDeclaration.classes.fold( 93 | seen, 94 | (acc, _, clazz) -> gatherTypeDeclarations(clazz, acc) 95 | ) 96 | 97 | function gatherModuleTypeAliases(clazz: reflect.Class) = 98 | (seen: List) -> 99 | if (clazz.superclass != reflect.Class(Module)) 100 | seen 101 | else 102 | clazz.enclosingDeclaration.typeAliases.fold( 103 | seen, 104 | (acc, _, alias) -> gatherTypeDeclarations(alias, acc) 105 | ) 106 | 107 | function gatherModule(decl: reflect.TypeDeclaration) = 108 | (seen: List) -> 109 | gatherTypeDeclarations(decl.enclosingDeclaration.moduleClass, seen) 110 | 111 | function gatherTypeArguments(clazz: reflect.TypeDeclaration) = 112 | (seen: List) -> 113 | reflect.DeclaredType(clazz).typeArguments 114 | .fold(seen, (acc, it) -> gatherTypeDeclarationsFromType(it, clazz, acc)) 115 | 116 | function isAnnotationClass(clazz: reflect.Class): Boolean = 117 | if (clazz.reflectee == Annotation) true 118 | else if (clazz.superclass != null) isAnnotationClass(clazz.superclass!!) 119 | else false 120 | -------------------------------------------------------------------------------- /codegen/src/internal/utils.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | @Unlisted 17 | module pkl.python.internal.utils 18 | 19 | import "pkl:reflect" 20 | 21 | local pcfRenderer: PcfRenderer = new { useCustomStringDelimiters = true } 22 | 23 | /// Turn the Pkl string into a Python string literal. 24 | /// 25 | /// We can use the pcf renderer here because Pkl and Python share almost the same grammar for 26 | /// strings. 27 | function toPythonString(str: String): String = pcfRenderer.renderValue(str) 28 | 29 | // noinspection UnresolvedElement 30 | function getPythonNameAnnotation(source: reflect.Declaration): String? = 31 | source 32 | .annotations 33 | .findOrNull((it) -> it.getClass().toString() == "pkl.python.python#Name") 34 | ?.value 35 | 36 | /// Converts a Pkl declaration (class, property, typealias) into a Python name. 37 | /// If a member has an explicit `@python.Name` annotation, use it. 38 | /// 39 | /// Otherwise, normalize the name and return it. 40 | /// 41 | /// Normalization rules: 42 | /// 43 | /// 1. Any non-letter and non-digit characters get stripped, and each proceding letter gets capitalized. 44 | /// 2. If a name does not start with a latin alphabet character, prefix with `N`. 45 | /// 3. Capitalize names so they get exported. 46 | function toPythonName(source: reflect.Declaration): String = 47 | // Edge case: if we are generating a module class, always call it `Module`. 48 | /*if (source is reflect.Class && source.enclosingDeclaration.moduleClass == source) "Module" 49 | else getPythonNameAnnotation(source) ?? normalizeName(source.name)*/ 50 | 51 | // Edge case: if we are generating a module class, always call it by it's module name. 52 | if (source is reflect.Class && source.enclosingDeclaration.moduleClass == source) 53 | let( moduleName = source.enclosingDeclaration.name ) 54 | moduleName.split(".").last 55 | // source.name //"Module" 56 | // moduleName.replaceAll(".", "_") 57 | else getPythonNameAnnotation(source) ?? normalizeName(source.name) 58 | 59 | function normalizeModuleName(name: String): String = 60 | let (normalized = normalizeName(name.replaceAll(".", "_")).toLowerCase()) 61 | normalized 62 | 63 | keywords: List = List( 64 | "False", 65 | "None", 66 | "True", 67 | "and", 68 | "as", 69 | "assert", 70 | "async", 71 | "await", 72 | "break", 73 | "class", 74 | "continue", 75 | "def", 76 | "del", 77 | "elif", 78 | "else", 79 | "except", 80 | "finally", 81 | "for", 82 | "from", 83 | "global", 84 | "if", 85 | "import", 86 | "in", 87 | "is", 88 | "lambda", 89 | "nonlocal", 90 | "not", 91 | "or", 92 | "pass", 93 | "raise", 94 | "return", 95 | "try", 96 | "while", 97 | "with", 98 | "yield" 99 | ) 100 | 101 | function renderDocComment(docComment: String, indent: String) = 102 | docComment 103 | .split(Regex(#"\r?\n"#)) 104 | .map((it) -> 105 | if (it.trim().isBlank) "\(indent)#" 106 | else "\(indent)# \(it)" 107 | ) 108 | .join("\n") 109 | 110 | function renderHeaderComment(`module`: reflect.Module) = 111 | "# Code generated from Pkl module `\(`module`.name)`. DO NOT EDIT." 112 | 113 | function normalizeEnumName(name: String) = 114 | if (name == "") "empty" 115 | else 116 | let (normalized = normalizeName(name)) 117 | normalized[0].toLowerCase() + normalized.drop(1) 118 | 119 | function normalizeName(name: String) = 120 | /* 121 | if (keywords.contains(name)) "`\(name)`" 122 | else 123 | let (parts = name.split(Regex(#"(?u)[^\p{L}\d_]"#))) 124 | parts.first + parts.drop(1).map((p) -> p.capitalize()).join("") 125 | */ 126 | let (parts = name.split(Regex(#"(?u)[^\p{L}\d_]"#)).filter((it)-> it != "")) 127 | parts.join("_") 128 | 129 | function renderImports(imports: List): String = 130 | let (distinctImports = imports.distinct) 131 | new Listing { 132 | for (imp in distinctImports) { 133 | "import \(imp)" 134 | } 135 | }.join("\n") + "\n" 136 | 137 | function isModuleClass(source: reflect.Declaration): Boolean = 138 | source is reflect.Class && source.enclosingDeclaration.moduleClass == source 139 | -------------------------------------------------------------------------------- /codegen/src/python.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | @Module { name = "pkl_gen_python" } 17 | module pkl.python.python 18 | 19 | /// A name in Python; i.e., an identifier. 20 | typealias PythonName = String(matches(Regex(#"(?u)\p{L}[\p{L}\d_]+"#))) 21 | 22 | /// Metadata for the corresponding Python module for the annotated Pkl module(s). 23 | /// 24 | /// This flag 25 | /// 26 | /// Example: 27 | /// 28 | /// ``` 29 | /// @python.Module { name = "MyLibrary" } 30 | /// module myteam.myproj.MyLibrary 31 | /// 32 | /// import "package://pkg.pkl-lang.org/pkl-swift/pkl.swift@#/swift.pkl" 33 | /// ``` 34 | class Module extends Annotation { 35 | /// The full name of the Python module 36 | name: PythonName 37 | } 38 | 39 | /// The name for the annotated member when generated to Python. 40 | /// 41 | /// This may be used to annotate modules, classes, typealiases, and properties. 42 | /// 43 | /// If the annotation is applied to a module, it determines the name of the namespace (the `enum` that holds all the 44 | /// module's members). 45 | /// 46 | /// Examples: 47 | /// 48 | /// ``` 49 | /// @python.Name { value = "ThePerson" } 50 | /// class Person 51 | /// ``` 52 | class Name extends Annotation { 53 | value: PythonName 54 | } 55 | -------------------------------------------------------------------------------- /codegen/src/tests/ClassGen.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | amends "pkl:test" 17 | 18 | import ".../internal/ClassGen.pkl" 19 | import "pkl:reflect" 20 | 21 | local class Person { 22 | name: String 23 | hobbies: List 24 | hidden talent: String 25 | } 26 | 27 | facts { 28 | ["getFields ignores hidden members"] { 29 | local fields = ClassGen.getProperties(reflect.Class(Person), List()) 30 | fields.keys == Set("name", "hobbies") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /codegen/src/tests/fixtures/types.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | class Bike { 17 | isFixie: Boolean 18 | } 19 | 20 | abstract class Being { 21 | isAlive: Boolean 22 | } 23 | 24 | /// A Person! 25 | open class Person extends Being { 26 | bike: Bike 27 | 28 | /// The person's first name 29 | firstName: UInt16? 30 | 31 | /// The person's last name 32 | lastName: Mapping 33 | } 34 | 35 | typealias BugKind = "butterfly" | "beetle\"" | "beetle one" | "beetle_one" 36 | 37 | class Bug { 38 | /// The owner of this bug. 39 | owner: Person? 40 | 41 | secondOwner: Person 42 | 43 | /// The age of this bug 44 | age: Int? 45 | 46 | /// How long the bug holds its breath for 47 | holdsBreathFor: Duration 48 | 49 | size: DataSize 50 | 51 | kind: BugKind 52 | } 53 | 54 | class Cyclic { 55 | a: String 56 | 57 | b: Int 58 | 59 | myself: Cyclic 60 | } 61 | -------------------------------------------------------------------------------- /codegen/src/tests/fixtures/types2.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | import "types3.pkl" 17 | 18 | class Person { 19 | bikes: Listing 20 | otherbikes: Listing 21 | } 22 | -------------------------------------------------------------------------------- /codegen/src/tests/fixtures/types3.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | class Bike 17 | -------------------------------------------------------------------------------- /codegen/src/tests/fixtures/types4.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | class Foo { 17 | bar: Listing 18 | } 19 | -------------------------------------------------------------------------------- /codegen/src/tests/gatherer.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | amends "pkl:test" 17 | 18 | import "pkl:reflect" 19 | import "fixtures/types.pkl" 20 | import "fixtures/types2.pkl" 21 | import "fixtures/types4.pkl" 22 | import "../internal/gatherer.pkl" 23 | 24 | // it's important that these classes are defined in another module because they gather the type 25 | // declarations of their enclosing module. 26 | facts { 27 | ["gather type declarations"] { 28 | gatherer.gatherTypeDeclarations(reflect.Class(types.Bug), List()).map((c) -> c.name) 29 | == List("Bug", "Person", "Bike", "ModuleClass", "Being", "Cyclic", "BugKind") 30 | } 31 | ["gather type declarations - listing arguments"] { 32 | gatherer.gatherTypeDeclarations(reflect.Class(types2.Person), List()).map((c) -> c.name) 33 | == List("Person", "Bike", "ModuleClass", "ModuleClass") 34 | } 35 | ["gather type declarations - type params with unions"] { 36 | gatherer.gatherTypeDeclarations(reflect.Class(types4.Foo), List()).map((c) -> c.name) 37 | == List("Foo", "ModuleClass") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /codegen/src/tests/typegen.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | amends "pkl:test" 17 | 18 | import "pkl:reflect" 19 | 20 | import "../internal/typegen.pkl" 21 | 22 | local class Maps { 23 | res1: Map 24 | res2: Map> 25 | res3: Mapping 26 | res4: Mapping> 27 | res5: Mapping 28 | } 29 | 30 | local reflectedMaps = reflect.Class(Maps) 31 | 32 | local class Slices { 33 | res1: List 34 | res2: List> 35 | res3: Listing 36 | res4: Listing> 37 | res5: List 38 | res6: Listing 39 | } 40 | 41 | local reflectedSlices = reflect.Class(Slices) 42 | 43 | local class Nullables { 44 | res1: String? 45 | res2: Boolean? 46 | res3: Listing 47 | res4: Listing? 48 | res5: Listing? 49 | res6: Mapping 50 | res7: Mapping? 51 | res8: Mapping? 52 | } 53 | 54 | local reflectedNullables = reflect.Class(Nullables) 55 | 56 | local class Pairs { 57 | res1: Pair 58 | res2: Pair 59 | } 60 | 61 | local class Nothing { 62 | res1: nothing 63 | } 64 | 65 | local nothingType: reflect.Type = reflect.Class(Nothing).properties["res1"].type 66 | 67 | local reflectedPairs = reflect.Class(Pairs) 68 | 69 | local mod = reflect.Module(module).moduleClass 70 | 71 | local function generateType(typ: reflect.Type) = typegen.generateType(typ, mod, List()).render("") 72 | 73 | facts { 74 | ["basic types"] { 75 | generateType(reflect.stringType) == "str" 76 | generateType(reflect.booleanType) == "bool" 77 | generateType(reflect.int8Type) == "int" 78 | generateType(reflect.int16Type) == "int" 79 | generateType(reflect.int32Type) == "int" 80 | generateType(reflect.intType) == "int" 81 | generateType(reflect.floatType) == "float" 82 | generateType(reflect.uint8Type) == "int" 83 | generateType(reflect.uint16Type) == "int" 84 | generateType(reflect.uint32Type) == "int" 85 | generateType(reflect.uintType) == "int" 86 | generateType(reflect.anyType) == "Any" 87 | generateType(reflect.DeclaredType(reflect.Class(Null))) == "None" 88 | generateType(reflect.DeclaredType(reflect.TypeAlias(Char))) == "str" 89 | generateType(reflect.dynamicType) == "Object" 90 | generateType(reflect.durationType) == "Duration" 91 | generateType(reflect.dataSizeType) == "DataSize" 92 | generateType(nothingType) == "None" 93 | } 94 | ["dictionaries"] { 95 | generateType(reflectedMaps.properties["res1"].type) == "Dict[str, str]" 96 | generateType(reflectedMaps.properties["res2"].type) == "Dict[str, Dict[str, str]]" 97 | generateType(reflectedMaps.properties["res3"].type) == "Dict[str, str]" 98 | generateType(reflectedMaps.properties["res4"].type) == "Dict[str, List[bool]]" 99 | generateType(reflectedMaps.properties["res5"].type) == "Dict[Any, Any]" 100 | } 101 | ["arrays"] { 102 | generateType(reflectedSlices.properties["res1"].type) == "List[str]" 103 | generateType(reflectedSlices.properties["res2"].type) == "List[Dict[str, str]]" 104 | generateType(reflectedSlices.properties["res3"].type) == "List[str]" 105 | generateType(reflectedSlices.properties["res4"].type) == "List[Dict[str, str]]" 106 | } 107 | ["nullables"] { 108 | generateType(reflectedNullables.properties["res1"].type) == "Optional[str]" 109 | generateType(reflectedNullables.properties["res2"].type) == "Optional[bool]" 110 | generateType(reflectedNullables.properties["res3"].type) == "List[Optional[str]]" 111 | generateType(reflectedNullables.properties["res4"].type) == "Optional[List[str]]" 112 | generateType(reflectedNullables.properties["res5"].type) == "Optional[List[Optional[str]]]" 113 | generateType(reflectedNullables.properties["res6"].type) == "Dict[Optional[str], str]" 114 | generateType(reflectedNullables.properties["res7"].type) == "Optional[Dict[str, str]]" 115 | generateType(reflectedNullables.properties["res8"].type) == "Optional[Dict[Optional[str], Optional[str]]]" 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /codegen/src/tests/utils.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | amends "pkl:test" 17 | 18 | import "../internal/utils.pkl" 19 | 20 | facts { 21 | ["normalizeName"] { 22 | utils.normalizeName("foo") == "foo" 23 | utils.normalizeName("foo foo") == "foo_foo" 24 | utils.normalizeName("1 foo") == "1_foo" 25 | utils.normalizeName("bar ` $$ 你好 baz") == "bar_你好_baz" 26 | utils.normalizeName("Python111") == "Python111" 27 | utils.normalizeName("snake_case") == "snake_case" 28 | } 29 | ["toPythonString"] { 30 | utils.toPythonString("foo") == #""foo""# 31 | utils.toPythonString("你好") == #""你好""# 32 | utils.toPythonString(#"pkl:"name""#) == ##"#"pkl:"name""#"## 33 | utils.toPythonString(""" 34 | my multiline 35 | 36 | string 37 | """) == #""" 38 | """ 39 | my multiline 40 | 41 | string 42 | """ 43 | """# 44 | utils.toPythonString(""" 45 | multiline string 46 | 47 | with `backticks` 48 | """) == #""" 49 | """ 50 | multiline string 51 | 52 | with `backticks` 53 | """ 54 | """# 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /generator-settings.pkl: -------------------------------------------------------------------------------- 1 | amends "codegen/src/GeneratorSettings.pkl" 2 | 3 | generateScript = "codegen/src/Generator.pkl" 4 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel", "msgpack", "requests"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "pkl-python" 7 | dynamic = ["version"] 8 | description = "Python library for Apple's PKL." 9 | authors = [ 10 | { name = "Jungwoo Yang", email = "jwyang0213@gmail.com" }, 11 | ] 12 | license = { file = "LICENSE" } 13 | readme = "README.md" 14 | requires-python = ">=3.8" 15 | classifiers = [ 16 | "Programming Language :: Python :: 3", 17 | "License :: OSI Approved :: MIT License", 18 | "Operating System :: OS Independent", 19 | ] 20 | dependencies = [ 21 | "msgpack >= 1.0.8", 22 | ] 23 | 24 | [tool.setuptools] 25 | package-dir = {"" = "src"} 26 | 27 | [tool.setuptools.dynamic] 28 | version = {file = "src/pkl/VERSION"} 29 | 30 | [project.optional-dependencies] 31 | dev = [ 32 | "pre-commit", 33 | "black", 34 | "isort", 35 | "mypy", 36 | "pylint", 37 | "pytest", 38 | "pytest-cov", 39 | "tox", 40 | ] 41 | 42 | [project.urls] 43 | "Homepage" = "https://github.com/jw-y/pkl-python" 44 | "Bug Reports" = "https://github.com/jw-y/pkl-python/issues" 45 | "Source" = "https://github.com/jw-y/pkl-python" 46 | 47 | [project.scripts] 48 | pkl-gen-python = "pkl_gen_python:main" 49 | 50 | [tool.twine] 51 | repository = "pypi" 52 | 53 | [tool.black] 54 | line-length = 88 55 | target-version = ['py310'] 56 | force-exclude = 'codegen/snippet-tests/output/' 57 | 58 | [tool.isort] 59 | profile = "black" 60 | skip = ["codegen/snippet-tests/output/*"] 61 | 62 | [tool.autoflake] 63 | exclude = ["codegen/snippet-tests/output/*"] 64 | 65 | [tool.pytest.ini_options] 66 | addopts = "-ra -q" 67 | 68 | 69 | [tool.cibuildwheel] 70 | build = [ 71 | "*-macosx_x86_64", 72 | "*-macosx_arm64", 73 | "*-manylinux_aarch64", 74 | "*-manylinux_x86_64", 75 | #"*-musllinux_x86_64", 76 | "*-win_amd64", 77 | ] 78 | -------------------------------------------------------------------------------- /scripts/download_binary.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from pathlib import Path 3 | 4 | import requests 5 | 6 | VERSION = "0.25.2" 7 | 8 | BASE_PATH = "https://github.com/apple/pkl/releases/download/" 9 | filenames = [ 10 | "pkl-macos-aarch64", 11 | "pkl-macos-amd64", 12 | "pkl-linux-aarch64", 13 | "pkl-linux-amd64", 14 | "pkl-alpine-linux-amd64", 15 | ] 16 | JAVA_FILE = f"https://repo1.maven.org/maven2/org/pkl-lang/pkl-cli-java/{VERSION}/pkl-cli-java-{VERSION}.jar" 17 | 18 | 19 | def main(save_path): 20 | urls = [BASE_PATH + VERSION + "/" + file for file in filenames] 21 | urls.append(JAVA_FILE) 22 | 23 | for url in urls: 24 | file = url.split("/")[-1] 25 | fp = save_path / file 26 | 27 | response = requests.get(url) 28 | with open(fp, "wb") as f: 29 | f.write(response.content) 30 | 31 | print("written to", fp) 32 | 33 | 34 | if __name__ == "__main__": 35 | parser = argparse.ArgumentParser() 36 | parser.add_argument( 37 | "output_path", help="Directory where binaries will be downloaded" 38 | ) 39 | 40 | args = parser.parse_args() 41 | 42 | main(Path(args.output_path)) 43 | -------------------------------------------------------------------------------- /scripts/eval.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from pathlib import Path 3 | from pprint import pprint 4 | 5 | import pkll 6 | 7 | 8 | def main(target, force=False, debug=False, is_print=False): 9 | target = Path(target) 10 | 11 | if target.is_file(): 12 | files = [target] 13 | elif target.is_dir(): 14 | files = list(target.glob("*.pkl")) 15 | else: 16 | raise ValueError(target) 17 | 18 | for f in files: 19 | if f.is_file(): 20 | config = pkll.load(f.absolute().as_uri(), force_render=force, debug=debug) 21 | if is_print: 22 | pprint(config) 23 | 24 | 25 | if __name__ == "__main__": 26 | parser = argparse.ArgumentParser() 27 | parser.add_argument("target") 28 | parser.add_argument("--force", "-f", action="store_true") 29 | parser.add_argument("--debug", "-d", action="store_true") 30 | parser.add_argument("--print", "-p", action="store_true") 31 | args = parser.parse_args() 32 | main(args.target, force=args.force, debug=args.debug, is_print=args.print) 33 | -------------------------------------------------------------------------------- /scripts/foo.pkl: -------------------------------------------------------------------------------- 1 | foo: String = "hello" 2 | 3 | bar: Int = 5 4 | -------------------------------------------------------------------------------- /scripts/run_mod.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if a directory argument was provided 4 | if [ "$#" -ne 1 ]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | # Assign the first argument to a variable 10 | DIRECTORY=$1 11 | 12 | # Check if the specified directory exists 13 | if [ ! -d "$DIRECTORY" ]; then 14 | echo "Directory does not exist: $DIRECTORY" 15 | exit 1 16 | fi 17 | 18 | # Convert the directory path to a Python module path 19 | MOD_PATH=$(echo "$DIRECTORY" | sed 's#/#.#g') 20 | 21 | # Iterate over each Python file in the specified directory 22 | for file in "$DIRECTORY"/*.py; do 23 | # Extract the base filename without the extension 24 | MODULE=$(basename "$file" .py) 25 | 26 | # Skip __init__.py files 27 | if [ "$MODULE" == "__init__" ]; then 28 | continue 29 | fi 30 | 31 | echo "Running $MODULE as a module..." 32 | python -m "$MOD_PATH.$MODULE" 33 | # Check if the script exited with a non-zero status 34 | if [ $? -ne 0 ]; then 35 | echo "$MODULE encountered an error." 36 | fi 37 | done 38 | -------------------------------------------------------------------------------- /scripts/run_py.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if a directory argument was provided 4 | if [ "$#" -ne 1 ]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | # Assign the first argument to a variable 10 | DIRECTORY=$1 11 | 12 | # Check if the specified directory exists 13 | if [ ! -d "$DIRECTORY" ]; then 14 | echo "Directory does not exist: $DIRECTORY" 15 | exit 1 16 | fi 17 | 18 | # Iterate over each Python file in the specified directory 19 | for file in "$DIRECTORY"/*.py; do 20 | echo "Running $file..." 21 | python -m "$file" 22 | # Check if the script exited with a non-zero status 23 | if [ $? -ne 0 ]; then 24 | echo "$file encountered an error." 25 | fi 26 | done 27 | -------------------------------------------------------------------------------- /src/pkl/VERSION: -------------------------------------------------------------------------------- 1 | 0.1.16 2 | -------------------------------------------------------------------------------- /src/pkl/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | from typing import Optional, Union 4 | from urllib.parse import ParseResult, urlparse 5 | 6 | from pkl.evaluator_manager import Evaluator, EvaluatorManager 7 | from pkl.evaluator_options import EvaluatorOptions, PreconfiguredOptions 8 | from pkl.parser import DataSize, Duration, IntSeq, Pair, Parser, Regex 9 | from pkl.reader import ModuleReader, PathElement, ResourceReader 10 | from pkl.utils import ModuleSource, PklBugError, PklError 11 | 12 | # get version 13 | with open(os.path.join(os.path.dirname(__file__), "VERSION"), "r") as _f: 14 | __version__ = _f.read().strip() 15 | 16 | 17 | def _search_project_dir(module_path: str) -> str: 18 | cur_path = Path(module_path).parent.absolute() 19 | root_path = cur_path.root 20 | 21 | while not (cur_path / "PklProject").exists(): 22 | if cur_path == cur_path.parent or cur_path == root_path: 23 | break 24 | cur_path = cur_path.parent 25 | 26 | return str(cur_path.absolute()) 27 | 28 | 29 | def _parse_module_uri(module_uri, module_text): 30 | parsed = urlparse(str(module_uri)) 31 | 32 | def is_uri(_uri: ParseResult): 33 | return bool(_uri.scheme) and (bool(_uri.netloc) or bool(_uri.path)) 34 | 35 | if module_text: 36 | source = ModuleSource.from_text(module_text) 37 | elif is_uri(parsed): 38 | source = ModuleSource.from_uri(module_uri) 39 | else: 40 | source = ModuleSource.from_path(module_uri) 41 | return source 42 | 43 | 44 | def load( 45 | module_uri: Union[str, Path], 46 | *, 47 | module_text: Optional[str] = None, 48 | expr: Optional[str] = None, 49 | project_dir: Optional[str] = None, 50 | evaluator_options: EvaluatorOptions = PreconfiguredOptions(), 51 | parser=None, 52 | debug=False, 53 | **kwargs, 54 | ): 55 | """ 56 | Loads and evaluates a Pkl module or expression with specified parameters and customization options. 57 | 58 | Args: 59 | module_uri (str): The absolute URI of the module to be loaded. 60 | module_text (Optional[str], None): Optionally, the content of the module to be loaded. 61 | If None, the module is loaded from the specified URI. 62 | expr (Optional[str], None): Optionally, a Pkl expression to be evaluated 63 | within the loaded module. If None, the entire module is evaluated. 64 | project_dir (Optional[str], None): The project directory to use for this command. 65 | By default, searches up from the working directory for a PklProject file. 66 | evaluator_options (EvaluatorOptions, PreconfiguredOptions()): 67 | extra options for evaluator 68 | parser: A specific parser to be used for parsing the module. 69 | If None, a default parser is used. 70 | debug (bool, False): Enable debugging mode for additional output and diagnostics. 71 | **kwargs: Additional keyword arguments for extensibility and future use. 72 | 73 | Returns: 74 | The result of the module or expression evaluation, depending on the inputs and configuration. 75 | 76 | This function provides a flexible interface for loading and evaluating Pkl modules 77 | with a variety of customization options, including custom module and resource readers, 78 | environmental configurations, and support for complex project dependencies. 79 | """ 80 | 81 | source = _parse_module_uri(module_uri, module_text) 82 | 83 | if project_dir is None: 84 | project_dir = _search_project_dir(str(module_uri)) 85 | 86 | with EvaluatorManager(debug=debug) as manager: 87 | if (Path(project_dir) / "PklProject").exists(): 88 | evaluator = manager.new_project_evaluator( 89 | project_dir, evaluator_options, parser=parser 90 | ) 91 | else: 92 | evaluator = manager.new_evaluator(evaluator_options, parser=parser) 93 | config = evaluator.evaluate_expression(source, expr) 94 | return config 95 | 96 | 97 | def loads( 98 | module_text: Optional[str], 99 | *, 100 | expr: Optional[str] = None, 101 | project_dir: Optional[str] = None, 102 | evaluator_options: EvaluatorOptions = PreconfiguredOptions(), 103 | parser=None, 104 | debug=False, 105 | **kwargs, 106 | ): 107 | """ 108 | This function is a specialized version of `load` that defaults `module_uri` to None. 109 | 110 | {load.__doc__} 111 | """ 112 | return load( 113 | module_uri=None, 114 | module_text=module_text, 115 | expr=expr, 116 | project_dir=project_dir, 117 | evaluator_options=evaluator_options, 118 | parser=parser, 119 | debug=debug, 120 | **kwargs, 121 | ) 122 | 123 | 124 | __all__ = [ 125 | "load", 126 | "loads", 127 | "Evaluator", 128 | "EvaluatorManager", 129 | "EvaluatorOptions", 130 | "PreconfiguredOptions", 131 | "ModuleReader", 132 | "ResourceReader", 133 | "PathElement", 134 | "Parser", 135 | "ModuleSource", 136 | "PklError", 137 | "PklBugError", 138 | "Duration", 139 | "DataSize", 140 | "Pair", 141 | "IntSeq", 142 | "Regex", 143 | ] 144 | -------------------------------------------------------------------------------- /src/pkl/evaluator_options.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import os 4 | from dataclasses import dataclass, field 5 | from pathlib import Path 6 | from typing import Dict, List, Optional, Union 7 | 8 | from pkl.reader import ModuleReader, ResourceReader 9 | 10 | 11 | @dataclass 12 | class ClientResourceReader: 13 | # The URI scheme this reader is responsible for reading. 14 | scheme: str 15 | 16 | # Tells whether the path part of ths URI has a 17 | # [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3). 18 | # 19 | # An example of a hierarchical URI is `file:///path/to/my/file`, where 20 | # `/path/to/my/file` designates a nested path through the `/` character. 21 | # 22 | # An example of a non-hierarchical URI is `pkl.base`, where the `base` does not denote 23 | # any form of hierarchy. 24 | hasHierarchicalUris: bool 25 | 26 | # Tells whether this reader supports globbing. 27 | isGlobbable: bool 28 | 29 | 30 | @dataclass 31 | class ClientModuleReader: 32 | # The URI scheme this reader is responsible for reading. 33 | scheme: str 34 | 35 | # Tells whether the path part of ths URI has a 36 | # [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3). 37 | # 38 | # An example of a hierarchical URI is `file:///path/to/my/file`, where 39 | # `/path/to/my/file` designates a nested path through the `/` character. 40 | # 41 | # An example of a non-hierarchical URI is `pkl.base`, where the `base` does not denote 42 | # any form of hierarchy. 43 | hasHierarchicalUris: bool 44 | 45 | # Tells whether this reader supports globbing. 46 | isGlobbable: bool 47 | 48 | # Tells whether the module is local to the system. 49 | # 50 | # A local resource that [hasHierarchicalUris] supports triple-dot imports. 51 | isLocal: bool 52 | 53 | 54 | @dataclass 55 | class Checksums: 56 | # The sha-256 checksum of this dependency's metadata. 57 | sha256: str 58 | 59 | 60 | @dataclass 61 | class RemoteDependency: 62 | type: str = "remote" 63 | 64 | # The canonical URI of this dependency 65 | packageUri: Optional[str] = None 66 | 67 | # The checksums of this remote dependency 68 | checksums: Optional[Checksums] = None 69 | 70 | 71 | @dataclass 72 | class Project: 73 | # The URI pointing to the location of the project file. 74 | projectFileUri: str 75 | 76 | type: str = "local" 77 | 78 | # The canonical URI of this project's package 79 | packageUri: Optional[str] = None 80 | 81 | # The dependencies of this project. 82 | dependencies: Dict[str, Union[Project, RemoteDependency]] = field( 83 | default_factory=dict 84 | ) 85 | 86 | 87 | @dataclass 88 | class EvaluatorOptions: 89 | # Regex patterns to determine which modules are allowed for import. 90 | # 91 | # API version of the CLI's `--allowed-modules` flag 92 | allowedModules: Optional[List[str]] = None 93 | 94 | # Regex patterns to dettermine which resources are allowed to be read. 95 | # 96 | # API version of the CLI's `--allowed-resources` flag 97 | allowedResources: Optional[List[str]] = None 98 | 99 | # Register client-side module readers. 100 | moduleReaders: Optional[List[ModuleReader]] = None 101 | 102 | # Register client-side resource readers. 103 | resourceReaders: Optional[List[ResourceReader]] = None 104 | 105 | # Directories, ZIP archives, or JAR archives 106 | # to search when resolving `modulepath:` URIs. 107 | # 108 | # API version of the CLI's `--module-path` flag. 109 | modulePaths: Optional[List[str]] = None 110 | 111 | # Environment variable to set. 112 | # 113 | # API version of the CLI's `--env-var` flag. 114 | env: Optional[Dict[str, str]] = None 115 | 116 | # External properties to set. 117 | # 118 | # API version of the CLI's `--properties` flag. 119 | properties: Optional[Dict[str, str]] = None 120 | 121 | # Duration, in seconds, after which evaluation of a source module will be timed out. 122 | # 123 | # API version of the CLI's `--timeout` flag. 124 | timeoutSeconds: Optional[int] = None 125 | 126 | # Restricts access to file-based modules and resources to those located under the root directory. 127 | rootDir: Optional[str] = None 128 | 129 | # The cache directory for storing packages. 130 | cacheDir: Optional[str] = None 131 | 132 | # The format to generate. 133 | # 134 | # This sets the `pkl.outputFormat` external property. 135 | outputFormat: Optional[str] = None 136 | 137 | # The project dependency settings. 138 | # project: Optional[Project] = None 139 | 140 | 141 | @dataclass 142 | class PreconfiguredOptions(EvaluatorOptions): 143 | allowedModules: Optional[List[str]] = field( 144 | default_factory=lambda: [ 145 | "pkl:", 146 | "repl:", 147 | "file:", 148 | "http:", 149 | "https:", 150 | "modulepath:", 151 | "package:", 152 | "projectpackage:", 153 | ] 154 | ) 155 | allowedResources: Optional[List[str]] = field( 156 | default_factory=lambda: [ 157 | "http:", 158 | "https:", 159 | "file:", 160 | "env:", 161 | "prop:", 162 | "modulepath:", 163 | "package:", 164 | "projectpackage:", 165 | ] 166 | ) 167 | env: Optional[Dict[str, str]] = field(default_factory=lambda: dict(os.environ)) 168 | 169 | cacheDir: Optional[str] = str(Path("~/.pkl/cache").expanduser()) 170 | -------------------------------------------------------------------------------- /src/pkl/reader.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from dataclasses import dataclass 3 | from typing import List 4 | 5 | 6 | @dataclass 7 | class PathElement: 8 | # name is the name of the path element. 9 | name: str 10 | 11 | # isDirectory tells if the path element is a directory. 12 | isDirectory: bool 13 | 14 | 15 | @dataclass 16 | class Reader(ABC): 17 | # The URI scheme this reader is responsible for reading. 18 | scheme: str 19 | 20 | # Tells whether the path part of ths URI has a 21 | # [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3). 22 | # 23 | # An example of a hierarchical URI is `file:///path/to/my/file`, where 24 | # `/path/to/my/file` designates a nested path through the `/` character. 25 | # 26 | # An example of a non-hierarchical URI is `pkl.base`, where the `base` does not denote 27 | # any form of hierarchy. 28 | hasHierarchicalUris: bool 29 | 30 | # Tells whether this reader supports globbing. 31 | isGlobbable: bool 32 | 33 | # listElements returns the list of elements at a specified path. 34 | # If HasHierarchicalUris is false, path will be empty and ListElements should return all 35 | # available values. 36 | # 37 | # This method is only called if it is hierarchical and local, or if it is globbable. 38 | def list_elements(self, url: str) -> List[PathElement]: 39 | raise NotImplementedError( 40 | f"Must implement 'list_elements' for {self.__class__}" 41 | ) 42 | 43 | @abstractmethod 44 | def read(self, url): 45 | pass 46 | 47 | 48 | @dataclass 49 | class ModuleReader(Reader): 50 | # Tells whether the module is local to the system. 51 | # 52 | # A local resource that [hasHierarchicalUris] supports triple-dot imports. 53 | isLocal: bool 54 | 55 | @abstractmethod 56 | def read(self, url) -> str: 57 | pass 58 | 59 | 60 | @dataclass 61 | class ResourceReader(Reader): 62 | @abstractmethod 63 | def read(self, url) -> bytes: 64 | pass 65 | -------------------------------------------------------------------------------- /src/pkl/server.py: -------------------------------------------------------------------------------- 1 | import atexit 2 | import os 3 | import signal 4 | import subprocess 5 | 6 | import msgpack 7 | 8 | 9 | def preexec_function(): 10 | # Cause the child process to be terminated when the parent exits 11 | signal.signal(signal.SIGHUP, signal.SIG_IGN) 12 | 13 | 14 | _PROCESSES = [] 15 | 16 | 17 | def terminate_processes(): 18 | for process in _PROCESSES: 19 | process.terminate() 20 | process.wait() 21 | 22 | 23 | atexit.register(terminate_processes) 24 | 25 | 26 | class PKLServer: 27 | def __init__(self, cmd=None, debug=False): 28 | from pkl.binary_manager import BinaryManager 29 | 30 | manager = BinaryManager() 31 | binary_path = manager.get_binary_filepath() 32 | 33 | self.cmd = cmd or [binary_path, "server"] 34 | self.next_request_id = 1 35 | self.unpacker = msgpack.Unpacker() 36 | 37 | env = {"PKL_DEBUG": "1"} if debug else {} 38 | 39 | self.process = subprocess.Popen( 40 | self.cmd, 41 | stdin=subprocess.PIPE, 42 | stdout=subprocess.PIPE, 43 | stderr=subprocess.PIPE, 44 | text=False, 45 | bufsize=0, 46 | preexec_fn=preexec_function, 47 | env=env, 48 | ) 49 | self.stdout = self.process.stdout 50 | self.stdin = self.process.stdin 51 | self.stderr = self.process.stderr 52 | self.closed = False 53 | 54 | os.set_blocking(self.stdout.fileno(), False) 55 | os.set_blocking(self.stderr.fileno(), False) 56 | _PROCESSES.append(self.process) 57 | 58 | def get_request_id(self): 59 | ret = self.next_request_id 60 | self.next_request_id += 1 61 | return ret 62 | 63 | def send(self, msg): 64 | if self.closed: 65 | raise ValueError("Server closed") 66 | self.stdin.write(msg) 67 | self.stdin.flush() 68 | 69 | def _read(self, stream): 70 | msg = None 71 | while msg is None: 72 | msg = stream.read() 73 | return msg 74 | 75 | def _receive(self, stream): 76 | while True: 77 | for unpacked in self.unpacker: 78 | return unpacked 79 | msg = self._read(stream) 80 | self.unpacker.feed(msg) 81 | 82 | def receive(self): 83 | if self.closed: 84 | raise ValueError("Server closed") 85 | return self._receive(self.stdout) 86 | 87 | def receive_err(self): 88 | if self.closed: 89 | raise ValueError("Server closed") 90 | msg = self.stderr.read() 91 | if msg is not None: 92 | print(msg.decode(), end="") 93 | 94 | def terminate(self): 95 | self.process.terminate() 96 | self.process.stdout.close() 97 | self.process.stderr.close() 98 | self.process.stdin.close() 99 | self.process.wait() 100 | self.closed = True 101 | -------------------------------------------------------------------------------- /src/pkl/utils.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from pathlib import Path 3 | from typing import Optional, Union 4 | from urllib.parse import urlparse 5 | 6 | 7 | class PklBugError(Exception): 8 | pass 9 | 10 | 11 | class PklError(Exception): 12 | pass 13 | 14 | 15 | @dataclass 16 | class ModuleSource: 17 | uri: str 18 | text: Optional[str] = None 19 | 20 | @classmethod 21 | def from_path(cls, path: Union[str, Path]): 22 | uri = Path(path).absolute().as_uri() 23 | return cls(uri=uri) 24 | 25 | @classmethod 26 | def from_text(cls, text: str): 27 | return cls(uri="repl:text", text=text) 28 | 29 | @classmethod 30 | def from_uri(cls, uri): 31 | res = urlparse(uri) 32 | parsed = res.geturl() 33 | return cls(uri=parsed) 34 | -------------------------------------------------------------------------------- /tests/Fixtures/AnyType.pkl: -------------------------------------------------------------------------------- 1 | 2 | class Bird { 3 | species: String 4 | } 5 | 6 | bird: Any = new Bird { 7 | species = "Owl" 8 | } 9 | 10 | primitive: Any = "foo" 11 | 12 | primitive2: Any = 12 13 | 14 | array: Any = new Listing { 15 | 1 16 | 2 17 | } 18 | 19 | set: Any = Set(5, 6) 20 | 21 | mapping: Any = new Mapping { 22 | ["1"] = 12 23 | [12] = "1" 24 | } 25 | 26 | nullable: Any = null 27 | 28 | duration: Any = 5.min 29 | 30 | dataSize: Any = 10.mb 31 | -------------------------------------------------------------------------------- /tests/Fixtures/ApiTypes.pkl: -------------------------------------------------------------------------------- 1 | res1: Pair = Pair(42, "Hello") 2 | res2: Duration = 10.h 3 | res3: DataSize = 1.2345.gib 4 | -------------------------------------------------------------------------------- /tests/Fixtures/Classes.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | module Classes 17 | 18 | animals: Listing = new { 19 | new { name = "Uni" } 20 | new { name = "Wally" } 21 | new { name = "Mouse" } 22 | } 23 | 24 | class Animal { 25 | name: String 26 | } 27 | -------------------------------------------------------------------------------- /tests/Fixtures/Collections.pkl: -------------------------------------------------------------------------------- 1 | 2 | res1: List = List(1, 2, 3) 3 | 4 | res2: Listing = new { 2; 3; 4; } 5 | 6 | res3: List> = List(List(1), List(2), List(3)) 7 | 8 | res4: Listing> = new { new { 1 }; new { 2 }; new { 3 } } 9 | 10 | res5: Mapping = new { [1] = true; [2] = false } 11 | 12 | res6: Mapping> = new { 13 | [1] { 14 | [1] = true 15 | } 16 | [2] { 17 | [2] = true 18 | } 19 | [3] { 20 | [3] = true 21 | } 22 | } 23 | 24 | res7: Map = Map(1, true, 2, false) 25 | 26 | res8: Map> = Map(1, Map(1, true), 2, Map(2, false)) 27 | 28 | res9: Set = Set("one", "two", "three") 29 | 30 | res10: Set = Set(1, 2, 3) 31 | -------------------------------------------------------------------------------- /tests/Fixtures/ExtendedModule.pkl: -------------------------------------------------------------------------------- 1 | extends "OpenModule.pkl" 2 | 3 | foo = "foo" 4 | 5 | bar = 10 6 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/AnyType_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `AnyType`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Any 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class Bird: 12 | species: str 13 | 14 | _registered_identifier = "AnyType#Bird" 15 | 16 | 17 | @dataclass 18 | class AnyType: 19 | bird: Any 20 | 21 | primitive: Any 22 | 23 | primitive2: Any 24 | 25 | array: Any 26 | 27 | set: Any 28 | 29 | mapping: Any 30 | 31 | nullable: Any 32 | 33 | duration: Any 34 | 35 | dataSize: Any 36 | 37 | _registered_identifier = "AnyType" 38 | 39 | @classmethod 40 | def load_pkl(cls, source): 41 | # Load the Pkl module at the given source and evaluate it into `AnyType.Module`. 42 | # - Parameter source: The source of the Pkl module. 43 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 44 | return config 45 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/ApiTypes_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `ApiTypes`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | 6 | import pkl 7 | 8 | 9 | @dataclass 10 | class ApiTypes: 11 | res1: pkl.Pair[int, str] 12 | 13 | res2: pkl.Duration 14 | 15 | res3: pkl.DataSize 16 | 17 | _registered_identifier = "ApiTypes" 18 | 19 | @classmethod 20 | def load_pkl(cls, source): 21 | # Load the Pkl module at the given source and evaluate it into `ApiTypes.Module`. 22 | # - Parameter source: The source of the Pkl module. 23 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 24 | return config 25 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/Classes_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `Classes`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import List 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class Animal: 12 | name: str 13 | 14 | _registered_identifier = "Classes#Animal" 15 | 16 | 17 | @dataclass 18 | class Classes: 19 | animals: List[Animal] 20 | 21 | _registered_identifier = "Classes" 22 | 23 | @classmethod 24 | def load_pkl(cls, source): 25 | # Load the Pkl module at the given source and evaluate it into `Classes.Module`. 26 | # - Parameter source: The source of the Pkl module. 27 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 28 | return config 29 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/Collections_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `Collections`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Dict, List, Set 6 | 7 | import pkl 8 | 9 | 10 | @dataclass 11 | class Collections: 12 | res1: List[int] 13 | 14 | res2: List[int] 15 | 16 | res3: List[List[int]] 17 | 18 | res4: List[List[int]] 19 | 20 | res5: Dict[int, bool] 21 | 22 | res6: Dict[int, Dict[int, bool]] 23 | 24 | res7: Dict[int, bool] 25 | 26 | res8: Dict[int, Dict[int, bool]] 27 | 28 | res9: Set[str] 29 | 30 | res10: Set[int] 31 | 32 | _registered_identifier = "Collections" 33 | 34 | @classmethod 35 | def load_pkl(cls, source): 36 | # Load the Pkl module at the given source and evaluate it into `Collections.Module`. 37 | # - Parameter source: The source of the Pkl module. 38 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 39 | return config 40 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/ExtendedModule_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `ExtendedModule`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | 6 | import pkl 7 | 8 | from . import OpenModule_pkl 9 | 10 | 11 | @dataclass 12 | class ExtendedModule(OpenModule_pkl.OpenModule): 13 | foo: str 14 | 15 | bar: int 16 | 17 | _registered_identifier = "ExtendedModule" 18 | 19 | @classmethod 20 | def load_pkl(cls, source): 21 | # Load the Pkl module at the given source and evaluate it into `ExtendedModule.Module`. 22 | # - Parameter source: The source of the Pkl module. 23 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 24 | return config 25 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/OpenModule_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `OpenModule`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | 6 | import pkl 7 | 8 | 9 | @dataclass 10 | class OpenModule: 11 | foo: str 12 | 13 | bar: int 14 | 15 | _registered_identifier = "OpenModule" 16 | 17 | @classmethod 18 | def load_pkl(cls, source): 19 | # Load the Pkl module at the given source and evaluate it into `OpenModule.Module`. 20 | # - Parameter source: The source of the Pkl module. 21 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 22 | return config 23 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/UnionTypes_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `UnionTypes`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Literal, Union 6 | 7 | import pkl 8 | 9 | Fruit = Union["Banana", "Grape", "Apple"] 10 | 11 | 12 | City = Literal["San Francisco", "Tokyo", "Zurich", "London"] 13 | 14 | 15 | ZebraOrDonkey = Union["Zebra", "Donkey"] 16 | 17 | 18 | AnimalOrString = Union["Animal", str] 19 | 20 | 21 | @dataclass 22 | class Animal: 23 | name: str 24 | 25 | _registered_identifier = "UnionTypes#Animal" 26 | 27 | 28 | @dataclass 29 | class Donkey(Animal): 30 | name: str 31 | 32 | _registered_identifier = "UnionTypes#Donkey" 33 | 34 | 35 | @dataclass 36 | class Zebra(Animal): 37 | name: str 38 | 39 | _registered_identifier = "UnionTypes#Zebra" 40 | 41 | 42 | @dataclass 43 | class Apple: 44 | isRed: bool 45 | 46 | _registered_identifier = "UnionTypes#Apple" 47 | 48 | 49 | @dataclass 50 | class Grape: 51 | isUsedForWine: bool 52 | 53 | _registered_identifier = "UnionTypes#Grape" 54 | 55 | 56 | @dataclass 57 | class Banana: 58 | isRipe: bool 59 | 60 | _registered_identifier = "UnionTypes#Banana" 61 | 62 | 63 | @dataclass 64 | class UnionTypes: 65 | fruit1: Fruit 66 | 67 | fruit2: Fruit 68 | 69 | fruit3: Fruit 70 | 71 | city1: City 72 | 73 | city2: City 74 | 75 | city3: City 76 | 77 | city4: City 78 | 79 | animal1: ZebraOrDonkey 80 | 81 | animal2: ZebraOrDonkey 82 | 83 | animalOrString1: AnimalOrString 84 | 85 | animalOrString2: AnimalOrString 86 | 87 | _registered_identifier = "UnionTypes" 88 | 89 | @classmethod 90 | def load_pkl(cls, source): 91 | # Load the Pkl module at the given source and evaluate it into `UnionTypes.Module`. 92 | # - Parameter source: The source of the Pkl module. 93 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 94 | return config 95 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/pkl_python_example_Poly_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `pkl.python.example.Poly`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | from typing import Dict, List, Optional 6 | 7 | import pkl 8 | 9 | from . import pkl_python_lib1_pkl 10 | 11 | 12 | @dataclass 13 | class Bird(pkl_python_lib1_pkl.Being): 14 | name: str 15 | 16 | flies: bool 17 | 18 | _registered_identifier = "pkl.python.example.Poly#Bird" 19 | 20 | 21 | @dataclass 22 | class Animal(pkl_python_lib1_pkl.Being): 23 | name: str 24 | 25 | _registered_identifier = "pkl.python.example.Poly#Animal" 26 | 27 | 28 | @dataclass 29 | class Dog(Animal): 30 | barks: bool 31 | 32 | hates: Optional[Animal] 33 | 34 | _registered_identifier = "pkl.python.example.Poly#Dog" 35 | 36 | 37 | @dataclass 38 | class Poly: 39 | beings: List[pkl_python_lib1_pkl.Being] 40 | 41 | rex: Dog 42 | 43 | moreBeings: Dict[str, pkl_python_lib1_pkl.Being] 44 | 45 | _registered_identifier = "pkl.python.example.Poly" 46 | 47 | @classmethod 48 | def load_pkl(cls, source): 49 | # Load the Pkl module at the given source and evaluate it into `pkl_python_example_Poly.Module`. 50 | # - Parameter source: The source of the Pkl module. 51 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 52 | return config 53 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated/pkl_python_lib1_pkl.py: -------------------------------------------------------------------------------- 1 | # Code generated from Pkl module `pkl.python.lib1`. DO NOT EDIT. 2 | from __future__ import annotations 3 | 4 | from dataclasses import dataclass 5 | 6 | import pkl 7 | 8 | 9 | @dataclass 10 | class Being: 11 | exists: bool 12 | 13 | _registered_identifier = "pkl.python.lib1#Being" 14 | 15 | 16 | @dataclass 17 | class lib1: 18 | _registered_identifier = "pkl.python.lib1" 19 | 20 | @classmethod 21 | def load_pkl(cls, source): 22 | # Load the Pkl module at the given source and evaluate it into `pkl_python_lib1.Module`. 23 | # - Parameter source: The source of the Pkl module. 24 | config = pkl.load(source, parser=pkl.Parser(namespace=globals())) 25 | return config 26 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated_Swift/AnyType.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `AnyType`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum AnyType {} 5 | 6 | extension AnyType { 7 | public struct Module: PklRegisteredType, Decodable, Hashable { 8 | public static let registeredIdentifier: String = "AnyType" 9 | 10 | public var bird: AnyHashable? 11 | 12 | public var primitive: AnyHashable? 13 | 14 | public var primitive2: AnyHashable? 15 | 16 | public var array: AnyHashable? 17 | 18 | public var set: AnyHashable? 19 | 20 | public var mapping: AnyHashable? 21 | 22 | public var nullable: AnyHashable? 23 | 24 | public var duration: AnyHashable? 25 | 26 | public var dataSize: AnyHashable? 27 | 28 | public init( 29 | bird: AnyHashable?, 30 | primitive: AnyHashable?, 31 | primitive2: AnyHashable?, 32 | array: AnyHashable?, 33 | set: AnyHashable?, 34 | mapping: AnyHashable?, 35 | nullable: AnyHashable?, 36 | duration: AnyHashable?, 37 | dataSize: AnyHashable? 38 | ) { 39 | self.bird = bird 40 | self.primitive = primitive 41 | self.primitive2 = primitive2 42 | self.array = array 43 | self.set = set 44 | self.mapping = mapping 45 | self.nullable = nullable 46 | self.duration = duration 47 | self.dataSize = dataSize 48 | } 49 | 50 | public init(from decoder: Decoder) throws { 51 | let dec = try decoder.container(keyedBy: PklCodingKey.self) 52 | let bird = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "bird")).value 53 | let primitive = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "primitive")).value 54 | let primitive2 = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "primitive2")).value 55 | let array = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "array")).value 56 | let set = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "set")).value 57 | let mapping = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "mapping")).value 58 | let nullable = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "nullable")).value 59 | let duration = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "duration")).value 60 | let dataSize = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "dataSize")).value 61 | self = Module(bird: bird, primitive: primitive, primitive2: primitive2, array: array, set: set, mapping: mapping, nullable: nullable, duration: duration, dataSize: dataSize) 62 | } 63 | } 64 | 65 | public struct Bird: PklRegisteredType, Decodable, Hashable { 66 | public static let registeredIdentifier: String = "AnyType#Bird" 67 | 68 | public var species: String 69 | 70 | public init(species: String) { 71 | self.species = species 72 | } 73 | } 74 | 75 | /// Load the Pkl module at the given source and evaluate it into `AnyType.Module`. 76 | /// 77 | /// - Parameter source: The source of the Pkl module. 78 | public static func loadFrom(source: ModuleSource) async throws -> AnyType.Module { 79 | try await PklSwift.withEvaluator { evaluator in 80 | try await loadFrom(evaluator: evaluator, source: source) 81 | } 82 | } 83 | 84 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 85 | /// `AnyType.Module`. 86 | /// 87 | /// - Parameter evaluator: The evaluator to use for evaluation. 88 | /// - Parameter source: The module to evaluate. 89 | public static func loadFrom( 90 | evaluator: PklSwift.Evaluator, 91 | source: PklSwift.ModuleSource 92 | ) async throws -> AnyType.Module { 93 | try await evaluator.evaluateModule(source: source, as: Module.self) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated_Swift/ApiTypes.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `ApiTypes`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum ApiTypes {} 5 | 6 | extension ApiTypes { 7 | public struct Module: PklRegisteredType, Decodable, Hashable { 8 | public static let registeredIdentifier: String = "ApiTypes" 9 | 10 | public var res1: Pair 11 | 12 | public var res2: Duration 13 | 14 | public var res3: DataSize 15 | 16 | public init(res1: Pair, res2: Duration, res3: DataSize) { 17 | self.res1 = res1 18 | self.res2 = res2 19 | self.res3 = res3 20 | } 21 | } 22 | 23 | /// Load the Pkl module at the given source and evaluate it into `ApiTypes.Module`. 24 | /// 25 | /// - Parameter source: The source of the Pkl module. 26 | public static func loadFrom(source: ModuleSource) async throws -> ApiTypes.Module { 27 | try await PklSwift.withEvaluator { evaluator in 28 | try await loadFrom(evaluator: evaluator, source: source) 29 | } 30 | } 31 | 32 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 33 | /// `ApiTypes.Module`. 34 | /// 35 | /// - Parameter evaluator: The evaluator to use for evaluation. 36 | /// - Parameter source: The module to evaluate. 37 | public static func loadFrom( 38 | evaluator: PklSwift.Evaluator, 39 | source: PklSwift.ModuleSource 40 | ) async throws -> ApiTypes.Module { 41 | try await evaluator.evaluateModule(source: source, as: Module.self) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated_Swift/Classes.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `Classes`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum Classes {} 5 | 6 | extension Classes { 7 | public struct Module: PklRegisteredType, Decodable, Hashable { 8 | public static let registeredIdentifier: String = "Classes" 9 | 10 | public var animals: [Animal] 11 | 12 | public init(animals: [Animal]) { 13 | self.animals = animals 14 | } 15 | } 16 | 17 | public struct Animal: PklRegisteredType, Decodable, Hashable { 18 | public static let registeredIdentifier: String = "Classes#Animal" 19 | 20 | public var name: String 21 | 22 | public init(name: String) { 23 | self.name = name 24 | } 25 | } 26 | 27 | /// Load the Pkl module at the given source and evaluate it into `Classes.Module`. 28 | /// 29 | /// - Parameter source: The source of the Pkl module. 30 | public static func loadFrom(source: ModuleSource) async throws -> Classes.Module { 31 | try await PklSwift.withEvaluator { evaluator in 32 | try await loadFrom(evaluator: evaluator, source: source) 33 | } 34 | } 35 | 36 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 37 | /// `Classes.Module`. 38 | /// 39 | /// - Parameter evaluator: The evaluator to use for evaluation. 40 | /// - Parameter source: The module to evaluate. 41 | public static func loadFrom( 42 | evaluator: PklSwift.Evaluator, 43 | source: PklSwift.ModuleSource 44 | ) async throws -> Classes.Module { 45 | try await evaluator.evaluateModule(source: source, as: Module.self) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated_Swift/Collections.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `Collections`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum Collections {} 5 | 6 | extension Collections { 7 | public struct Module: PklRegisteredType, Decodable, Hashable { 8 | public static let registeredIdentifier: String = "Collections" 9 | 10 | public var res1: [Int] 11 | 12 | public var res2: [Int] 13 | 14 | public var res3: [[Int]] 15 | 16 | public var res4: [[Int]] 17 | 18 | public var res5: [Int: Bool] 19 | 20 | public var res6: [Int: [Int: Bool]] 21 | 22 | public var res7: [Int: Bool] 23 | 24 | public var res8: [Int: [Int: Bool]] 25 | 26 | public var res9: Set 27 | 28 | public var res10: Set 29 | 30 | public init( 31 | res1: [Int], 32 | res2: [Int], 33 | res3: [[Int]], 34 | res4: [[Int]], 35 | res5: [Int: Bool], 36 | res6: [Int: [Int: Bool]], 37 | res7: [Int: Bool], 38 | res8: [Int: [Int: Bool]], 39 | res9: Set, 40 | res10: Set 41 | ) { 42 | self.res1 = res1 43 | self.res2 = res2 44 | self.res3 = res3 45 | self.res4 = res4 46 | self.res5 = res5 47 | self.res6 = res6 48 | self.res7 = res7 49 | self.res8 = res8 50 | self.res9 = res9 51 | self.res10 = res10 52 | } 53 | } 54 | 55 | /// Load the Pkl module at the given source and evaluate it into `Collections.Module`. 56 | /// 57 | /// - Parameter source: The source of the Pkl module. 58 | public static func loadFrom(source: ModuleSource) async throws -> Collections.Module { 59 | try await PklSwift.withEvaluator { evaluator in 60 | try await loadFrom(evaluator: evaluator, source: source) 61 | } 62 | } 63 | 64 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 65 | /// `Collections.Module`. 66 | /// 67 | /// - Parameter evaluator: The evaluator to use for evaluation. 68 | /// - Parameter source: The module to evaluate. 69 | public static func loadFrom( 70 | evaluator: PklSwift.Evaluator, 71 | source: PklSwift.ModuleSource 72 | ) async throws -> Collections.Module { 73 | try await evaluator.evaluateModule(source: source, as: Module.self) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated_Swift/ExtendedModule.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `ExtendedModule`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum ExtendedModule {} 5 | 6 | extension ExtendedModule { 7 | public struct Module: OpenModule.Module { 8 | public static let registeredIdentifier: String = "ExtendedModule" 9 | 10 | public var foo: String 11 | 12 | public var bar: Int 13 | 14 | public init(foo: String, bar: Int) { 15 | self.foo = foo 16 | self.bar = bar 17 | } 18 | } 19 | 20 | /// Load the Pkl module at the given source and evaluate it into `ExtendedModule.Module`. 21 | /// 22 | /// - Parameter source: The source of the Pkl module. 23 | public static func loadFrom(source: ModuleSource) async throws -> ExtendedModule.Module { 24 | try await PklSwift.withEvaluator { evaluator in 25 | try await loadFrom(evaluator: evaluator, source: source) 26 | } 27 | } 28 | 29 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 30 | /// `ExtendedModule.Module`. 31 | /// 32 | /// - Parameter evaluator: The evaluator to use for evaluation. 33 | /// - Parameter source: The module to evaluate. 34 | public static func loadFrom( 35 | evaluator: PklSwift.Evaluator, 36 | source: PklSwift.ModuleSource 37 | ) async throws -> ExtendedModule.Module { 38 | try await evaluator.evaluateModule(source: source, as: Module.self) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated_Swift/OpenModule.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `OpenModule`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum OpenModule {} 5 | 6 | public protocol OpenModule_Module: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var foo: String { get } 8 | 9 | var bar: Int { get } 10 | } 11 | 12 | extension OpenModule { 13 | public typealias Module = OpenModule_Module 14 | 15 | public struct ModuleImpl: Module { 16 | public static let registeredIdentifier: String = "OpenModule" 17 | 18 | public var foo: String 19 | 20 | public var bar: Int 21 | 22 | public init(foo: String, bar: Int) { 23 | self.foo = foo 24 | self.bar = bar 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated_Swift/pkl_swift_example_Poly.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `pkl.swift.example.Poly`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum pkl_swift_example_Poly {} 5 | 6 | public protocol pkl_swift_example_Poly_Animal: pkl_swift_lib1_Being { 7 | var name: String { get } 8 | } 9 | 10 | extension pkl_swift_example_Poly { 11 | public struct Module: PklRegisteredType, Decodable, Hashable { 12 | public static let registeredIdentifier: String = "pkl.swift.example.Poly" 13 | 14 | public var beings: [any pkl_swift_lib1.Being] 15 | 16 | public var rex: Dog 17 | 18 | public var moreBeings: [String: any pkl_swift_lib1.Being] 19 | 20 | public init( 21 | beings: [any pkl_swift_lib1.Being], 22 | rex: Dog, 23 | moreBeings: [String: any pkl_swift_lib1.Being] 24 | ) { 25 | self.beings = beings 26 | self.rex = rex 27 | self.moreBeings = moreBeings 28 | } 29 | 30 | public static func ==(lhs: Module, rhs: Module) -> Bool { 31 | arrayEquals(arr1: lhs.beings, arr2: rhs.beings) 32 | && lhs.rex == rhs.rex 33 | && mapEquals(map1: lhs.moreBeings, map2: rhs.moreBeings) 34 | } 35 | 36 | public func hash(into hasher: inout Hasher) { 37 | for x in self.beings { 38 | hasher.combine(x) 39 | } 40 | hasher.combine(rex) 41 | for (k, v) in self.moreBeings { 42 | hasher.combine(k) 43 | hasher.combine(v) 44 | } 45 | } 46 | 47 | public init(from decoder: Decoder) throws { 48 | let dec = try decoder.container(keyedBy: PklCodingKey.self) 49 | let beings = try dec.decode([PklSwift.PklAny].self, forKey: PklCodingKey(string: "beings")) 50 | .map { $0.value as! any pkl_swift_lib1.Being } 51 | let rex = try dec.decode(Dog.self, forKey: PklCodingKey(string: "rex")) 52 | let moreBeings = try dec.decode([String: PklSwift.PklAny].self, forKey: PklCodingKey(string: "moreBeings")) 53 | .mapValues { $0.value as! any pkl_swift_lib1.Being } 54 | self = Module(beings: beings, rex: rex, moreBeings: moreBeings) 55 | } 56 | } 57 | 58 | public struct Dog: Animal { 59 | public static let registeredIdentifier: String = "pkl.swift.example.Poly#Dog" 60 | 61 | public var barks: Bool 62 | 63 | public var hates: (any Animal)? 64 | 65 | public var name: String 66 | 67 | public var exists: Bool 68 | 69 | public init(barks: Bool, hates: (any Animal)?, name: String, exists: Bool) { 70 | self.barks = barks 71 | self.hates = hates 72 | self.name = name 73 | self.exists = exists 74 | } 75 | 76 | public static func ==(lhs: Dog, rhs: Dog) -> Bool { 77 | lhs.barks == rhs.barks 78 | && ((lhs.hates == nil && rhs.hates == nil) || lhs.hates?.isDynamicallyEqual(to: rhs.hates) ?? false) 79 | && lhs.name == rhs.name 80 | && lhs.exists == rhs.exists 81 | } 82 | 83 | public func hash(into hasher: inout Hasher) { 84 | hasher.combine(barks) 85 | if let hates { 86 | hasher.combine(hates) 87 | } 88 | hasher.combine(name) 89 | hasher.combine(exists) 90 | } 91 | 92 | public init(from decoder: Decoder) throws { 93 | let dec = try decoder.container(keyedBy: PklCodingKey.self) 94 | let barks = try dec.decode(Bool.self, forKey: PklCodingKey(string: "barks")) 95 | let hates = try dec.decode(PklSwift.PklAny.self, forKey: PklCodingKey(string: "hates")) 96 | .value as! (any Animal)? 97 | let name = try dec.decode(String.self, forKey: PklCodingKey(string: "name")) 98 | let exists = try dec.decode(Bool.self, forKey: PklCodingKey(string: "exists")) 99 | self = Dog(barks: barks, hates: hates, name: name, exists: exists) 100 | } 101 | } 102 | 103 | public typealias Animal = pkl_swift_example_Poly_Animal 104 | 105 | public struct AnimalImpl: Animal { 106 | public static let registeredIdentifier: String = "pkl.swift.example.Poly#Animal" 107 | 108 | public var name: String 109 | 110 | public var exists: Bool 111 | 112 | public init(name: String, exists: Bool) { 113 | self.name = name 114 | self.exists = exists 115 | } 116 | } 117 | 118 | public struct Bird: pkl_swift_lib1.Being { 119 | public static let registeredIdentifier: String = "pkl.swift.example.Poly#Bird" 120 | 121 | public var name: String 122 | 123 | public var flies: Bool 124 | 125 | public var exists: Bool 126 | 127 | public init(name: String, flies: Bool, exists: Bool) { 128 | self.name = name 129 | self.flies = flies 130 | self.exists = exists 131 | } 132 | } 133 | 134 | /// Load the Pkl module at the given source and evaluate it into `pkl_swift_example_Poly.Module`. 135 | /// 136 | /// - Parameter source: The source of the Pkl module. 137 | public static func loadFrom(source: ModuleSource) async throws -> pkl_swift_example_Poly.Module { 138 | try await PklSwift.withEvaluator { evaluator in 139 | try await loadFrom(evaluator: evaluator, source: source) 140 | } 141 | } 142 | 143 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 144 | /// `pkl_swift_example_Poly.Module`. 145 | /// 146 | /// - Parameter evaluator: The evaluator to use for evaluation. 147 | /// - Parameter source: The module to evaluate. 148 | public static func loadFrom( 149 | evaluator: PklSwift.Evaluator, 150 | source: PklSwift.ModuleSource 151 | ) async throws -> pkl_swift_example_Poly.Module { 152 | try await evaluator.evaluateModule(source: source, as: Module.self) 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /tests/Fixtures/Generated_Swift/pkl_swift_lib1.pkl.swift: -------------------------------------------------------------------------------- 1 | // Code generated from Pkl module `pkl.swift.lib1`. DO NOT EDIT. 2 | import PklSwift 3 | 4 | public enum pkl_swift_lib1 {} 5 | 6 | public protocol pkl_swift_lib1_Being: PklRegisteredType, DynamicallyEquatable, Hashable { 7 | var exists: Bool { get } 8 | } 9 | 10 | extension pkl_swift_lib1 { 11 | public struct Module: PklRegisteredType, Decodable, Hashable { 12 | public static let registeredIdentifier: String = "pkl.swift.lib1" 13 | 14 | public init() {} 15 | } 16 | 17 | public typealias Being = pkl_swift_lib1_Being 18 | 19 | /// Load the Pkl module at the given source and evaluate it into `pkl_swift_lib1.Module`. 20 | /// 21 | /// - Parameter source: The source of the Pkl module. 22 | public static func loadFrom(source: ModuleSource) async throws -> pkl_swift_lib1.Module { 23 | try await PklSwift.withEvaluator { evaluator in 24 | try await loadFrom(evaluator: evaluator, source: source) 25 | } 26 | } 27 | 28 | /// Load the Pkl module at the given source and evaluate it with the given evaluator into 29 | /// `pkl_swift_lib1.Module`. 30 | /// 31 | /// - Parameter evaluator: The evaluator to use for evaluation. 32 | /// - Parameter source: The module to evaluate. 33 | public static func loadFrom( 34 | evaluator: PklSwift.Evaluator, 35 | source: PklSwift.ModuleSource 36 | ) async throws -> pkl_swift_lib1.Module { 37 | try await evaluator.evaluateModule(source: source, as: Module.self) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/Fixtures/OpenModule.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | open module OpenModule 17 | 18 | foo: String 19 | 20 | bar: Int 21 | -------------------------------------------------------------------------------- /tests/Fixtures/Poly.pkl: -------------------------------------------------------------------------------- 1 | module pkl.python.example.Poly 2 | 3 | import "lib1.pkl" 4 | 5 | beings: Listing = new { 6 | new Animal { 7 | name = "Lion" 8 | } 9 | new Dog { 10 | name = "Ruuf" 11 | barks = true 12 | } 13 | new Bird { 14 | name = "Duck" 15 | flies = false 16 | exists = false 17 | } 18 | } 19 | 20 | rex: Dog = new { 21 | name = "Rex" 22 | barks = false 23 | } 24 | 25 | moreBeings: Mapping = new { 26 | ["duck"] = new Bird { 27 | name = "Ducky" 28 | flies = true 29 | } 30 | ["dog"] = new Dog { 31 | name = "TRex" 32 | barks = false 33 | hates = rex 34 | } 35 | } 36 | 37 | open class Animal extends lib1.Being { 38 | name: String 39 | } 40 | 41 | class Bird extends lib1.Being { 42 | name: String 43 | flies: Boolean 44 | } 45 | 46 | class Dog extends Animal { 47 | barks: Boolean 48 | hates: Animal? 49 | } 50 | -------------------------------------------------------------------------------- /tests/Fixtures/UnionTypes.pkl: -------------------------------------------------------------------------------- 1 | class Banana { 2 | isRipe: Boolean 3 | } 4 | 5 | class Grape { 6 | isUsedForWine: Boolean 7 | } 8 | 9 | class Apple { 10 | isRed: Boolean 11 | } 12 | 13 | abstract class Animal { 14 | name: String 15 | } 16 | 17 | typealias Fruit = Banana | Grape | Apple 18 | 19 | typealias City = "San Francisco"|"Tokyo"|"Zurich"|"London" 20 | 21 | fruit1: Fruit = new Banana { 22 | isRipe = true 23 | } 24 | 25 | fruit2: Fruit = new Grape { 26 | isUsedForWine = true 27 | } 28 | 29 | fruit3: Fruit = new Apple { 30 | isRed = false 31 | } 32 | 33 | city1: City = "San Francisco" 34 | 35 | city2: City = "Tokyo" 36 | 37 | city3: City = "Zurich" 38 | 39 | city4: City = "London" 40 | 41 | class Zebra extends Animal { name = "Zebra" } 42 | 43 | class Donkey extends Animal { name = "Donkey" } 44 | 45 | typealias ZebraOrDonkey = Zebra|Donkey 46 | 47 | animal1: ZebraOrDonkey = new Zebra {} 48 | 49 | animal2: ZebraOrDonkey = new Donkey {} 50 | 51 | typealias AnimalOrString = Animal|String 52 | 53 | animalOrString1: AnimalOrString = new Zebra {} 54 | 55 | animalOrString2: AnimalOrString = "Zebra" 56 | -------------------------------------------------------------------------------- /tests/Fixtures/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jw-y/pkl-python/9119258861a8e8a133b62194183ea69ff06fc32f/tests/Fixtures/__init__.py -------------------------------------------------------------------------------- /tests/Fixtures/lib1.pkl: -------------------------------------------------------------------------------- 1 | module pkl.python.lib1 2 | 3 | abstract class Being { 4 | exists: Boolean = true 5 | } 6 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jw-y/pkl-python/9119258861a8e8a133b62194183ea69ff06fc32f/tests/__init__.py -------------------------------------------------------------------------------- /tests/_pkl/any.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/any" } 17 | module any 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | class Person { 22 | name: String 23 | } 24 | 25 | res1 = new Listing { 26 | new { 27 | name = "Barney" 28 | } 29 | } 30 | 31 | res2 = new Person { 32 | name = "Bobby" 33 | } 34 | 35 | res3 = new Mapping { 36 | ["Wilma"] { 37 | name = "Wilma" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/_pkl/classes.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/classes" } 17 | module classes 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | animals: Listing = new { 22 | new Greyhound { name = "Uni"; barks = false; canRoach = true } 23 | new Cat { name = "Millie"; meows = true } 24 | } 25 | 26 | myAnimal: Animal = new Greyhound { 27 | name = "Uni" 28 | barks = false 29 | canRoach = true 30 | } 31 | 32 | house: House = new { 33 | area = 2000 34 | bedrooms = 3 35 | bathrooms = 2 36 | } 37 | 38 | abstract class Animal { 39 | name: String 40 | } 41 | 42 | open class Dog extends Animal { 43 | barks: Boolean 44 | breed: String 45 | } 46 | 47 | class Greyhound extends Dog { 48 | breed = "Greyhound" 49 | canRoach: Boolean 50 | } 51 | 52 | class Cat extends Animal { 53 | meows: Boolean 54 | } 55 | 56 | class House { 57 | area: Int 58 | bedrooms: Int 59 | bathrooms: Int 60 | } 61 | -------------------------------------------------------------------------------- /tests/_pkl/collections.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/collections" } 17 | module collections 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | res1: List = List(1, 2, 3) 22 | 23 | res2: Listing = new { 2; 3; 4; } 24 | 25 | res3: List> = List(List(1), List(2), List(3)) 26 | 27 | res4: Listing> = new { new { 1 }; new { 2 }; new { 3 } } 28 | 29 | res5: Mapping = new { [1] = true; [2] = false } 30 | 31 | res6: Mapping> = new { 32 | [1] { 33 | [1] = true 34 | } 35 | [2] { 36 | [2] = true 37 | } 38 | [3] { 39 | [3] = true 40 | } 41 | } 42 | 43 | res7: Map = Map(1, true, 2, false) 44 | 45 | res8: Map> = Map(1, Map(1, true), 2, Map(2, false)) 46 | 47 | res9: Set = Set("one", "two", "three") 48 | 49 | res10: Set = Set(1, 2, 3) 50 | 51 | res11: Pair = Pair(1, 5.0) 52 | 53 | res12: Pair = Pair("hello", "goodbye") 54 | 55 | res13: Pair = Pair(1, 2) 56 | -------------------------------------------------------------------------------- /tests/_pkl/datasize.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/datasize" } 17 | module datasize 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | res1: DataSize = 1.b 22 | 23 | res2: DataSize = 2.kb 24 | 25 | res3: DataSize = 3.mb 26 | 27 | res4: DataSize = 4.gb 28 | 29 | res5: DataSize = 5.tb 30 | 31 | res6: DataSize = 6.pb 32 | 33 | res7: DataSize = 7.kib 34 | 35 | res8: DataSize = 8.mib 36 | 37 | res9: DataSize = 9.gib 38 | 39 | res10: DataSize = 10.tib 40 | 41 | res11: DataSize = 11.pib 42 | 43 | res12: DataSizeUnit = "mb" 44 | -------------------------------------------------------------------------------- /tests/_pkl/duration.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/duration" } 17 | module duration 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | res1: Duration = 1.ns 22 | 23 | res2: Duration = 2.us 24 | 25 | res3: Duration = 3.ms 26 | 27 | res4: Duration = 4.s 28 | 29 | res5: Duration = 5.min 30 | 31 | res6: Duration = 6.h 32 | 33 | res7: Duration = 7.d 34 | 35 | res8: DurationUnit = "us" 36 | -------------------------------------------------------------------------------- /tests/_pkl/dynamic.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/dynamic" } 17 | module dynamic 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | res1: Dynamic = new { 22 | res2 { res3 = 5 } 23 | ["res4"] = 6 24 | new MyClass { myValue = 7 } 25 | res5 = new MyClass { myValue = 8 } 26 | [5] = 9 27 | } 28 | 29 | class MyClass { 30 | myValue: Int 31 | } 32 | -------------------------------------------------------------------------------- /tests/_pkl/nullables.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/nullables" } 17 | module nullables 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | res0: String? = "bar" 22 | res1: String? = null 23 | res2: Int? = 1 24 | res3: Int? = null 25 | res4: Int8? = 2 26 | res5: Int8? = null 27 | res6: Int16? = 3 28 | res7: Int16? = null 29 | res8: Int32? = 4 30 | res9: Int32? = null 31 | res10: UInt? = 5 32 | res11: UInt? = null 33 | res12: UInt8? = 6 34 | res13: UInt8? = null 35 | res14: UInt16? = 7 36 | res15: UInt16? = null 37 | res16: UInt32? = 8 38 | res17: UInt32? = null 39 | res18: Float? = 5.3 40 | res19: Float? = null 41 | res20: Boolean? = true 42 | res21: Boolean? = null 43 | res22: Mapping? = new { ["foo"] = "bar" } 44 | res23: Mapping? = null 45 | // can't test this due to https://github.com/stretchr/testify/issues/1143 46 | //res24: Mapping? = new { 47 | // ["foo"] = "bar" 48 | // [null] = null 49 | // ["foo2"] = null 50 | //} 51 | res25: Mapping? = null 52 | res26: Listing? = new { 1; 2; null; 4; 5 } 53 | res27: Listing? = null 54 | res28: MyClass? = new {} 55 | res29: MyClass? = new { prop = "foo" } 56 | res30: MyClass? = null 57 | 58 | class MyClass { 59 | prop: String? 60 | } 61 | -------------------------------------------------------------------------------- /tests/_pkl/primitives.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/primitives" } 17 | module primitives 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | res0: String = "bar" 22 | res1: Int = 1 23 | res2: Int8 = 2 24 | res3: Int16 = 3 25 | res4: Int32 = 4 26 | res5: UInt = 5 27 | res6: UInt8 = 6 28 | res7: UInt16 = 7 29 | res8: UInt32 = 8 30 | res9: Float = 5.3 31 | res10: Boolean = true 32 | res11: Null = null 33 | res12: Number = 33 34 | res13: Number = 33.3333 35 | -------------------------------------------------------------------------------- /tests/_pkl/testfs/person.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | name: String = "Barney" 17 | 18 | age: Int = 43 19 | -------------------------------------------------------------------------------- /tests/_pkl/testfs/subdir/person.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | amends "..." 17 | 18 | name = "Fred" 19 | -------------------------------------------------------------------------------- /tests/_pkl/unions.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/unions" } 17 | module unions 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | res1: Number = "two" 22 | res2: OtherNumbers = "三" 23 | 24 | typealias Number = "one"|"two"|"three" 25 | typealias OtherNumbers = nothing|"一"|"二"|"三" 26 | -------------------------------------------------------------------------------- /tests/_pkl/unknown_type.pkl: -------------------------------------------------------------------------------- 1 | // ===----------------------------------------------------------------------===// 2 | // Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ===----------------------------------------------------------------------===// 16 | //@go.Package { name = "github.com/apple/pkl-go/pkl/test_fixtures/gen/unknown_type" } 17 | module unknown_type 18 | 19 | //import ".../codegen/src/go.pkl" 20 | 21 | // Simulate a situation where a property's type is generated as `any`, and the value is not a type that is codegen'd. 22 | res: Any = new PcfRenderer {} 23 | -------------------------------------------------------------------------------- /tests/pkls/AppConfig.pkl: -------------------------------------------------------------------------------- 1 | @python.Package { name = "/home/jwyang/dev/pkll/tests/" } 2 | module myorg.myteam.AppConfig 3 | 4 | import ".../codegen/src/python.pkl" 5 | 6 | /// The hostname of this application. 7 | host: String 8 | 9 | /// The port to listen on. 10 | port: UInt16 11 | -------------------------------------------------------------------------------- /tests/pkls/codegen.pkl: -------------------------------------------------------------------------------- 1 | @python.Package { name = "/home/jwyang/dev/pkll/tests/" } 2 | module any 3 | 4 | import ".../codegen/src/python.pkl" 5 | 6 | class Person { 7 | name: String 8 | } 9 | 10 | res1 = new Listing { 11 | new { 12 | name = "Barney" 13 | } 14 | } 15 | 16 | res2 = new Person { 17 | name = "Bobby" 18 | } 19 | 20 | res3 = new Mapping { 21 | ["Wilma"] { 22 | name = "Wilma" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/pkls/glob.pkl: -------------------------------------------------------------------------------- 1 | module MyModule 2 | 3 | theModules = import*("../test_fixtures/*.pkl") 4 | 5 | 6 | @Deprecated { message = "Replace with" } 7 | x0: Int = 1 8 | 9 | x1: Int = trace(1) 10 | -------------------------------------------------------------------------------- /tests/pkls/myModule.pkl: -------------------------------------------------------------------------------- 1 | module MyModule 2 | 3 | theModules = import*("customfs:/*.pkl") 4 | -------------------------------------------------------------------------------- /tests/pkls/types.pkl: -------------------------------------------------------------------------------- 1 | 2 | a : Int = 1 3 | b : Float = 2.0 4 | c : String = "Hello, World!" 5 | d : Boolean = true 6 | e = Null 7 | 8 | dynamic = new Dynamic {} 9 | 10 | class Bird { 11 | name: String 12 | lifespan: Int 13 | migratory: Boolean 14 | } 15 | typed = new Bird { 16 | name = "Pigeon" 17 | lifespan = 8 18 | migratory = false 19 | } 20 | 21 | map = Map() 22 | mapping : Mapping = new {} 23 | 24 | list = List() 25 | listing : Listing = new {} 26 | 27 | sett = Set() 28 | 29 | duration: Duration = 10.ms 30 | 31 | datasize: DataSize = 16.b 32 | 33 | pair = Pair(1, "A") 34 | 35 | x = IntSeq(0, 10) 36 | 37 | y = Regex("[a-z]{1,5}") 38 | -------------------------------------------------------------------------------- /tests/pkls/with_log.pkl: -------------------------------------------------------------------------------- 1 | 2 | 3 | a = 1 4 | b = trace(1) 5 | -------------------------------------------------------------------------------- /tests/pkls/with_read.pkl: -------------------------------------------------------------------------------- 1 | path = read*("customfs:/*.txt") 2 | -------------------------------------------------------------------------------- /tests/test_binary.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import pytest 5 | 6 | import pkl 7 | from pkl.binary_manager import BinaryManager 8 | 9 | 10 | def remove_pkl_from_path(monkeypatch): 11 | manager = BinaryManager() 12 | path = manager.is_command_available() 13 | if path is None: 14 | return 15 | path = path.rsplit("/", 1)[0] 16 | original_path = os.environ.get("PATH", "") 17 | paths = original_path.split(os.pathsep) 18 | paths = [p for p in paths if path not in p] 19 | monkeypatch.setenv("PATH", os.pathsep.join(paths)) 20 | 21 | 22 | def remove_pkl_binary(): 23 | path = Path(pkl.__file__) 24 | ls = list((path.parent / "bin").iterdir()) 25 | if len(ls) == 0: 26 | return 27 | assert len(ls) == 1 28 | binary_path = ls[0] 29 | os.remove(binary_path) 30 | return binary_path 31 | 32 | 33 | def test_latest_release(): 34 | manager = BinaryManager() 35 | urls = manager.get_latest_pkl_release_urls() 36 | assert len(urls) == 7 37 | 38 | 39 | def test_without_download_binary(): 40 | manager = BinaryManager() 41 | output = manager.check() 42 | assert output.lower().startswith("pkl") 43 | 44 | 45 | def test_download_binary(monkeypatch: pytest.MonkeyPatch): 46 | remove_pkl_binary() 47 | remove_pkl_from_path(monkeypatch) 48 | manager = BinaryManager() 49 | output = manager.check() 50 | assert output.lower().startswith("pkl") 51 | 52 | removed = remove_pkl_binary() 53 | assert manager.binary_path == removed 54 | 55 | 56 | def test_binary_file_exists(): 57 | manager = BinaryManager() 58 | manager.is_command_available() 59 | 60 | fp = manager.get_binary_filepath() 61 | assert os.path.exists(fp), f"Binary file not found at {fp}" 62 | -------------------------------------------------------------------------------- /tests/test_evaluator_manager.py: -------------------------------------------------------------------------------- 1 | from pkl import EvaluatorManager, EvaluatorOptions, ModuleSource, PreconfiguredOptions 2 | 3 | 4 | def test_manager(): 5 | with EvaluatorManager(debug=True) as manager: 6 | manager.new_evaluator(EvaluatorOptions()) 7 | 8 | 9 | def test_multiple(): 10 | with EvaluatorManager(debug=True) as manager: 11 | opts = PreconfiguredOptions() 12 | evaluator = manager.new_evaluator(opts) 13 | source = ModuleSource.from_path("./tests/pkls/with_log.pkl") 14 | evaluator.evaluate_module(source) 15 | -------------------------------------------------------------------------------- /tests/test_fixtures.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import pkl 4 | from tests.Fixtures.Generated.AnyType_pkl import AnyType, Bird 5 | from tests.Fixtures.Generated.ApiTypes_pkl import ApiTypes 6 | from tests.Fixtures.Generated.Classes_pkl import Animal, Classes 7 | from tests.Fixtures.Generated.Collections_pkl import Collections 8 | from tests.Fixtures.Generated.ExtendedModule_pkl import ExtendedModule 9 | 10 | base_path = Path("./tests/Fixtures") 11 | 12 | 13 | def test_evaluate_classes(): 14 | result = Classes.load_pkl(base_path / "Classes.pkl") 15 | expected = Classes( 16 | animals=[ 17 | Animal(name="Uni"), 18 | Animal(name="Wally"), 19 | Animal(name="Mouse"), 20 | ] 21 | ) 22 | assert result == expected 23 | 24 | 25 | def test_evaluate_collections(): 26 | result = Collections.load_pkl(base_path / "Collections.pkl") 27 | expected = Collections( 28 | res1=[1, 2, 3], 29 | res2=[2, 3, 4], 30 | res3=[[1], [2], [3]], 31 | res4=[[1], [2], [3]], 32 | res5={1: True, 2: False}, 33 | res6={1: {1: True}, 2: {2: True}, 3: {3: True}}, 34 | res7={1: True, 2: False}, 35 | res8={1: {1: True}, 2: {2: False}}, 36 | res9={"one", "two", "three"}, 37 | res10={1, 2, 3}, 38 | ) 39 | assert result == expected 40 | 41 | 42 | def test_evaluate_api_types(): 43 | result = ApiTypes.load_pkl(base_path / "ApiTypes.pkl") 44 | # Define expected result based on your ApiTypes.Module structure 45 | expected = ApiTypes( 46 | res1=pkl.Pair(42, "Hello"), 47 | res2=pkl.Duration(10, "h"), 48 | res3=pkl.DataSize(1.2345, "gib"), 49 | ) 50 | assert result == expected 51 | 52 | 53 | def test_polymorphic_types(): 54 | from tests.Fixtures.Generated.pkl_python_example_Poly_pkl import ( 55 | Animal, 56 | Bird, 57 | Dog, 58 | Poly, 59 | ) 60 | 61 | result = Poly.load_pkl(base_path / "Poly.pkl") 62 | expected = Poly( 63 | beings=[ 64 | Animal(name="Lion", exists=True), 65 | Dog(barks=True, hates=None, name="Ruuf", exists=True), 66 | Bird(name="Duck", flies=False, exists=False), 67 | ], 68 | rex=Dog(barks=False, hates=None, name="Rex", exists=True), 69 | moreBeings={ 70 | "duck": Bird(name="Ducky", flies=True, exists=True), 71 | "dog": Dog( 72 | barks=False, 73 | hates=Dog(barks=False, hates=None, name="Rex", exists=True), 74 | name="TRex", 75 | exists=True, 76 | ), 77 | }, 78 | ) 79 | assert result == expected 80 | 81 | 82 | def test_polymorphic_modules(): 83 | result = ExtendedModule.load_pkl(base_path / "ExtendedModule.pkl") 84 | expected = ExtendedModule(foo="foo", bar=10) 85 | assert result == expected 86 | 87 | 88 | def test_any_type(): 89 | result = AnyType.load_pkl(base_path / "AnyType.pkl") 90 | expected = AnyType( 91 | bird=Bird(species="Owl"), 92 | primitive="foo", 93 | primitive2=12, 94 | array=[1, 2], 95 | set={5, 6}, 96 | mapping={"1": 12, 12: "1"}, 97 | nullable=None, 98 | duration=pkl.Duration(5.0, unit="min"), 99 | dataSize=pkl.DataSize(10.0, unit="mb"), 100 | ) 101 | assert result == expected 102 | 103 | 104 | def test_union_types(): 105 | from tests.Fixtures.Generated.UnionTypes_pkl import ( 106 | Apple, 107 | Banana, 108 | Donkey, 109 | Grape, 110 | UnionTypes, 111 | Zebra, 112 | ) 113 | 114 | result = UnionTypes.load_pkl(base_path / "UnionTypes.pkl") 115 | expected = UnionTypes( 116 | fruit1=Banana(isRipe=True), 117 | fruit2=Grape(isUsedForWine=True), 118 | fruit3=Apple(isRed=False), 119 | city1="San Francisco", 120 | city2="Tokyo", 121 | city3="Zurich", 122 | city4="London", 123 | animal1=Zebra(name="Zebra"), 124 | animal2=Donkey(name="Donkey"), 125 | animalOrString1=Zebra(name="Zebra"), 126 | animalOrString2="Zebra", 127 | ) 128 | assert result == expected 129 | -------------------------------------------------------------------------------- /tests/test_load.py: -------------------------------------------------------------------------------- 1 | import pkl 2 | 3 | 4 | def test_load(): 5 | _ = pkl.load("./tests/pkls/types.pkl") 6 | 7 | 8 | def test_loads(): 9 | config = pkl.loads("a: Int = 1 + 1") 10 | assert config.a == 2 11 | 12 | 13 | def test_load_expr(): 14 | config = pkl.load("./tests/pkls/types.pkl", expr="datasize") 15 | assert config.__class__.__name__ == "DataSize" 16 | 17 | 18 | def test_load_text(): 19 | config = pkl.load(None, module_text="a: Int = 1 + 1") 20 | assert config.a == 2 21 | 22 | 23 | def test_load_debug(): 24 | _ = pkl.load("./tests/pkls/types.pkl", debug=True) 25 | -------------------------------------------------------------------------------- /tests/test_parser.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import pytest 4 | 5 | import pkl 6 | 7 | base_path = Path("./tests/Fixtures") 8 | 9 | 10 | def test_AnyType(): 11 | file = base_path / "AnyType.pkl" 12 | _ = pkl.load(file) 13 | 14 | 15 | def test_ApiTypes(): 16 | file = base_path / "ApiTypes.pkl" 17 | _ = pkl.load(file) 18 | 19 | 20 | def test_Classes(): 21 | file = base_path / "Classes.pkl" 22 | _ = pkl.load(file) 23 | 24 | 25 | def test_Collections(): 26 | file = base_path / "Collections.pkl" 27 | _ = pkl.load(file) 28 | 29 | 30 | def test_ExtendedModule(): 31 | file = base_path / "ExtendedModule.pkl" 32 | _ = pkl.load(file) 33 | 34 | 35 | def test_OpenModule(): 36 | file = base_path / "OpenModule.pkl" 37 | with pytest.raises(Exception): 38 | _ = pkl.load(file) 39 | 40 | 41 | def test_Poly(): 42 | file = base_path / "Poly.pkl" 43 | _ = pkl.load(file) 44 | 45 | 46 | def test_UnionTypes(): 47 | file = base_path / "UnionTypes.pkl" 48 | _ = pkl.load(file) 49 | 50 | 51 | def test_lib1(): 52 | file = base_path / "lib1.pkl" 53 | _ = pkl.load(file) 54 | 55 | 56 | def test_types(): 57 | file = Path("./tests/pkls") / "types.pkl" 58 | _ = pkl.load(file) 59 | -------------------------------------------------------------------------------- /tests/test_readers.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import pytest 4 | 5 | import pkl 6 | from pkl import ( 7 | ModuleReader, 8 | PathElement, 9 | PklError, 10 | PreconfiguredOptions, 11 | ResourceReader, 12 | ) 13 | 14 | 15 | def test_read_modules(): 16 | class TestModuleReader(ModuleReader): 17 | def read(self, url) -> str: 18 | return "foo = 1" 19 | 20 | def list_elements(self, url: str) -> List[PathElement]: 21 | return [PathElement("foo.pkl", False)] 22 | 23 | opts = PreconfiguredOptions( 24 | moduleReaders=[TestModuleReader("customfs", True, True, True)] 25 | ) 26 | opts.allowedModules.append("customfs:") 27 | _ = pkl.load("./tests/pkls/myModule.pkl", evaluator_options=opts) 28 | 29 | 30 | def test_read_modules_error(): 31 | class TestModuleReader(ModuleReader): 32 | def read(self, url) -> str: 33 | raise FileNotFoundError("foo.pkl not found") 34 | 35 | def list_elements(self, url: str) -> List[PathElement]: 36 | return [PathElement("foo.pkl", False)] 37 | 38 | opts = PreconfiguredOptions( 39 | moduleReaders=[TestModuleReader("customfs", True, True, True)] 40 | ) 41 | opts.allowedModules.append("customfs:") 42 | with pytest.raises(PklError): 43 | _ = pkl.load("./tests/pkls/myModule.pkl", evaluator_options=opts) 44 | 45 | 46 | def test_read_resources(): 47 | class TestResourceReader(ResourceReader): 48 | def read(self, url) -> bytes: 49 | return b"Hello, World!" 50 | 51 | def list_elements(self, url: str) -> List[PathElement]: 52 | return [PathElement("foo.txt", False)] 53 | 54 | opts = PreconfiguredOptions( 55 | resourceReaders=[ 56 | TestResourceReader( 57 | scheme="customfs", hasHierarchicalUris=True, isGlobbable=True 58 | ) 59 | ] 60 | ) 61 | opts.allowedResources.append("customfs:") 62 | 63 | _ = pkl.load("./tests/pkls/with_read.pkl", evaluator_options=opts) 64 | -------------------------------------------------------------------------------- /tests/test_server.py: -------------------------------------------------------------------------------- 1 | from pkl.server import PKLServer 2 | 3 | 4 | def test_server(): 5 | server = PKLServer() 6 | server.terminate() 7 | -------------------------------------------------------------------------------- /tests/test_trace.py: -------------------------------------------------------------------------------- 1 | import pkl 2 | 3 | 4 | def test_trace(): 5 | _ = pkl.load("tests/trace.pkl") 6 | 7 | 8 | if __name__ == "__main__": 9 | test_trace() 10 | -------------------------------------------------------------------------------- /tests/trace.pkl: -------------------------------------------------------------------------------- 1 | many = new Listing { 2 | for (i in IntSeq(0, 100)) { 3 | trace(i) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [testenv:flake8] 2 | basepython = python3.10 3 | deps = flake8 4 | commands = flake8 pkl tests 5 | 6 | [flake8] 7 | max-line-length = 120 8 | exclude = .git,__pycache__,docs/source/conf.py,old,build,dist 9 | ignore = E203,W503 10 | per-file-ignores = 11 | codegen/snippet-tests/output/*: F401 12 | --------------------------------------------------------------------------------