├── .envrc ├── {{cookiecutter.package_name}} ├── {{cookiecutter.package_name}} │ ├── py.typed │ ├── __init__.py │ └── {{cookiecutter.package_name}}.py ├── .envrc ├── tests │ ├── __init__.py │ └── test_stub.py ├── .editorconfig ├── .coveragerc ├── .github │ └── workflows │ │ └── test.yml ├── .pre-commit-config.yaml ├── licenses │ ├── MIT │ ├── BSD-3-clause │ └── APL-2.0 ├── README.md ├── pyproject.toml └── .gitignore ├── template_config.yml ├── .editorconfig ├── .coveragerc ├── cookiecutter.json ├── hooks ├── pre_gen_project.py └── post_gen_project.py ├── .pre-commit-config.yaml ├── LICENSE ├── .github └── workflows │ └── test.yml ├── pyproject.toml ├── README.md ├── notes.md ├── .gitignore └── pixi.lock /.envrc: -------------------------------------------------------------------------------- 1 | watch_file pixi.lock 2 | eval "$(pixi shell-hook -e dev)" 3 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/{{cookiecutter.package_name}}/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/.envrc: -------------------------------------------------------------------------------- 1 | watch_file pixi.lock 2 | eval "$(pixi shell-hook -e dev)" 3 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/tests/__init__.py: -------------------------------------------------------------------------------- 1 | """Tests for the {{cookiecutter.package_name}} package.""" 2 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/{{cookiecutter.package_name}}/__init__.py: -------------------------------------------------------------------------------- 1 | """{{cookiecutter.package_name}} package.""" 2 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/{{cookiecutter.package_name}}/{{cookiecutter.package_name}}.py: -------------------------------------------------------------------------------- 1 | """{{cookiecutter.package_name}} package.""" 2 | -------------------------------------------------------------------------------- /template_config.yml: -------------------------------------------------------------------------------- 1 | default_context: 2 | author_name: "John Smith" 3 | email: "" 4 | github_username: "" 5 | abbreviations: 6 | bb: https://bitbucket.org/{0} 7 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/tests/test_stub.py: -------------------------------------------------------------------------------- 1 | """Tests for the {{cookiecutter.package_name}} package.""" 2 | 3 | 4 | def test_stub() -> None: 5 | """Stub test to ensure the test suite runs.""" 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org/#file-format-details 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 4 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org/#file-format-details 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 4 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = hooks/ 3 | 4 | [report] 5 | exclude_lines = 6 | # Have to re-enable the standard pragma 7 | pragma: no cover 8 | 9 | # Don't complain about missing debug-only code: 10 | def __repr__ 11 | if self\.debug 12 | 13 | # Don't complain if tests don't hit defensive assertion code: 14 | raise AssertionError 15 | raise NotImplementedError 16 | 17 | # Don't complain if non-runnable code isn't run: 18 | if 0: 19 | if __name__ == .__main__.: 20 | 21 | # Don't complain if an ellipsis isn't run (typically in an abstractmethod): 22 | ^\s*\.\.\. 23 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = {{cookiecutter.package_name}} 3 | omit = {{cookiecutter.package_name}}/__main__.py 4 | 5 | [report] 6 | exclude_lines = 7 | # Have to re-enable the standard pragma 8 | pragma: no cover 9 | 10 | # Don't complain about missing debug-only code: 11 | def __repr__ 12 | if self\.debug 13 | 14 | # Don't complain if tests don't hit defensive assertion code: 15 | raise AssertionError 16 | raise NotImplementedError 17 | 18 | # Don't complain if non-runnable code isn't run: 19 | if 0: 20 | if __name__ == .__main__.: 21 | 22 | # Don't complain if an ellipsis isn't run (typically in an abstractmethod): 23 | ^\s*\.\.\. 24 | -------------------------------------------------------------------------------- /cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "Pixi Project", 3 | "package_name": "{{cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_')}}", 4 | "author_name": "", 5 | "github_username": "", 6 | "project_url": "https://github.com/{{cookiecutter.github_username}}/{{cookiecutter.package_name}}", 7 | "pixi_dependencies": "", 8 | "pixi_test_dependencies": "", 9 | "line_length": "100", 10 | "license": ["MIT", "APL-2.0", "BSD-3-clause", "None"], 11 | "github_setup": ["None", "private", "internal", "public"], 12 | "_copy_without_render": [".github/workflows"], 13 | "__prompts__": { 14 | "pixi_dependencies": "Pixi dependencies (e.g. numpy scipy@1.14.*)", 15 | "pixi_test_dependencies": "Pixi test dependencies (e.g. pytest-xdist@>=3.6)" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | pull_request: {} 5 | push: 6 | branches: master 7 | 8 | jobs: 9 | test: 10 | strategy: 11 | matrix: 12 | python-version: ['3.14'] 13 | os: [ubuntu-latest] 14 | 15 | name: Python ${{ matrix.os }} ${{ matrix.python-version }} 16 | runs-on: ${{ matrix.os }} 17 | 18 | steps: 19 | - uses: actions/checkout@v5 20 | 21 | - uses: actions/setup-python@v6 22 | with: 23 | python-version: ${{ matrix.python-version }} 24 | 25 | - uses: prefix-dev/setup-pixi@v0.9.1 26 | with: 27 | pixi-version: v0.56.0 28 | cache: true 29 | environments: dev 30 | 31 | - run: pixi run fmt 32 | - run: pixi run lint 33 | - run: pixi run types 34 | - run: pixi run test --cov --cov-report=xml 35 | 36 | - name: Upload Coverage to Codecov 37 | uses: codecov/codecov-action@v4 38 | env: 39 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 40 | -------------------------------------------------------------------------------- /hooks/pre_gen_project.py: -------------------------------------------------------------------------------- 1 | """Hooks to run before generating the project.""" 2 | 3 | from re import match 4 | 5 | 6 | def main() -> None: 7 | """Run the hooks.""" 8 | check_module_name("{{cookiecutter.package_name}}") 9 | 10 | 11 | def check_module_name(module_name: str) -> None: 12 | """ 13 | Check if the module name is a valid Python module name. 14 | 15 | :param module_name: the name of the module to check. 16 | :raises ValueError: if the module name is not a valid Python module name. 17 | 18 | >>> check_module_name("valid_module_name") 19 | >>> check_module_name("valid_module_name2") 20 | >>> check_module_name("invalid module name") 21 | Traceback (most recent call last): 22 | ... 23 | ValueError: module_name='invalid module name' is not a valid Python module name. 24 | """ 25 | MODULE_REGEX = r"^[a-zA-Z][_a-zA-Z0-9]+$" 26 | 27 | if not match(MODULE_REGEX, module_name): 28 | raise ValueError(f"{module_name=} is not a valid Python module name.") 29 | 30 | 31 | if __name__ == "__main__": 32 | main() 33 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | exclude: '.pixi/' 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v6.0.0 5 | hooks: 6 | - id: check-yaml 7 | - id: check-toml 8 | - id: end-of-file-fixer 9 | - id: trailing-whitespace 10 | 11 | - repo: local 12 | hooks: 13 | - id: ruff 14 | name: ruff-format 15 | stages: [pre-commit, pre-push] 16 | language: system 17 | entry: pixi run fmt 18 | types: [python] 19 | pass_filenames: false 20 | 21 | - id: ruff 22 | name: ruff-check 23 | stages: [pre-commit, pre-push] 24 | language: system 25 | entry: pixi run lint 26 | types: [python] 27 | pass_filenames: false 28 | 29 | - id: ty 30 | name: ty 31 | stages: [pre-commit, pre-push] 32 | language: system 33 | entry: pixi run types 34 | types: [python] 35 | pass_filenames: false 36 | 37 | - id: pytest 38 | name: pytest 39 | stages: [pre-commit, pre-push] 40 | language: system 41 | entry: pixi run test 42 | types: [python] 43 | pass_filenames: false 44 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | exclude: '.pixi/' 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v6.0.0 5 | hooks: 6 | - id: check-yaml 7 | - id: check-toml 8 | exclude: "{{cookiecutter.package_name}}/pyproject.toml" 9 | - id: end-of-file-fixer 10 | - id: trailing-whitespace 11 | 12 | - repo: local 13 | hooks: 14 | - id: ruff 15 | name: ruff-format 16 | stages: [pre-commit, pre-push] 17 | language: system 18 | entry: pixi run fmt 19 | types: [python] 20 | pass_filenames: false 21 | 22 | - id: ruff 23 | name: ruff-check 24 | stages: [pre-commit, pre-push] 25 | language: system 26 | entry: pixi run lint 27 | types: [python] 28 | pass_filenames: false 29 | 30 | - id: ty 31 | name: ty 32 | stages: [pre-commit, pre-push] 33 | language: system 34 | entry: pixi run types 35 | types: [python] 36 | pass_filenames: false 37 | 38 | - id: pytest 39 | name: pytest 40 | stages: [pre-commit, pre-push] 41 | language: system 42 | entry: pixi run test 43 | types: [python] 44 | pass_filenames: false 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jonathon Vandezande 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 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/licenses/MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) {year} {author_name} 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 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/README.md: -------------------------------------------------------------------------------- 1 | # {{cookiecutter.project_name}} 2 | 3 | {% if cookiecutter.license == "None" %}![License](https://img.shields.io/badge/license-None-black){% else %}[![License](https://img.shields.io/github/license/{{cookiecutter.github_username}}/{{cookiecutter.package_name}})]({{cookiecutter.project_url}}/blob/master/LICENSE){% endif %} 4 | [![Powered by: Pixi](https://img.shields.io/badge/Powered_by-Pixi-facc15)](https://pixi.sh) 5 | [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff) 6 | [![Typing: ty](https://img.shields.io/badge/typing-ty-EFC621.svg)](https://github.com/astral-sh/ty) 7 | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/{{cookiecutter.github_username}}/{{cookiecutter.package_name}}/test.yml?branch=master&logo=github-actions)]({{cookiecutter.project_url}}/actions/) 8 | [![Codecov](https://img.shields.io/codecov/c/github/{{cookiecutter.github_username}}/{{cookiecutter.package_name}})](https://codecov.io/gh/{{cookiecutter.github_username}}/{{cookiecutter.package_name}}) 9 | 10 | 11 | ## Credits 12 | This package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [jevandezande/pixi-cookiecutter](https://github.com/jevandezande/pixi-cookiecutter) project template. 13 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/licenses/BSD-3-clause: -------------------------------------------------------------------------------- 1 | Copyright {year} {author_name} 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test Pixi Cookiecutter 2 | 3 | on: 4 | pull_request: {} 5 | push: 6 | branches: master 7 | 8 | jobs: 9 | test: 10 | strategy: 11 | matrix: 12 | python-version: ['3.13', '3.14'] 13 | os: [ubuntu-latest] 14 | 15 | name: Python ${{ matrix.os }} ${{ matrix.python-version }} 16 | runs-on: ${{ matrix.os }} 17 | 18 | steps: 19 | - uses: actions/checkout@v5 20 | 21 | - uses: actions/setup-python@v6 22 | with: 23 | python-version: ${{ matrix.python-version }} 24 | 25 | - uses: prefix-dev/setup-pixi@v0.9.2 26 | with: 27 | pixi-version: v0.59.0 28 | cache: true 29 | environments: dev 30 | 31 | - run: pixi global install direnv 32 | 33 | - run: pixi run fmt 34 | - run: pixi run lint 35 | - run: pixi run types 36 | - run: pixi run test --cov --cov-report=xml 37 | 38 | - name: Upload Coverage to Codecov 39 | uses: codecov/codecov-action@v4 40 | env: 41 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 42 | 43 | 44 | - name: Configure git 45 | run: | 46 | git config --global user.email "default@example.com" 47 | git config --global user.name "Default Name" 48 | git config --global init.defaultBranch master 49 | 50 | - name: Run cookiecutter 51 | run: | 52 | pixi run cookiecutter . --no-input --config-file template_config.yml -o .. 53 | 54 | - name: Run pre-commit 55 | run: | 56 | cd ../pixi_project 57 | direnv allow . 58 | pixi run -e dev pre-commit run --all-files 59 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "pixi_cookiecutter" 3 | description = "Cookiecutter for setting up python projects with pixi that just work" 4 | license = "MIT" 5 | version = "0.1.0" 6 | readme = "README.md" 7 | keywords = ["cookiecutter", "pixi"] 8 | authors = [{name = "Jonathon Vandezande"}] 9 | requires-python = ">=3.12" 10 | 11 | [tool.pixi.workspace] 12 | channels = ["conda-forge"] 13 | platforms = ["linux-64", "osx-arm64"] 14 | 15 | [tool.pixi.dependencies] 16 | cookiecutter = ">=2.6" 17 | 18 | [tool.pixi.environments] 19 | default = { solve-group = "default" } 20 | dev = { features = ["dev"], solve-group = "default"} 21 | 22 | [tool.pixi.feature.dev.tasks] 23 | fmt = { cmd="ruff format hooks" } 24 | lint = { cmd="ruff check hooks --fix" } 25 | types = { cmd="ty check hooks" } 26 | test = { cmd="pytest" } 27 | all = { depends-on = ["fmt", "lint", "types", "test"] } 28 | 29 | [tool.pixi.feature.dev.dependencies] 30 | pytest = ">=8.3" 31 | pytest-cov = ">=6.0" 32 | ruff = ">=0.11" 33 | pre-commit = ">=4.2" 34 | 35 | [tool.pixi.feature.dev.pypi-dependencies] 36 | ty = "*" 37 | 38 | [tool.ruff] 39 | extend-exclude = ["\\{\\{cookiecutter.package_name\\}\\}"] 40 | line-length = 100 41 | 42 | [tool.ruff.lint] 43 | select = [ 44 | "B", # bugbear 45 | "D", # pydocstyle 46 | "E", # pycodestyle errors 47 | "F", # pyflakes 48 | "I", # isort 49 | "N", # pep8-naming conventions 50 | "W", # pycodestyle warnings 51 | "C4", # comprehensions 52 | "PL", # pylint 53 | "PT", # flake8-pytest-style 54 | "PIE", # misc lints 55 | "PYI", # flake8-pyi 56 | "TID", # tidy imports 57 | "TCH", # type-checking imports 58 | "RUF", # Ruff-specific rules 59 | "RSE", # flake8-raise 60 | "ICN001", # unconventional-import-alias 61 | ] 62 | ignore = [ 63 | "N806", # Non-lowercase variable in function 64 | "PLR0911", # Too many returns 65 | "PLR0912", # Too many branches 66 | "PLR0913", # Too many arguments to function call 67 | "PLR0914", # Too many locals 68 | "PLR0915", # Too many statements 69 | "PLR1702", # Too many nested-blocks 70 | ] 71 | 72 | [tool.ruff.lint.per-file-ignores] 73 | "__init__.py" = ["F401", "F403"] 74 | 75 | [tool.ruff.lint.pydocstyle] 76 | convention = "numpy" 77 | 78 | [tool.pytest.ini_options] 79 | testpaths = ["hooks"] 80 | addopts = "--doctest-modules" 81 | doctest_optionflags = "NORMALIZE_WHITESPACE" 82 | 83 | [build-system] 84 | build-backend = "hatchling.build" 85 | requires = ["hatchling"] 86 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "{{cookiecutter.package_name}}" 3 | description = "{{cookiecutter.project_name}}" 4 | {%- if cookiecutter.license != 'None' %} 5 | license = "{{cookiecutter.license}}" 6 | {%- endif %} 7 | version = "0.0.1" 8 | readme = "README.md" 9 | keywords = [] 10 | authors = [{name = "{{cookiecutter.author_name}}"}] 11 | requires-python = ">={python_version}" 12 | 13 | [tool.pixi.workspace] 14 | channels = ["conda-forge"] 15 | platforms = ["linux-64", "osx-arm64"] 16 | 17 | [tool.pixi.dependencies] 18 | {pixi_dependencies} 19 | 20 | [tool.pixi.pypi-dependencies] 21 | {{cookiecutter.package_name}} = { path = ".", editable = true } 22 | 23 | [tool.pixi.environments] 24 | default = { solve-group = "default" } 25 | dev = { features = ["dev"], solve-group = "default"} 26 | 27 | [tool.pixi.feature.dev.tasks] 28 | fmt = { cmd="ruff format ." } 29 | lint = { cmd="ruff check . --fix" } 30 | types = { cmd="ty check" } 31 | test = { cmd="pytest" } 32 | all = { depends-on = ["fmt", "lint", "types", "test"] } 33 | 34 | [tool.pixi.feature.dev.dependencies] 35 | pytest = ">=8.3" 36 | pytest-cov = ">=6.0" 37 | ruff = ">=0.11" 38 | pre-commit = ">=4.2" 39 | {pixi_test_dependencies} 40 | 41 | [tool.pixi.feature.dev.pypi-dependencies] 42 | ty = "*" 43 | 44 | [tool.ruff] 45 | line-length = {{cookiecutter.line_length}} 46 | 47 | [tool.ruff.lint] 48 | select = [ 49 | "B", # bugbear 50 | "D", # pydocstyle 51 | "E", # pycodestyle errors 52 | "F", # pyflakes 53 | "I", # isort 54 | "N", # pep8-naming conventions 55 | "W", # pycodestyle warnings 56 | "C4", # comprehensions 57 | "PL", # pylint 58 | "PT", # flake8-pytest-style 59 | "PIE", # misc lints 60 | "PYI", # flake8-pyi 61 | "TID", # tidy imports 62 | "TCH", # type-checking imports 63 | "RUF", # Ruff-specific rules 64 | "RSE", # flake8-raise 65 | "ICN001", # unconventional-import-alias 66 | ] 67 | ignore = [ 68 | "N806", # Non-lowercase variable in function 69 | "PLR0911", # Too many returns 70 | "PLR0912", # Too many branches 71 | "PLR0913", # Too many arguments to function call 72 | "PLR0914", # Too many locals 73 | "PLR0915", # Too many statements 74 | "PLR1702", # Too many nested-blocks 75 | ] 76 | 77 | [tool.ruff.lint.per-file-ignores] 78 | "__init__.py" = ["F401", "F403"] 79 | 80 | [tool.ruff.lint.pydocstyle] 81 | convention = "numpy" 82 | 83 | [tool.pytest.ini_options] 84 | testpaths = ["tests", "{{cookiecutter.package_name}}"] 85 | addopts = "--doctest-modules" 86 | doctest_optionflags = "NORMALIZE_WHITESPACE" 87 | 88 | [build-system] 89 | build-backend = "hatchling.build" 90 | requires = ["hatchling"] 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pixi Cookiecutter 2 | [![License](https://img.shields.io/github/license/jevandezande/pixi-cookiecutter)](https://github.com/jevandezande/pixi-cookiecutter/blob/master/LICENSE) 3 | [![Powered by: Pixi](https://img.shields.io/badge/powered_by-pixi-facc15)](https://pixi.sh) 4 | [![Code style: ruff](https://img.shields.io/badge/code_style-ruff-000000.svg)](https://github.com/astral-sh/ruff) 5 | [![Typing: ty](https://img.shields.io/badge/typing-ty-EFC621.svg)](https://github.com/astral-sh/ty) 6 | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/jevandezande/pixi-cookiecutter/test.yml?branch=master&logo=github-actions)](https://github.com/jevandezande/pixi-cookiecutter/actions/) 7 | [![Codecov](https://img.shields.io/codecov/c/github/jevandezande/pixi-cookiecutter)](https://app.codecov.io/github/jevandezande/pixi-cookiecutter) 8 | 9 | [Cookiecutter](https://github.com/audreyr/cookiecutter) for setting up [pixi](https://pixi.sh/) projects with all the necessary features for modern python development. 10 | 11 | ## Features 12 | - Packaging with [pixi](https://prefix.dev/) 13 | - Environment loading with [direnv](https://direnv.net/) 14 | - Formatting and linting with [ruff](https://github.com/charliermarsh/ruff) 15 | - Static typing with [ty](https://github.com/astral-sh/ty) 16 | - Testing with [pytest](https://docs.pytest.org/en/latest/) 17 | - Git hooks that run all the above with [pre-commit](https://pre-commit.com/) 18 | - Continuous integration with [GitHub Actions](https://github.com/features/actions) 19 | - Code coverage with [Codecov](https://docs.codecov.com/docs) 20 | 21 | 22 | ## Setup 23 | While all of the steps are automated, you will need to first install `pixi`, `cookiecutter`, and `direnv`, and optionally install the [GitHub-CLI](https://cli.github.com/). 24 | 25 | ```sh 26 | curl -fsSL https://pixi.sh/install.sh | bash 27 | pixi global install cookiecutter direnv 28 | 29 | # Optional 30 | curl -sS https://webi.sh/gh | sh 31 | ``` 32 | See [notes.md](notes.md#Project-Tools) for optional dependencies and [alternative installation methods](notes.md#Alternative-installation-methods). 33 | 34 | ```sh 35 | # Use cookiecutter to create a project from this template 36 | cookiecutter gh:jevandezande/pixi-cookiecutter 37 | ``` 38 | 39 | The cookiecutter will automagically 40 | - Generate a project with the input configuration 41 | - Initialize git 42 | - Setup environment 43 | - Setup pre-commit and pre-push hooks 44 | - Make initial commit 45 | - Sets up remote on GitHub (optional) 46 | 47 | 48 | ## Recommendations 49 | - Make a custom config file (see [template_config.yml](template_config.yml)). 50 | - Install [act](https://github.com/nektos/act) to run GitHub Actions locally. 51 | - Install [direnv](https://pixi.sh/latest/integration/third_party/direnv) to automagically load the environment. 52 | 53 | Read [notes](notes.md) for more tips. 54 | 55 | If you don't need packages from conda repositores, check out `uv` and the [uv-cookiecutter](https://github.com/jevandezande/uv-cookiecutter). 56 | -------------------------------------------------------------------------------- /notes.md: -------------------------------------------------------------------------------- 1 | # Notes 2 | ## Configuring Pixi 3 | 4 | If installing programs with pixi (recommended), make sure that `~/.pixi/bin` 5 | is in your path by adding the following to your .zshrc/.bashrc/.profile 6 | ```sh 7 | export PATH=$PATH:~/.pixi/bin 8 | ``` 9 | ### Installing pixi 10 | ```sh 11 | curl -fsSL https://pixi.sh/install.sh | bash 12 | ``` 13 | 14 | ## Cookiecutter 15 | While cookiecutter doesn't need to be installed globally if running the 16 | cookiecutter from within this project, it is needed if you want to run this 17 | cookiecutter without separately downloading it. 18 | 19 | ### Installing cookiecutter 20 | ```sh 21 | pixi global install cookiecutter 22 | ``` 23 | 24 | ## Configuring Pixi Cookiecutter 25 | Make a [config file](https://cookiecutter.readthedocs.io/en/stable/advanced/user_config.html) 26 | (see [template_config.yml](template_config.yml)) with default settings and save 27 | it as a `.cookiecutterrc` or use it directly via: `--config-file cookiecutter.yml` 28 | 29 | ## Adding project dependencies 30 | Dependencies can be specified in a list, with the @ operator to specify 31 | versions: `dep1@* dep2 dep3@version`. Dependencies that are not tagged to a 32 | specific version (e.g. `dep2`) will have a "\*" appended 33 | 34 | ## Project Tools 35 | ### Act 36 | [act](https://github.com/nektos/act) runs GitHub Actions locally in a docker 37 | container. This makes sure all tests are independent of system settings, and 38 | should replicate running these actions on GitHub. One can act as a variety of 39 | different GitHub actions: 40 | 41 | ```sh 42 | act push 43 | act pull_request 44 | act schedule 45 | ``` 46 | 47 | #### Installing act 48 | ```sh 49 | pixi global install act 50 | ``` 51 | 52 | ### Direnv 53 | [direnv](https://pixi.sh/latest/integration/third_party/direnv) can automagically load environment variables and the pixi shell. 54 | 55 | #### Installing direnv 56 | ```sh 57 | pixi global install direnv 58 | ``` 59 | 60 | Warning: if installed simultaneously from multiple sources, bad things can happen. 61 | 62 | Make sure that direnv is available in your shell by adding the following to your 63 | .zshrc/.bashrc/.profile (swap zsh for the name of your shell). 64 | ```sh 65 | eval "$(direnv hook zsh)" 66 | ``` 67 | 68 | ### GitHub-CLI 69 | [GitHub-CLI](https://cli.github.com/) can create a new repository on GitHub and 70 | provides many useful additional tools. My favorites: 71 | 72 | - [copilot](https://github.com/github/gh-copilot) - chat interface for questions about the command line 73 | - [dash](https://github.com/dlvhdr/gh-dash) - displays a dashboard with pull requests and issues 74 | - [gh-f](https://github.com/gennaro-tedesco/gh-f) - fuzzy finder for gh-cli 75 | - [gh-notify](https://github.com/meiji163/gh-notify) - shows your GitHub notifications 76 | - [markdown-preview](https://github.com/yusukebe/gh-markdown-preview) - renders markdown documents in your browser 77 | - [poi](https://github.com/seachicken/gh-poi) - safely cleans up old local branches 78 | 79 | #### Installing GitHub-CLI 80 | ```sh 81 | curl -sS https://webi.sh/gh | sh 82 | ``` 83 | 84 | ### Pre-commit 85 | [pre-commit](https://pre-commit.com/) runs formatting, linting, and other hooks 86 | on `git commit`. 87 | 88 | #### Installing pre-commit 89 | Pre-commit comes installed with the pixi package, but if you want to install it 90 | globally: 91 | ```sh 92 | pixi global install pre-commit 93 | ``` 94 | 95 | ### Alternative installation methods 96 | #### Act 97 | ```sh 98 | # Brew 99 | brew install act 100 | # GitHub-CLI 101 | gh extension install nektos/gh-act 102 | ``` 103 | 104 | #### Cookiecutter 105 | ```sh 106 | # Apt 107 | apt install cookiecutter 108 | # Brew 109 | brew install cookiecutter 110 | ``` 111 | 112 | #### Direnv 113 | ```sh 114 | # Apt 115 | apt install direnv 116 | # Brew 117 | brew install direnv 118 | ``` 119 | 120 | #### GitHub-CLI 121 | ```sh 122 | # Apt 123 | apt install gh 124 | # Brew 125 | brew install gh 126 | ``` 127 | 128 | #### Pre-commit 129 | ```sh 130 | # Apt 131 | apt install pre-commit 132 | # Brew 133 | brew install pre-commit 134 | ``` 135 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/python 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=python 3 | 4 | ### Python ### 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | cover/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | .pybuilder/ 80 | target/ 81 | 82 | # Jupyter Notebook 83 | .ipynb_checkpoints 84 | 85 | # IPython 86 | profile_default/ 87 | ipython_config.py 88 | 89 | # pyenv 90 | # For a library or package, you might want to ignore these files since the code is 91 | # intended to run in multiple environments; otherwise, check them in: 92 | # .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # poetry 102 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 103 | # This is especially recommended for binary packages to ensure reproducibility, and is more 104 | # commonly ignored for libraries. 105 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 106 | #poetry.lock 107 | 108 | # pdm 109 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 110 | #pdm.lock 111 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 112 | # in version control. 113 | # https://pdm.fming.dev/#use-with-ide 114 | .pdm.toml 115 | 116 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 117 | __pypackages__/ 118 | 119 | # Celery stuff 120 | celerybeat-schedule 121 | celerybeat.pid 122 | 123 | # SageMath parsed files 124 | *.sage.py 125 | 126 | # Environments 127 | .env 128 | .venv 129 | env/ 130 | venv/ 131 | ENV/ 132 | env.bak/ 133 | venv.bak/ 134 | 135 | # Spyder project settings 136 | .spyderproject 137 | .spyproject 138 | 139 | # Rope project settings 140 | .ropeproject 141 | 142 | # mkdocs documentation 143 | /site 144 | 145 | # mypy 146 | .mypy_cache/ 147 | .dmypy.json 148 | dmypy.json 149 | 150 | # Pyre type checker 151 | .pyre/ 152 | 153 | # pytype static type analyzer 154 | .pytype/ 155 | 156 | # Cython debug symbols 157 | cython_debug/ 158 | 159 | # PyCharm 160 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 161 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 162 | # and can be added to the global gitignore or merged into this file. For a more nuclear 163 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 164 | #.idea/ 165 | 166 | ### Python Patch ### 167 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration 168 | poetry.toml 169 | 170 | # ruff 171 | .ruff_cache/ 172 | 173 | # LSP config files 174 | pyrightconfig.json 175 | 176 | # End of https://www.toptal.com/developers/gitignore/api/python 177 | 178 | # Pixi 179 | .pixi 180 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/python 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=python 3 | 4 | ### Python ### 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | cover/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | .pybuilder/ 80 | target/ 81 | 82 | # Jupyter Notebook 83 | .ipynb_checkpoints 84 | 85 | # IPython 86 | profile_default/ 87 | ipython_config.py 88 | 89 | # pyenv 90 | # For a library or package, you might want to ignore these files since the code is 91 | # intended to run in multiple environments; otherwise, check them in: 92 | # .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # poetry 102 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 103 | # This is especially recommended for binary packages to ensure reproducibility, and is more 104 | # commonly ignored for libraries. 105 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 106 | #poetry.lock 107 | 108 | # pdm 109 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 110 | #pdm.lock 111 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 112 | # in version control. 113 | # https://pdm.fming.dev/#use-with-ide 114 | .pdm.toml 115 | 116 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 117 | __pypackages__/ 118 | 119 | # Celery stuff 120 | celerybeat-schedule 121 | celerybeat.pid 122 | 123 | # SageMath parsed files 124 | *.sage.py 125 | 126 | # Environments 127 | .env 128 | .venv 129 | env/ 130 | venv/ 131 | ENV/ 132 | env.bak/ 133 | venv.bak/ 134 | 135 | # Spyder project settings 136 | .spyderproject 137 | .spyproject 138 | 139 | # Rope project settings 140 | .ropeproject 141 | 142 | # mkdocs documentation 143 | /site 144 | 145 | # mypy 146 | .mypy_cache/ 147 | .dmypy.json 148 | dmypy.json 149 | 150 | # Pyre type checker 151 | .pyre/ 152 | 153 | # pytype static type analyzer 154 | .pytype/ 155 | 156 | # Cython debug symbols 157 | cython_debug/ 158 | 159 | # PyCharm 160 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 161 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 162 | # and can be added to the global gitignore or merged into this file. For a more nuclear 163 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 164 | #.idea/ 165 | 166 | ### Python Patch ### 167 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration 168 | poetry.toml 169 | 170 | # ruff 171 | .ruff_cache/ 172 | 173 | # LSP config files 174 | pyrightconfig.json 175 | 176 | # End of https://www.toptal.com/developers/gitignore/api/python 177 | 178 | # Pixi 179 | .pixi 180 | -------------------------------------------------------------------------------- /hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | """Hooks for setting up project once generated.""" 2 | 3 | import logging 4 | import shutil 5 | import subprocess 6 | import sys 7 | from datetime import datetime 8 | from pathlib import Path 9 | from shutil import rmtree 10 | from typing import Any, Literal 11 | 12 | logger = logging.Logger("post_gen_project_logger") 13 | logger.setLevel(logging.INFO) 14 | 15 | 16 | PROTOCOL = Literal["git", "https"] 17 | GITHUB_PRIVACY_OPTIONS = ["private", "internal", "public"] 18 | MINIMUM_PYTHON_MINOR_VERSION = 12 19 | 20 | 21 | def call(cmd: str, check: bool = True, **kwargs: Any) -> subprocess.CompletedProcess[bytes]: 22 | """ 23 | Call shell commands. 24 | 25 | :param cmd: command to call 26 | :param check: whether to raise an exception if the command fails 27 | :param kwargs: keyword arguments to pass to subprocess.call 28 | 29 | Warning: strings with spaces are not yet supported. 30 | """ 31 | logger.debug(f"Calling: {cmd}") 32 | return subprocess.run(cmd.split(), check=check, **kwargs) 33 | 34 | 35 | def set_python_version() -> None: 36 | """Set the python version in pyproject.toml and .github/workflows/test.yml.""" 37 | python_version = f"{sys.version_info.major}.{sys.version_info.minor}" 38 | logger.info(f"Settting {python_version=}") 39 | if sys.version_info.minor < MINIMUM_PYTHON_MINOR_VERSION: 40 | logger.warning( 41 | f"{python_version=} should be upgraded to the latest avaiable python version." 42 | ) 43 | 44 | file_names = [ 45 | ".github/workflows/test.yml", 46 | "pyproject.toml", 47 | ] 48 | 49 | for file_name in file_names: 50 | with open(file_name) as f: 51 | contents = f.read().replace("{python_version}", python_version) 52 | with open(file_name, "w") as f: 53 | f.write(contents) 54 | 55 | 56 | def set_license(license: str | None = "MIT") -> None: 57 | """ 58 | Copy the licese file to LICENSE (if any). 59 | 60 | :param license: name of the license (or None for no license) 61 | """ 62 | if not license or license == "None": 63 | logger.debug("No license set") 64 | return 65 | 66 | licenses = {lic.name for lic in Path("licenses").iterdir()} 67 | if license not in licenses: 68 | try: 69 | # Check and correct cases 70 | license = next(lic for lic in licenses if lic.lower() == license.lower()) 71 | logger.warning(f"Corrected license to {license=}") 72 | except StopIteration as e: 73 | raise ValueError(f"{license=} not available; select from:\n{licenses}") from e 74 | 75 | shutil.copy(f"licenses/{license}", "LICENSE") 76 | 77 | with open("LICENSE") as f: 78 | contents = f.read().replace("{year}", f"{datetime.now().year}") 79 | contents = contents.replace("{author_name}", "{{cookiecutter.author_name}}") 80 | with open("LICENSE", "w") as f: 81 | f.write(contents) 82 | 83 | logger.debug(f"Set {license=}") 84 | 85 | 86 | def remove_license_dir() -> None: 87 | """Remove the licenses directory.""" 88 | rmtree("licenses") 89 | 90 | 91 | def git_init() -> None: 92 | """Initialize a git repository.""" 93 | call("git init") 94 | 95 | 96 | def process_dependency(dependency: str) -> str: 97 | """ 98 | Process a dependency. 99 | 100 | :param dependency: dependency to process 101 | :return: processed dependency in the format 'package = "version"' 102 | 103 | >>> process_dependency("pytest") 104 | 'pytest = "*"' 105 | >>> process_dependency("matplotlib@>=3.7.2") 106 | 'matplotlib = ">=3.7.2"' 107 | >>> process_dependency("more-itertools@10.*") 108 | 'more-itertools = "10.*"' 109 | >>> process_dependency("") 110 | Traceback (most recent call last): 111 | ... 112 | ValueError: Blank dependency 113 | >>> process_dependency("hello@1.2.3@v40") 114 | Traceback (most recent call last): 115 | ... 116 | ValueError: Unable to process dependency='hello@1.2.3@v40' 117 | """ 118 | if not dependency: 119 | raise ValueError("Blank dependency") 120 | 121 | match dependency.split("@"): 122 | case [package]: 123 | return f'{package} = "*"' 124 | case [package, version]: 125 | return f'{package} = "{version}"' 126 | case _: 127 | raise ValueError(f"Unable to process {dependency=}") 128 | 129 | 130 | def process_dependencies(deps: str) -> str: 131 | r""" 132 | Process a space separated list of dependencies. 133 | 134 | :param deps: dependencies to process 135 | :return: processed dependencies in the format 'package = "version"' 136 | 137 | >>> process_dependencies(' ') 138 | '' 139 | >>> process_dependencies("pytest matplotlib@~3.7 black@!=1.2.3") 140 | 'pytest = "*"\nmatplotlib = "~3.7"\nblack = "!=1.2.3"\n' 141 | """ 142 | if not deps.strip(): 143 | return "" 144 | 145 | return "\n".join(map(process_dependency, deps.split())) + "\n" 146 | 147 | 148 | def update_dependencies() -> None: 149 | """Add and update the dependencies in pyproject.toml and pixi.lock.""" 150 | # Extra space and .strip() avoids accidentally creating '""""' 151 | dependencies = process_dependencies("""{{cookiecutter.pixi_dependencies}} """.strip()) 152 | dev_dependencies = process_dependencies("""{{cookiecutter.pixi_test_dependencies}} """.strip()) 153 | 154 | with open("pyproject.toml") as f: 155 | contents = ( 156 | f.read() 157 | .replace("{pixi_dependencies}\n", dependencies) 158 | .replace("{pixi_test_dependencies}\n", dev_dependencies) 159 | ) 160 | with open("pyproject.toml", "w") as f: 161 | f.write(contents) 162 | 163 | call("pixi update") 164 | 165 | 166 | def check_program(program: str, install_str: str) -> None: 167 | """ 168 | Check that a program is installed. 169 | 170 | :param program: name of the program to check 171 | :param install_str: string to print if the program is not installed 172 | 173 | >>> check_program("python", "https://www.python.org/") 174 | >>> check_program("this_program_does_not_exist", "nothing") 175 | Traceback (most recent call last): 176 | ... 177 | OSError: this_program_does_not_exist is not installed; install with `nothing` 178 | """ 179 | try: 180 | call(program, stdout=subprocess.DEVNULL) 181 | except FileNotFoundError as e: 182 | raise OSError(f"{program} is not installed; install with `{install_str}`") from e 183 | except subprocess.CalledProcessError as e: 184 | raise OSError(f"Issue with {program} encountered") from e 185 | 186 | 187 | def allow_direnv() -> None: 188 | """Allow direnv.""" 189 | check_program("direnv", "pixi global install direnv") 190 | call("direnv allow .") 191 | 192 | 193 | def git_hooks() -> None: 194 | """Install pre-commit and pre-push hooks.""" 195 | call("pixi run -e dev pre-commit install") 196 | 197 | 198 | def git_initial_commit() -> None: 199 | """Make the initial commit.""" 200 | call("git add .") 201 | call("git commit -m Setup") 202 | 203 | 204 | def setup_remote(remote: str = "origin") -> None: 205 | """ 206 | Add remote (and optionally setup GitHub). 207 | 208 | :param remote: name for the remote 209 | :raises ValueError: if the privacy option is not valid 210 | """ 211 | if "{{cookiecutter.github_setup}}" != "None": # type: ignore [comparison-overlap] # noqa: PLR0133 212 | github_setup("{{cookiecutter.github_setup}}", remote) 213 | else: 214 | git_add_remote(remote, "{{cookiecutter.project_url}}") 215 | 216 | 217 | def git_add_remote(remote: str, url: str, protocol: PROTOCOL = "git") -> None: 218 | """ 219 | Add a remote to the git repository. 220 | 221 | :param remote: name for the remote 222 | :param url: url of remote 223 | :param protocol: protocol of the remote ("git" or "https") 224 | """ 225 | if protocol == "git": 226 | _, _, hostname, path = url.split("/", 3) 227 | url = f"{protocol}@{hostname}:{path}" 228 | 229 | call(f"git remote add {remote} {url}") 230 | 231 | 232 | def github_setup(privacy: str, remote: str = "origin", default_branch: str = "master") -> None: 233 | """ 234 | Make a repository on GitHub (requires GitHub CLI). 235 | 236 | :param privacy: privacy of the repository ("private", "internal", "public") 237 | :param remote: name of the remote to add 238 | :param default_branch: name of the default branch for upstream 239 | """ 240 | if privacy not in GITHUB_PRIVACY_OPTIONS: 241 | raise ValueError(f"{privacy=} not in {GITHUB_PRIVACY_OPTIONS}") 242 | 243 | check_program("gh", "https://cli.github.com/") 244 | 245 | try: 246 | call( 247 | f"gh repo create {{cookiecutter.package_name}} --{privacy} --remote {remote} --source ." 248 | ) 249 | except subprocess.CalledProcessError as e: 250 | logger.error(f"Error creating GitHub repository, likely already exists: {e}") 251 | 252 | try: 253 | call(f"git config branch.{default_branch}.remote {remote}") 254 | call(f"git config branch.{default_branch}.merge refs/heads/{default_branch}") 255 | except subprocess.CalledProcessError as e: 256 | logger.error(f"Error setting upstream to {default_branch}: {e}") 257 | 258 | 259 | def notes() -> None: 260 | """Print notes for the user.""" 261 | print( 262 | """ 263 | If using GitHub, generate a CODECOV_TOKEN at: 264 | https://app.codecov.io/gh/{{cookiecutter.github_username}}/{{cookiecutter.package_name}}/settings 265 | and add it to the GitHub repository secrets as CODECOV_TOKEN at: 266 | https://github.com/{{cookiecutter.github_username}}/{{cookiecutter.package_name}}/settings/secrets/actions 267 | """ 268 | ) 269 | 270 | 271 | SUCCESS = "\x1b[1;32m" 272 | TERMINATOR = "\x1b[0m" 273 | 274 | 275 | def main() -> None: 276 | """Run the post generation hooks.""" 277 | set_python_version() 278 | set_license("{{cookiecutter.license}}") 279 | remove_license_dir() 280 | git_init() 281 | update_dependencies() 282 | allow_direnv() 283 | git_hooks() 284 | git_initial_commit() 285 | setup_remote("origin") 286 | 287 | notes() 288 | 289 | print(f"{SUCCESS}Project successfully initialized{TERMINATOR}") 290 | 291 | 292 | if __name__ == "__main__": 293 | main() 294 | -------------------------------------------------------------------------------- /{{cookiecutter.package_name}}/licenses/APL-2.0: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {year} {author_name} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /pixi.lock: -------------------------------------------------------------------------------- 1 | version: 6 2 | environments: 3 | default: 4 | channels: 5 | - url: https://conda.anaconda.org/conda-forge/ 6 | packages: 7 | linux-64: 8 | - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 9 | - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 10 | - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda 11 | - conda: https://conda.anaconda.org/conda-forge/noarch/binaryornot-0.4.4-pyhd8ed1ab_2.conda 12 | - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314hdfeb8a1_0.conda 13 | - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda 14 | - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda 15 | - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda 16 | - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda 17 | - conda: https://conda.anaconda.org/conda-forge/noarch/chardet-5.2.0-pyhd8ed1ab_3.conda 18 | - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda 19 | - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda 20 | - conda: https://conda.anaconda.org/conda-forge/noarch/cookiecutter-2.6.0-pyhd8ed1ab_1.conda 21 | - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda 22 | - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda 23 | - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda 24 | - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda 25 | - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda 26 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_4.conda 27 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda 28 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda 29 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda 30 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda 31 | - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda 32 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda 33 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda 34 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda 35 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda 36 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda 37 | - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda 38 | - conda: https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda 39 | - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda 40 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda 41 | - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.4-h26f9b46_0.conda 42 | - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda 43 | - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda 44 | - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda 45 | - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda 46 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda 47 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda 48 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda 49 | - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda 50 | - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda 51 | - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda 52 | - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda 53 | - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda 54 | - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda 55 | - conda: https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda 56 | - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda 57 | - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda 58 | - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda 59 | - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda 60 | - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda 61 | - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py314h31f8a6b_0.conda 62 | - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda 63 | osx-arm64: 64 | - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda 65 | - conda: https://conda.anaconda.org/conda-forge/noarch/binaryornot-0.4.4-pyhd8ed1ab_2.conda 66 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py314h95ef04c_0.conda 67 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda 68 | - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda 69 | - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda 70 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda 71 | - conda: https://conda.anaconda.org/conda-forge/noarch/chardet-5.2.0-pyhd8ed1ab_3.conda 72 | - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda 73 | - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda 74 | - conda: https://conda.anaconda.org/conda-forge/noarch/cookiecutter-2.6.0-pyhd8ed1ab_1.conda 75 | - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda 76 | - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda 77 | - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda 78 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda 79 | - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda 80 | - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda 81 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.4-hf598326_0.conda 82 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.1-hec049ff_0.conda 83 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda 84 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda 85 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda 86 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda 87 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda 88 | - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda 89 | - conda: https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda 90 | - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda 91 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda 92 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.4-h5503f6c_0.conda 93 | - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda 94 | - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda 95 | - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda 96 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.0-h40d2674_102_cp314.conda 97 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda 98 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda 99 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda 100 | - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda 101 | - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda 102 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda 103 | - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda 104 | - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda 105 | - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda 106 | - conda: https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda 107 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda 108 | - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda 109 | - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda 110 | - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda 111 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda 112 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.25.0-py314h163e31d_0.conda 113 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda 114 | dev: 115 | channels: 116 | - url: https://conda.anaconda.org/conda-forge/ 117 | indexes: 118 | - https://pypi.org/simple 119 | packages: 120 | linux-64: 121 | - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 122 | - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 123 | - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda 124 | - conda: https://conda.anaconda.org/conda-forge/noarch/binaryornot-0.4.4-pyhd8ed1ab_2.conda 125 | - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314hdfeb8a1_0.conda 126 | - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda 127 | - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda 128 | - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda 129 | - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda 130 | - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_1.conda 131 | - conda: https://conda.anaconda.org/conda-forge/noarch/chardet-5.2.0-pyhd8ed1ab_3.conda 132 | - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda 133 | - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda 134 | - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda 135 | - conda: https://conda.anaconda.org/conda-forge/noarch/cookiecutter-2.6.0-pyhd8ed1ab_1.conda 136 | - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.11.0-py314h67df5f8_0.conda 137 | - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda 138 | - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda 139 | - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda 140 | - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda 141 | - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda 142 | - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda 143 | - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.15-pyhd8ed1ab_0.conda 144 | - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda 145 | - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda 146 | - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda 147 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_4.conda 148 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda 149 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda 150 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda 151 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda 152 | - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda 153 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda 154 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda 155 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda 156 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda 157 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda 158 | - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda 159 | - conda: https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda 160 | - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda 161 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda 162 | - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda 163 | - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.4-h26f9b46_0.conda 164 | - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda 165 | - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda 166 | - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda 167 | - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.3.0-pyha770c72_0.conda 168 | - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda 169 | - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda 170 | - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda 171 | - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.2-pyhd8ed1ab_0.conda 172 | - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda 173 | - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda 174 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda 175 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda 176 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda 177 | - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda 178 | - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda 179 | - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda 180 | - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda 181 | - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda 182 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.14.2-ha3a3aed_0.conda 183 | - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda 184 | - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda 185 | - conda: https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda 186 | - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda 187 | - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda 188 | - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda 189 | - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda 190 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.0.1-py314h9891dd4_6.conda 191 | - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda 192 | - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda 193 | - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda 194 | - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py314h31f8a6b_0.conda 195 | - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda 196 | - pypi: https://files.pythonhosted.org/packages/57/d3/01ecc23bbd8f3e0dfbcf9172d06d84e88155c5f416f1491137e8066fd859/ty-0.0.1a25-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 197 | osx-arm64: 198 | - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda 199 | - conda: https://conda.anaconda.org/conda-forge/noarch/binaryornot-0.4.4-pyhd8ed1ab_2.conda 200 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py314h95ef04c_0.conda 201 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda 202 | - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda 203 | - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda 204 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda 205 | - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_1.conda 206 | - conda: https://conda.anaconda.org/conda-forge/noarch/chardet-5.2.0-pyhd8ed1ab_3.conda 207 | - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda 208 | - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda 209 | - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda 210 | - conda: https://conda.anaconda.org/conda-forge/noarch/cookiecutter-2.6.0-pyhd8ed1ab_1.conda 211 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.11.0-py314hb7e19f3_0.conda 212 | - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda 213 | - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda 214 | - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda 215 | - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda 216 | - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda 217 | - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda 218 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda 219 | - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.15-pyhd8ed1ab_0.conda 220 | - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda 221 | - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda 222 | - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda 223 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.4-hf598326_0.conda 224 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.1-hec049ff_0.conda 225 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda 226 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda 227 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda 228 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda 229 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda 230 | - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda 231 | - conda: https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda 232 | - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda 233 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda 234 | - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda 235 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.4-h5503f6c_0.conda 236 | - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda 237 | - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda 238 | - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda 239 | - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.3.0-pyha770c72_0.conda 240 | - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda 241 | - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda 242 | - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda 243 | - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.2-pyhd8ed1ab_0.conda 244 | - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda 245 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.0-h40d2674_102_cp314.conda 246 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda 247 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda 248 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda 249 | - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda 250 | - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda 251 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda 252 | - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda 253 | - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda 254 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.14.2-h492a034_0.conda 255 | - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda 256 | - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda 257 | - conda: https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda 258 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda 259 | - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda 260 | - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda 261 | - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda 262 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.0.1-py314h6b18a25_6.conda 263 | - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda 264 | - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda 265 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda 266 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.25.0-py314h163e31d_0.conda 267 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda 268 | - pypi: https://files.pythonhosted.org/packages/22/e8/5707939118992ced2bf5385adc3ede7723c1b717b07ad14c495eea1e47b4/ty-0.0.1a25-py3-none-macosx_11_0_arm64.whl 269 | packages: 270 | - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 271 | sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 272 | md5: d7c89558ba9fa0495403155b64376d81 273 | license: None 274 | purls: [] 275 | size: 2562 276 | timestamp: 1578324546067 277 | - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 278 | build_number: 16 279 | sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22 280 | md5: 73aaf86a425cc6e73fcf236a5a46396d 281 | depends: 282 | - _libgcc_mutex 0.1 conda_forge 283 | - libgomp >=7.5.0 284 | constrains: 285 | - openmp_impl 9999 286 | license: BSD-3-Clause 287 | license_family: BSD 288 | purls: [] 289 | size: 23621 290 | timestamp: 1650670423406 291 | - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda 292 | sha256: 792da8131b1b53ff667bd6fc617ea9087b570305ccb9913deb36b8e12b3b5141 293 | md5: 85c4f19f377424eafc4ed7911b291642 294 | depends: 295 | - python >=3.10 296 | - python-dateutil >=2.7.0 297 | - python-tzdata 298 | - python 299 | license: Apache-2.0 300 | license_family: APACHE 301 | purls: 302 | - pkg:pypi/arrow?source=compressed-mapping 303 | size: 113854 304 | timestamp: 1760831179410 305 | - conda: https://conda.anaconda.org/conda-forge/noarch/binaryornot-0.4.4-pyhd8ed1ab_2.conda 306 | sha256: 6cf60d0d5cbe76ee9db0196c6d428d74fd94231fcff046e5b3949c60645dce53 307 | md5: 67692f4269b341f88f80896ec835d1a9 308 | depends: 309 | - chardet 310 | - python >=3.9 311 | license: BSD-3-Clause 312 | license_family: BSD 313 | purls: 314 | - pkg:pypi/binaryornot?source=hash-mapping 315 | size: 12948 316 | timestamp: 1734071831765 317 | - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314hdfeb8a1_0.conda 318 | sha256: 9f6d339fb78b647be35e3564dac453d8d2f1b865ba72fb961eaac41061368699 319 | md5: 3ef9d2a701760467b9db2338b6cd926f 320 | depends: 321 | - __glibc >=2.17,<3.0.a0 322 | - libgcc >=14 323 | - libstdcxx >=14 324 | - python >=3.14,<3.15.0a0 325 | - python_abi 3.14.* *_cp314 326 | constrains: 327 | - libbrotlicommon 1.2.0 h09219d5_0 328 | license: MIT 329 | license_family: MIT 330 | purls: 331 | - pkg:pypi/brotli?source=hash-mapping 332 | size: 368319 333 | timestamp: 1761592337171 334 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py314h95ef04c_0.conda 335 | sha256: 231c3e2d0a2635f51e4e0fd56ba0def25b21a7c484d31e863f261823af5351e3 336 | md5: 5f71e1aa8d7982bda0a87b6bfd5c71fd 337 | depends: 338 | - __osx >=11.0 339 | - libcxx >=19 340 | - python >=3.14,<3.15.0a0 341 | - python >=3.14,<3.15.0a0 *_cp314 342 | - python_abi 3.14.* *_cp314 343 | constrains: 344 | - libbrotlicommon 1.2.0 h87ba0bc_0 345 | license: MIT 346 | license_family: MIT 347 | purls: 348 | - pkg:pypi/brotli?source=hash-mapping 349 | size: 359535 350 | timestamp: 1761592749203 351 | - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda 352 | sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 353 | md5: 51a19bba1b8ebfb60df25cde030b7ebc 354 | depends: 355 | - __glibc >=2.17,<3.0.a0 356 | - libgcc >=14 357 | license: bzip2-1.0.6 358 | license_family: BSD 359 | purls: [] 360 | size: 260341 361 | timestamp: 1757437258798 362 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda 363 | sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 364 | md5: 58fd217444c2a5701a44244faf518206 365 | depends: 366 | - __osx >=11.0 367 | license: bzip2-1.0.6 368 | license_family: BSD 369 | purls: [] 370 | size: 125061 371 | timestamp: 1757437486465 372 | - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda 373 | sha256: 3b5ad78b8bb61b6cdc0978a6a99f8dfb2cc789a451378d054698441005ecbdb6 374 | md5: f9e5fbc24009179e8b0409624691758a 375 | depends: 376 | - __unix 377 | license: ISC 378 | purls: [] 379 | size: 155907 380 | timestamp: 1759649036195 381 | - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda 382 | sha256: 955bac31be82592093f6bc006e09822cd13daf52b28643c9a6abd38cd5f4a306 383 | md5: 257ae203f1d204107ba389607d375ded 384 | depends: 385 | - python >=3.10 386 | license: ISC 387 | purls: 388 | - pkg:pypi/certifi?source=hash-mapping 389 | size: 160248 390 | timestamp: 1759648987029 391 | - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda 392 | sha256: c6339858a0aaf5d939e00d345c98b99e4558f285942b27232ac098ad17ac7f8e 393 | md5: cf45f4278afd6f4e6d03eda0f435d527 394 | depends: 395 | - __glibc >=2.17,<3.0.a0 396 | - libffi >=3.5.2,<3.6.0a0 397 | - libgcc >=14 398 | - pycparser 399 | - python >=3.14,<3.15.0a0 400 | - python_abi 3.14.* *_cp314 401 | license: MIT 402 | license_family: MIT 403 | purls: 404 | - pkg:pypi/cffi?source=hash-mapping 405 | size: 300271 406 | timestamp: 1761203085220 407 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda 408 | sha256: 5b5ee5de01eb4e4fd2576add5ec9edfc654fbaf9293e7b7ad2f893a67780aa98 409 | md5: 10dd19e4c797b8f8bdb1ec1fbb6821d7 410 | depends: 411 | - __osx >=11.0 412 | - libffi >=3.5.2,<3.6.0a0 413 | - pycparser 414 | - python >=3.14,<3.15.0a0 415 | - python >=3.14,<3.15.0a0 *_cp314 416 | - python_abi 3.14.* *_cp314 417 | license: MIT 418 | license_family: MIT 419 | purls: 420 | - pkg:pypi/cffi?source=hash-mapping 421 | size: 292983 422 | timestamp: 1761203354051 423 | - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_1.conda 424 | sha256: d5696636733b3c301054b948cdd793f118efacce361d9bd4afb57d5980a9064f 425 | md5: 57df494053e17dce2ac3a0b33e1b2a2e 426 | depends: 427 | - python >=3.9 428 | license: MIT 429 | license_family: MIT 430 | purls: 431 | - pkg:pypi/cfgv?source=hash-mapping 432 | size: 12973 433 | timestamp: 1734267180483 434 | - conda: https://conda.anaconda.org/conda-forge/noarch/chardet-5.2.0-pyhd8ed1ab_3.conda 435 | sha256: cfca3959d2bec9fcfec98350ecdd88b71dac6220d1002c257d65b40f6fbba87c 436 | md5: 56bfd153e523d9b9d05e4cf3c1cfe01c 437 | depends: 438 | - python >=3.9 439 | license: LGPL-2.1-only 440 | license_family: GPL 441 | purls: 442 | - pkg:pypi/chardet?source=hash-mapping 443 | size: 132170 444 | timestamp: 1741798023836 445 | - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda 446 | sha256: b32f8362e885f1b8417bac2b3da4db7323faa12d5db62b7fd6691c02d60d6f59 447 | md5: a22d1fd9bf98827e280a02875d9a007a 448 | depends: 449 | - python >=3.10 450 | license: MIT 451 | license_family: MIT 452 | purls: 453 | - pkg:pypi/charset-normalizer?source=hash-mapping 454 | size: 50965 455 | timestamp: 1760437331772 456 | - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda 457 | sha256: c6567ebc27c4c071a353acaf93eb82bb6d9a6961e40692a359045a89a61d02c0 458 | md5: e76c4ba9e1837847679421b8d549b784 459 | depends: 460 | - __unix 461 | - python >=3.10 462 | license: BSD-3-Clause 463 | license_family: BSD 464 | purls: 465 | - pkg:pypi/click?source=compressed-mapping 466 | size: 91622 467 | timestamp: 1758270534287 468 | - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda 469 | sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 470 | md5: 962b9857ee8e7018c22f2776ffa0b2d7 471 | depends: 472 | - python >=3.9 473 | license: BSD-3-Clause 474 | license_family: BSD 475 | purls: 476 | - pkg:pypi/colorama?source=hash-mapping 477 | size: 27011 478 | timestamp: 1733218222191 479 | - conda: https://conda.anaconda.org/conda-forge/noarch/cookiecutter-2.6.0-pyhd8ed1ab_1.conda 480 | sha256: 946b258512a9b8831240a6fe9450d66409d423d00d84d7e66d4eb76b2daca4f1 481 | md5: d18cb8ec1efa4cc38a0434bfa53e20d3 482 | depends: 483 | - arrow 484 | - binaryornot >=0.4.4 485 | - click >=7.0,<9.0.0 486 | - jinja2 >=2.7,<4.0.0 487 | - python >=3.9 488 | - python-slugify >=4.0.0 489 | - pyyaml >=5.3.1 490 | - requests >=2.23.0 491 | - rich 492 | license: BSD-3-Clause 493 | license_family: BSD 494 | purls: 495 | - pkg:pypi/cookiecutter?source=hash-mapping 496 | size: 99743 497 | timestamp: 1734069812077 498 | - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.11.0-py314h67df5f8_0.conda 499 | sha256: d928f6d0567807c8a09786e18966445b011ec2eb85c7e18382c0b4870cf12f17 500 | md5: 6ff84b39468623308dee97e5dfbafca0 501 | depends: 502 | - __glibc >=2.17,<3.0.a0 503 | - libgcc >=14 504 | - python >=3.14,<3.15.0a0 505 | - python_abi 3.14.* *_cp314 506 | - tomli 507 | license: Apache-2.0 508 | license_family: APACHE 509 | purls: 510 | - pkg:pypi/coverage?source=hash-mapping 511 | size: 402708 512 | timestamp: 1760545023449 513 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.11.0-py314hb7e19f3_0.conda 514 | sha256: c977b9e080860cf64d247aa07528f65d8d01c1ad51a23ac1c6ad7a3f5f2a34bc 515 | md5: a9d2395b30c275eb59b35292ec104233 516 | depends: 517 | - __osx >=11.0 518 | - python >=3.14,<3.15.0a0 519 | - python >=3.14,<3.15.0a0 *_cp314 520 | - python_abi 3.14.* *_cp314 521 | - tomli 522 | license: Apache-2.0 523 | license_family: APACHE 524 | purls: 525 | - pkg:pypi/coverage?source=hash-mapping 526 | size: 402944 527 | timestamp: 1760545272491 528 | - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda 529 | sha256: 6d977f0b2fc24fee21a9554389ab83070db341af6d6f09285360b2e09ef8b26e 530 | md5: 003b8ba0a94e2f1e117d0bd46aebc901 531 | depends: 532 | - python >=3.9 533 | license: Apache-2.0 534 | license_family: APACHE 535 | purls: 536 | - pkg:pypi/distlib?source=hash-mapping 537 | size: 275642 538 | timestamp: 1752823081585 539 | - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda 540 | sha256: ce61f4f99401a4bd455b89909153b40b9c823276aefcbb06f2044618696009ca 541 | md5: 72e42d28960d875c7654614f8b50939a 542 | depends: 543 | - python >=3.9 544 | - typing_extensions >=4.6.0 545 | license: MIT and PSF-2.0 546 | purls: 547 | - pkg:pypi/exceptiongroup?source=hash-mapping 548 | size: 21284 549 | timestamp: 1746947398083 550 | - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda 551 | sha256: 19025a4078ff3940d97eb0da29983d5e0deac9c3e09b0eabf897daeaf9d1114e 552 | md5: 66b8b26023b8efdf8fcb23bac4b6325d 553 | depends: 554 | - python >=3.10 555 | license: Unlicense 556 | purls: 557 | - pkg:pypi/filelock?source=hash-mapping 558 | size: 17976 559 | timestamp: 1759948208140 560 | - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda 561 | sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 562 | md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 563 | depends: 564 | - python >=3.10 565 | - hyperframe >=6.1,<7 566 | - hpack >=4.1,<5 567 | - python 568 | license: MIT 569 | license_family: MIT 570 | purls: 571 | - pkg:pypi/h2?source=compressed-mapping 572 | size: 95967 573 | timestamp: 1756364871835 574 | - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda 575 | sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba 576 | md5: 0a802cb9888dd14eeefc611f05c40b6e 577 | depends: 578 | - python >=3.9 579 | license: MIT 580 | license_family: MIT 581 | purls: 582 | - pkg:pypi/hpack?source=hash-mapping 583 | size: 30731 584 | timestamp: 1737618390337 585 | - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda 586 | sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 587 | md5: 8e6923fc12f1fe8f8c4e5c9f343256ac 588 | depends: 589 | - python >=3.9 590 | license: MIT 591 | license_family: MIT 592 | purls: 593 | - pkg:pypi/hyperframe?source=hash-mapping 594 | size: 17397 595 | timestamp: 1737618427549 596 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda 597 | sha256: 9ba12c93406f3df5ab0a43db8a4b4ef67a5871dfd401010fbe29b218b2cbe620 598 | md5: 5eb22c1d7b3fc4abb50d92d621583137 599 | depends: 600 | - __osx >=11.0 601 | license: MIT 602 | license_family: MIT 603 | purls: [] 604 | size: 11857802 605 | timestamp: 1720853997952 606 | - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.15-pyhd8ed1ab_0.conda 607 | sha256: 32d5007d12e5731867908cbf5345f5cd44a6c8755a2e8e63e15a184826a51f82 608 | md5: 25f954b7dae6dd7b0dc004dab74f1ce9 609 | depends: 610 | - python >=3.10 611 | - ukkonen 612 | license: MIT 613 | license_family: MIT 614 | purls: 615 | - pkg:pypi/identify?source=hash-mapping 616 | size: 79151 617 | timestamp: 1759437561529 618 | - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda 619 | sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 620 | md5: 53abe63df7e10a6ba605dc5f9f961d36 621 | depends: 622 | - python >=3.10 623 | license: BSD-3-Clause 624 | license_family: BSD 625 | purls: 626 | - pkg:pypi/idna?source=hash-mapping 627 | size: 50721 628 | timestamp: 1760286526795 629 | - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda 630 | sha256: e1a9e3b1c8fe62dc3932a616c284b5d8cbe3124bbfbedcf4ce5c828cb166ee19 631 | md5: 9614359868482abba1bd15ce465e3c42 632 | depends: 633 | - python >=3.10 634 | license: MIT 635 | license_family: MIT 636 | purls: 637 | - pkg:pypi/iniconfig?source=compressed-mapping 638 | size: 13387 639 | timestamp: 1760831448842 640 | - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda 641 | sha256: f1ac18b11637ddadc05642e8185a851c7fab5998c6f5470d716812fae943b2af 642 | md5: 446bd6c8cb26050d528881df495ce646 643 | depends: 644 | - markupsafe >=2.0 645 | - python >=3.9 646 | license: BSD-3-Clause 647 | license_family: BSD 648 | purls: 649 | - pkg:pypi/jinja2?source=hash-mapping 650 | size: 112714 651 | timestamp: 1741263433881 652 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_4.conda 653 | sha256: 96b6900ca0489d9e5d0318a6b49f8eff43fd85fef6e07cb0c25344ee94cd7a3a 654 | md5: c94ab6ff54ba5172cf1c58267005670f 655 | depends: 656 | - __glibc >=2.17,<3.0.a0 657 | - zstd >=1.5.7,<1.6.0a0 658 | constrains: 659 | - binutils_impl_linux-64 2.44 660 | license: GPL-3.0-only 661 | license_family: GPL 662 | purls: [] 663 | size: 742501 664 | timestamp: 1761335175964 665 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.4-hf598326_0.conda 666 | sha256: df55e80dda21f2581366f66cf18a6c11315d611f6fb01e56011c5199f983c0d9 667 | md5: 6002a2ba796f1387b6a5c6d77051d1db 668 | depends: 669 | - __osx >=11.0 670 | license: Apache-2.0 WITH LLVM-exception 671 | license_family: Apache 672 | purls: [] 673 | size: 567892 674 | timestamp: 1761043967532 675 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda 676 | sha256: da2080da8f0288b95dd86765c801c6e166c4619b910b11f9a8446fb852438dc2 677 | md5: 4211416ecba1866fab0c6470986c22d6 678 | depends: 679 | - __glibc >=2.17,<3.0.a0 680 | - libgcc >=14 681 | constrains: 682 | - expat 2.7.1.* 683 | license: MIT 684 | license_family: MIT 685 | purls: [] 686 | size: 74811 687 | timestamp: 1752719572741 688 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.1-hec049ff_0.conda 689 | sha256: 8fbb17a56f51e7113ed511c5787e0dec0d4b10ef9df921c4fd1cccca0458f648 690 | md5: b1ca5f21335782f71a8bd69bdc093f67 691 | depends: 692 | - __osx >=11.0 693 | constrains: 694 | - expat 2.7.1.* 695 | license: MIT 696 | license_family: MIT 697 | purls: [] 698 | size: 65971 699 | timestamp: 1752719657566 700 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda 701 | sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 702 | md5: 35f29eec58405aaf55e01cb470d8c26a 703 | depends: 704 | - __glibc >=2.17,<3.0.a0 705 | - libgcc >=14 706 | license: MIT 707 | license_family: MIT 708 | purls: [] 709 | size: 57821 710 | timestamp: 1760295480630 711 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda 712 | sha256: 9b8acdf42df61b7bfe8bdc545c016c29e61985e79748c64ad66df47dbc2e295f 713 | md5: 411ff7cd5d1472bba0f55c0faf04453b 714 | depends: 715 | - __osx >=11.0 716 | license: MIT 717 | license_family: MIT 718 | purls: [] 719 | size: 40251 720 | timestamp: 1760295839166 721 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda 722 | sha256: 08f9b87578ab981c7713e4e6a7d935e40766e10691732bba376d4964562bcb45 723 | md5: c0374badb3a5d4b1372db28d19462c53 724 | depends: 725 | - __glibc >=2.17,<3.0.a0 726 | - _openmp_mutex >=4.5 727 | constrains: 728 | - libgomp 15.2.0 h767d61c_7 729 | - libgcc-ng ==15.2.0=*_7 730 | license: GPL-3.0-only WITH GCC-exception-3.1 731 | license_family: GPL 732 | purls: [] 733 | size: 822552 734 | timestamp: 1759968052178 735 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda 736 | sha256: e9fb1c258c8e66ee278397b5822692527c5f5786d372fe7a869b900853f3f5ca 737 | md5: f7b4d76975aac7e5d9e6ad13845f92fe 738 | depends: 739 | - __glibc >=2.17,<3.0.a0 740 | license: GPL-3.0-only WITH GCC-exception-3.1 741 | license_family: GPL 742 | purls: [] 743 | size: 447919 744 | timestamp: 1759967942498 745 | - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda 746 | sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 747 | md5: 1a580f7796c7bf6393fddb8bbbde58dc 748 | depends: 749 | - __glibc >=2.17,<3.0.a0 750 | - libgcc >=13 751 | constrains: 752 | - xz 5.8.1.* 753 | license: 0BSD 754 | purls: [] 755 | size: 112894 756 | timestamp: 1749230047870 757 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda 758 | sha256: 0cb92a9e026e7bd4842f410a5c5c665c89b2eb97794ffddba519a626b8ce7285 759 | md5: d6df911d4564d77c4374b02552cb17d1 760 | depends: 761 | - __osx >=11.0 762 | constrains: 763 | - xz 5.8.1.* 764 | license: 0BSD 765 | purls: [] 766 | size: 92286 767 | timestamp: 1749230283517 768 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda 769 | sha256: 3aa92d4074d4063f2a162cd8ecb45dccac93e543e565c01a787e16a43501f7ee 770 | md5: c7e925f37e3b40d893459e625f6a53f1 771 | depends: 772 | - __glibc >=2.17,<3.0.a0 773 | - libgcc >=13 774 | license: BSD-2-Clause 775 | license_family: BSD 776 | purls: [] 777 | size: 91183 778 | timestamp: 1748393666725 779 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda 780 | sha256: 0a1875fc1642324ebd6c4ac864604f3f18f57fbcf558a8264f6ced028a3c75b2 781 | md5: 85ccccb47823dd9f7a99d2c7f530342f 782 | depends: 783 | - __osx >=11.0 784 | license: BSD-2-Clause 785 | license_family: BSD 786 | purls: [] 787 | size: 71829 788 | timestamp: 1748393749336 789 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda 790 | sha256: 6d9c32fc369af5a84875725f7ddfbfc2ace795c28f246dc70055a79f9b2003da 791 | md5: 0b367fad34931cb79e0d6b7e5c06bb1c 792 | depends: 793 | - __glibc >=2.17,<3.0.a0 794 | - libgcc >=14 795 | - libzlib >=1.3.1,<2.0a0 796 | license: blessing 797 | purls: [] 798 | size: 932581 799 | timestamp: 1753948484112 800 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda 801 | sha256: 802ebe62e6bc59fc26b26276b793e0542cfff2d03c086440aeaf72fb8bbcec44 802 | md5: 1dcb0468f5146e38fae99aef9656034b 803 | depends: 804 | - __osx >=11.0 805 | - icu >=75.1,<76.0a0 806 | - libzlib >=1.3.1,<2.0a0 807 | license: blessing 808 | purls: [] 809 | size: 902645 810 | timestamp: 1753948599139 811 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda 812 | sha256: 1b981647d9775e1cdeb2fab0a4dd9cd75a6b0de2963f6c3953dbd712f78334b3 813 | md5: 5b767048b1b3ee9a954b06f4084f93dc 814 | depends: 815 | - __glibc >=2.17,<3.0.a0 816 | - libgcc 15.2.0 h767d61c_7 817 | constrains: 818 | - libstdcxx-ng ==15.2.0=*_7 819 | license: GPL-3.0-only WITH GCC-exception-3.1 820 | license_family: GPL 821 | purls: [] 822 | size: 3898269 823 | timestamp: 1759968103436 824 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda 825 | sha256: e5ec6d2ad7eef538ddcb9ea62ad4346fde70a4736342c4ad87bd713641eb9808 826 | md5: 80c07c68d2f6870250959dcc95b209d1 827 | depends: 828 | - __glibc >=2.17,<3.0.a0 829 | - libgcc >=14 830 | license: BSD-3-Clause 831 | license_family: BSD 832 | purls: [] 833 | size: 37135 834 | timestamp: 1758626800002 835 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda 836 | sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 837 | md5: edb0dca6bc32e4f4789199455a1dbeb8 838 | depends: 839 | - __glibc >=2.17,<3.0.a0 840 | - libgcc >=13 841 | constrains: 842 | - zlib 1.3.1 *_2 843 | license: Zlib 844 | license_family: Other 845 | purls: [] 846 | size: 60963 847 | timestamp: 1727963148474 848 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda 849 | sha256: ce34669eadaba351cd54910743e6a2261b67009624dbc7daeeafdef93616711b 850 | md5: 369964e85dc26bfe78f41399b366c435 851 | depends: 852 | - __osx >=11.0 853 | constrains: 854 | - zlib 1.3.1 *_2 855 | license: Zlib 856 | license_family: Other 857 | purls: [] 858 | size: 46438 859 | timestamp: 1727963202283 860 | - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda 861 | sha256: 7b1da4b5c40385791dbc3cc85ceea9fad5da680a27d5d3cb8bfaa185e304a89e 862 | md5: 5b5203189eb668f042ac2b0826244964 863 | depends: 864 | - mdurl >=0.1,<1 865 | - python >=3.10 866 | license: MIT 867 | license_family: MIT 868 | purls: 869 | - pkg:pypi/markdown-it-py?source=hash-mapping 870 | size: 64736 871 | timestamp: 1754951288511 872 | - conda: https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda 873 | sha256: e0cbfea51a19b3055ca19428bd9233a25adca956c208abb9d00b21e7259c7e03 874 | md5: fab1be106a50e20f10fe5228fd1d1651 875 | depends: 876 | - python >=3.10 877 | constrains: 878 | - jinja2 >=3.0.0 879 | track_features: 880 | - markupsafe_no_compile 881 | license: BSD-3-Clause 882 | license_family: BSD 883 | purls: 884 | - pkg:pypi/markupsafe?source=hash-mapping 885 | size: 15499 886 | timestamp: 1759055275624 887 | - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda 888 | sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 889 | md5: 592132998493b3ff25fd7479396e8351 890 | depends: 891 | - python >=3.9 892 | license: MIT 893 | license_family: MIT 894 | purls: 895 | - pkg:pypi/mdurl?source=hash-mapping 896 | size: 14465 897 | timestamp: 1733255681319 898 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda 899 | sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 900 | md5: 47e340acb35de30501a76c7c799c41d7 901 | depends: 902 | - __glibc >=2.17,<3.0.a0 903 | - libgcc >=13 904 | license: X11 AND BSD-3-Clause 905 | purls: [] 906 | size: 891641 907 | timestamp: 1738195959188 908 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda 909 | sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 910 | md5: 068d497125e4bf8a66bf707254fff5ae 911 | depends: 912 | - __osx >=11.0 913 | license: X11 AND BSD-3-Clause 914 | purls: [] 915 | size: 797030 916 | timestamp: 1738196177597 917 | - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda 918 | sha256: 3636eec0e60466a00069b47ce94b6d88b01419b6577d8e393da44bb5bc8d3468 919 | md5: 7ba3f09fceae6a120d664217e58fe686 920 | depends: 921 | - python >=3.9 922 | - setuptools 923 | license: BSD-3-Clause 924 | license_family: BSD 925 | purls: 926 | - pkg:pypi/nodeenv?source=hash-mapping 927 | size: 34574 928 | timestamp: 1734112236147 929 | - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.4-h26f9b46_0.conda 930 | sha256: e807f3bad09bdf4075dbb4168619e14b0c0360bacb2e12ef18641a834c8c5549 931 | md5: 14edad12b59ccbfa3910d42c72adc2a0 932 | depends: 933 | - __glibc >=2.17,<3.0.a0 934 | - ca-certificates 935 | - libgcc >=14 936 | license: Apache-2.0 937 | license_family: Apache 938 | purls: [] 939 | size: 3119624 940 | timestamp: 1759324353651 941 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.4-h5503f6c_0.conda 942 | sha256: f0512629f9589392c2fb9733d11e753d0eab8fc7602f96e4d7f3bd95c783eb07 943 | md5: 71118318f37f717eefe55841adb172fd 944 | depends: 945 | - __osx >=11.0 946 | - ca-certificates 947 | license: Apache-2.0 948 | license_family: Apache 949 | purls: [] 950 | size: 3067808 951 | timestamp: 1759324763146 952 | - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda 953 | sha256: 289861ed0c13a15d7bbb408796af4de72c2fe67e2bcb0de98f4c3fce259d7991 954 | md5: 58335b26c38bf4a20f399384c33cbcf9 955 | depends: 956 | - python >=3.8 957 | - python 958 | license: Apache-2.0 959 | license_family: APACHE 960 | purls: 961 | - pkg:pypi/packaging?source=hash-mapping 962 | size: 62477 963 | timestamp: 1745345660407 964 | - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda 965 | sha256: 7efd51b48d908de2d75cbb3c4a2e80dd9454e1c5bb8191b261af3136f7fa5888 966 | md5: 5c7a868f8241e64e1cf5fdf4962f23e2 967 | depends: 968 | - python >=3.10 969 | - python 970 | license: MIT 971 | license_family: MIT 972 | purls: 973 | - pkg:pypi/platformdirs?source=hash-mapping 974 | size: 23625 975 | timestamp: 1759953252315 976 | - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda 977 | sha256: a8eb555eef5063bbb7ba06a379fa7ea714f57d9741fe0efdb9442dbbc2cccbcc 978 | md5: 7da7ccd349dbf6487a7778579d2bb971 979 | depends: 980 | - python >=3.9 981 | license: MIT 982 | license_family: MIT 983 | purls: 984 | - pkg:pypi/pluggy?source=hash-mapping 985 | size: 24246 986 | timestamp: 1747339794916 987 | - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.3.0-pyha770c72_0.conda 988 | sha256: 66b6d429ab2201abaa7282af06b17f7631dcaafbc5aff112922b48544514b80a 989 | md5: bc6c44af2a9e6067dd7e949ef10cdfba 990 | depends: 991 | - cfgv >=2.0.0 992 | - identify >=1.0.0 993 | - nodeenv >=0.11.1 994 | - python >=3.9 995 | - pyyaml >=5.1 996 | - virtualenv >=20.10.0 997 | license: MIT 998 | license_family: MIT 999 | purls: 1000 | - pkg:pypi/pre-commit?source=hash-mapping 1001 | size: 195839 1002 | timestamp: 1754831350570 1003 | - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda 1004 | sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6 1005 | md5: 12c566707c80111f9799308d9e265aef 1006 | depends: 1007 | - python >=3.9 1008 | - python 1009 | license: BSD-3-Clause 1010 | license_family: BSD 1011 | purls: 1012 | - pkg:pypi/pycparser?source=hash-mapping 1013 | size: 110100 1014 | timestamp: 1733195786147 1015 | - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda 1016 | sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a 1017 | md5: 6b6ece66ebcae2d5f326c77ef2c5a066 1018 | depends: 1019 | - python >=3.9 1020 | license: BSD-2-Clause 1021 | license_family: BSD 1022 | purls: 1023 | - pkg:pypi/pygments?source=hash-mapping 1024 | size: 889287 1025 | timestamp: 1750615908735 1026 | - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda 1027 | sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 1028 | md5: 461219d1a5bd61342293efa2c0c90eac 1029 | depends: 1030 | - __unix 1031 | - python >=3.9 1032 | license: BSD-3-Clause 1033 | license_family: BSD 1034 | purls: 1035 | - pkg:pypi/pysocks?source=hash-mapping 1036 | size: 21085 1037 | timestamp: 1733217331982 1038 | - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.2-pyhd8ed1ab_0.conda 1039 | sha256: 41053d9893e379a3133bb9b557b98a3d2142fca474fb6b964ba5d97515f78e2d 1040 | md5: 1f987505580cb972cf28dc5f74a0f81b 1041 | depends: 1042 | - colorama >=0.4 1043 | - exceptiongroup >=1 1044 | - iniconfig >=1 1045 | - packaging >=20 1046 | - pluggy >=1.5,<2 1047 | - pygments >=2.7.2 1048 | - python >=3.10 1049 | - tomli >=1 1050 | constrains: 1051 | - pytest-faulthandler >=2 1052 | license: MIT 1053 | license_family: MIT 1054 | purls: 1055 | - pkg:pypi/pytest?source=hash-mapping 1056 | size: 276734 1057 | timestamp: 1757011891753 1058 | - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-7.0.0-pyhcf101f3_1.conda 1059 | sha256: d0f45586aad48ef604590188c33c83d76e4fc6370ac569ba0900906b24fd6a26 1060 | md5: 6891acad5e136cb62a8c2ed2679d6528 1061 | depends: 1062 | - coverage >=7.10.6 1063 | - pluggy >=1.2 1064 | - pytest >=7 1065 | - python >=3.10 1066 | - python 1067 | license: MIT 1068 | license_family: MIT 1069 | purls: 1070 | - pkg:pypi/pytest-cov?source=hash-mapping 1071 | size: 29016 1072 | timestamp: 1757612051022 1073 | - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda 1074 | build_number: 102 1075 | sha256: 76d750045b94fded676323bfd01975a26a474023635735773d0e4d80aaa72518 1076 | md5: 0a19d2cc6eb15881889b0c6fa7d6a78d 1077 | depends: 1078 | - __glibc >=2.17,<3.0.a0 1079 | - bzip2 >=1.0.8,<2.0a0 1080 | - ld_impl_linux-64 >=2.36.1 1081 | - libexpat >=2.7.1,<3.0a0 1082 | - libffi >=3.5.2,<3.6.0a0 1083 | - libgcc >=14 1084 | - liblzma >=5.8.1,<6.0a0 1085 | - libmpdec >=4.0.0,<5.0a0 1086 | - libsqlite >=3.50.4,<4.0a0 1087 | - libuuid >=2.41.2,<3.0a0 1088 | - libzlib >=1.3.1,<2.0a0 1089 | - ncurses >=6.5,<7.0a0 1090 | - openssl >=3.5.4,<4.0a0 1091 | - python_abi 3.14.* *_cp314 1092 | - readline >=8.2,<9.0a0 1093 | - tk >=8.6.13,<8.7.0a0 1094 | - tzdata 1095 | - zstd >=1.5.7,<1.6.0a0 1096 | license: Python-2.0 1097 | purls: [] 1098 | size: 36681389 1099 | timestamp: 1761176838143 1100 | python_site_packages_path: lib/python3.14/site-packages 1101 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.0-h40d2674_102_cp314.conda 1102 | build_number: 102 1103 | sha256: 3ca1da026fe5df8a479d60e1d3ed02d9bc50fcbafd5f125d86abe70d21a34cc7 1104 | md5: a9ff09231c555da7e30777747318321b 1105 | depends: 1106 | - __osx >=11.0 1107 | - bzip2 >=1.0.8,<2.0a0 1108 | - libexpat >=2.7.1,<3.0a0 1109 | - libffi >=3.5.2,<3.6.0a0 1110 | - liblzma >=5.8.1,<6.0a0 1111 | - libmpdec >=4.0.0,<5.0a0 1112 | - libsqlite >=3.50.4,<4.0a0 1113 | - libzlib >=1.3.1,<2.0a0 1114 | - ncurses >=6.5,<7.0a0 1115 | - openssl >=3.5.4,<4.0a0 1116 | - python_abi 3.14.* *_cp314 1117 | - readline >=8.2,<9.0a0 1118 | - tk >=8.6.13,<8.7.0a0 1119 | - tzdata 1120 | - zstd >=1.5.7,<1.6.0a0 1121 | license: Python-2.0 1122 | purls: [] 1123 | size: 13590581 1124 | timestamp: 1761177195716 1125 | python_site_packages_path: lib/python3.14/site-packages 1126 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda 1127 | sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 1128 | md5: 5b8d21249ff20967101ffa321cab24e8 1129 | depends: 1130 | - python >=3.9 1131 | - six >=1.5 1132 | - python 1133 | license: Apache-2.0 1134 | license_family: APACHE 1135 | purls: 1136 | - pkg:pypi/python-dateutil?source=hash-mapping 1137 | size: 233310 1138 | timestamp: 1751104122689 1139 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda 1140 | sha256: a84f270426ae7661f79807b107dedb9829c79bd45f77a3033aa021e10556e87f 1141 | md5: a4059bc12930bddeb41aef71537ffaed 1142 | depends: 1143 | - python >=3.9 1144 | - text-unidecode >=1.3 1145 | constrains: 1146 | - slugify <0 1147 | - unidecode >=1.1.1 1148 | - awesome-slugify <0 1149 | license: MIT 1150 | license_family: MIT 1151 | purls: 1152 | - pkg:pypi/python-slugify?source=hash-mapping 1153 | size: 18991 1154 | timestamp: 1733756348165 1155 | - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda 1156 | sha256: e8392a8044d56ad017c08fec2b0eb10ae3d1235ac967d0aab8bd7b41c4a5eaf0 1157 | md5: 88476ae6ebd24f39261e0854ac244f33 1158 | depends: 1159 | - python >=3.9 1160 | license: Apache-2.0 1161 | license_family: APACHE 1162 | purls: 1163 | - pkg:pypi/tzdata?source=hash-mapping 1164 | size: 144160 1165 | timestamp: 1742745254292 1166 | - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda 1167 | build_number: 8 1168 | sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 1169 | md5: 0539938c55b6b1a59b560e843ad864a4 1170 | constrains: 1171 | - python 3.14.* *_cp314 1172 | license: BSD-3-Clause 1173 | license_family: BSD 1174 | purls: [] 1175 | size: 6989 1176 | timestamp: 1752805904792 1177 | - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-6.0.3-pyh7db6752_0.conda 1178 | sha256: 828af2fd7bb66afc9ab1c564c2046be391aaf66c0215f05afaf6d7a9a270fe2a 1179 | md5: b12f41c0d7fb5ab81709fcc86579688f 1180 | depends: 1181 | - python >=3.10.* 1182 | - yaml 1183 | track_features: 1184 | - pyyaml_no_compile 1185 | license: MIT 1186 | license_family: MIT 1187 | purls: 1188 | - pkg:pypi/pyyaml?source=hash-mapping 1189 | size: 45223 1190 | timestamp: 1758891992558 1191 | - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda 1192 | sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c 1193 | md5: 283b96675859b20a825f8fa30f311446 1194 | depends: 1195 | - libgcc >=13 1196 | - ncurses >=6.5,<7.0a0 1197 | license: GPL-3.0-only 1198 | license_family: GPL 1199 | purls: [] 1200 | size: 282480 1201 | timestamp: 1740379431762 1202 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda 1203 | sha256: 7db04684d3904f6151eff8673270922d31da1eea7fa73254d01c437f49702e34 1204 | md5: 63ef3f6e6d6d5c589e64f11263dc5676 1205 | depends: 1206 | - ncurses >=6.5,<7.0a0 1207 | license: GPL-3.0-only 1208 | license_family: GPL 1209 | purls: [] 1210 | size: 252359 1211 | timestamp: 1740379663071 1212 | - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda 1213 | sha256: 8dc54e94721e9ab545d7234aa5192b74102263d3e704e6d0c8aa7008f2da2a7b 1214 | md5: db0c6b99149880c8ba515cf4abe93ee4 1215 | depends: 1216 | - certifi >=2017.4.17 1217 | - charset-normalizer >=2,<4 1218 | - idna >=2.5,<4 1219 | - python >=3.9 1220 | - urllib3 >=1.21.1,<3 1221 | constrains: 1222 | - chardet >=3.0.2,<6 1223 | license: Apache-2.0 1224 | license_family: APACHE 1225 | purls: 1226 | - pkg:pypi/requests?source=hash-mapping 1227 | size: 59263 1228 | timestamp: 1755614348400 1229 | - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.2.0-pyhcf101f3_0.conda 1230 | sha256: edfb44d0b6468a8dfced728534c755101f06f1a9870a7ad329ec51389f16b086 1231 | md5: a247579d8a59931091b16a1e932bbed6 1232 | depends: 1233 | - markdown-it-py >=2.2.0 1234 | - pygments >=2.13.0,<3.0.0 1235 | - python >=3.10 1236 | - typing_extensions >=4.0.0,<5.0.0 1237 | - python 1238 | license: MIT 1239 | license_family: MIT 1240 | purls: 1241 | - pkg:pypi/rich?source=compressed-mapping 1242 | size: 200840 1243 | timestamp: 1760026188268 1244 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.14.2-ha3a3aed_0.conda 1245 | noarch: python 1246 | sha256: d6c3ee6381ce275107a3fb3cfe82499f3cb74da1d95e134a93ed5e4851b4ec01 1247 | md5: ba27344e81c9c460c9502fcbf7bd1e5c 1248 | depends: 1249 | - python 1250 | - __glibc >=2.17,<3.0.a0 1251 | - libgcc >=14 1252 | constrains: 1253 | - __glibc >=2.17 1254 | license: MIT 1255 | license_family: MIT 1256 | purls: 1257 | - pkg:pypi/ruff?source=compressed-mapping 1258 | size: 11071649 1259 | timestamp: 1761253375744 1260 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.14.2-h492a034_0.conda 1261 | noarch: python 1262 | sha256: 34fef6ff3447a243abd7ca98a95f6199af7a38aeb182c7d5d93a7e8681530571 1263 | md5: 22bcd3c3680cd6dcefe9bc73612a7132 1264 | depends: 1265 | - python 1266 | - __osx >=11.0 1267 | constrains: 1268 | - __osx >=11.0 1269 | license: MIT 1270 | license_family: MIT 1271 | purls: 1272 | - pkg:pypi/ruff?source=hash-mapping 1273 | size: 10033698 1274 | timestamp: 1761253464229 1275 | - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda 1276 | sha256: 972560fcf9657058e3e1f97186cc94389144b46dbdf58c807ce62e83f977e863 1277 | md5: 4de79c071274a53dcaf2a8c749d1499e 1278 | depends: 1279 | - python >=3.9 1280 | license: MIT 1281 | license_family: MIT 1282 | purls: 1283 | - pkg:pypi/setuptools?source=hash-mapping 1284 | size: 748788 1285 | timestamp: 1748804951958 1286 | - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda 1287 | sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d 1288 | md5: 3339e3b65d58accf4ca4fb8748ab16b3 1289 | depends: 1290 | - python >=3.9 1291 | - python 1292 | license: MIT 1293 | license_family: MIT 1294 | purls: 1295 | - pkg:pypi/six?source=hash-mapping 1296 | size: 18455 1297 | timestamp: 1753199211006 1298 | - conda: https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda 1299 | sha256: 4770807cc5a217638c9aea3f05ea55718a82c50f32462df196b5472aff02787f 1300 | md5: 23b4ba5619c4752976eb7ba1f5acb7e8 1301 | depends: 1302 | - python >=3.9 1303 | license: Artistic-1.0-Perl 1304 | license_family: OTHER 1305 | purls: 1306 | - pkg:pypi/text-unidecode?source=hash-mapping 1307 | size: 65532 1308 | timestamp: 1733750024391 1309 | - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda 1310 | sha256: a84ff687119e6d8752346d1d408d5cf360dee0badd487a472aa8ddedfdc219e1 1311 | md5: a0116df4f4ed05c303811a837d5b39d8 1312 | depends: 1313 | - __glibc >=2.17,<3.0.a0 1314 | - libgcc >=13 1315 | - libzlib >=1.3.1,<2.0a0 1316 | license: TCL 1317 | license_family: BSD 1318 | purls: [] 1319 | size: 3285204 1320 | timestamp: 1748387766691 1321 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda 1322 | sha256: cb86c522576fa95c6db4c878849af0bccfd3264daf0cc40dd18e7f4a7bfced0e 1323 | md5: 7362396c170252e7b7b0c8fb37fe9c78 1324 | depends: 1325 | - __osx >=11.0 1326 | - libzlib >=1.3.1,<2.0a0 1327 | license: TCL 1328 | license_family: BSD 1329 | purls: [] 1330 | size: 3125538 1331 | timestamp: 1748388189063 1332 | - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda 1333 | sha256: cb77c660b646c00a48ef942a9e1721ee46e90230c7c570cdeb5a893b5cce9bff 1334 | md5: d2732eb636c264dc9aa4cbee404b1a53 1335 | depends: 1336 | - python >=3.10 1337 | - python 1338 | license: MIT 1339 | license_family: MIT 1340 | purls: 1341 | - pkg:pypi/tomli?source=compressed-mapping 1342 | size: 20973 1343 | timestamp: 1760014679845 1344 | - pypi: https://files.pythonhosted.org/packages/22/e8/5707939118992ced2bf5385adc3ede7723c1b717b07ad14c495eea1e47b4/ty-0.0.1a25-py3-none-macosx_11_0_arm64.whl 1345 | name: ty 1346 | version: 0.0.1a25 1347 | sha256: 949523621f336e01bc7d687b7bd08fe838edadbdb6563c2c057ed1d264e820cf 1348 | requires_python: '>=3.8' 1349 | - pypi: https://files.pythonhosted.org/packages/57/d3/01ecc23bbd8f3e0dfbcf9172d06d84e88155c5f416f1491137e8066fd859/ty-0.0.1a25-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 1350 | name: ty 1351 | version: 0.0.1a25 1352 | sha256: 0a90d897a7c1a5ae9b41a4c7b0a42262a06361476ad88d783dbedd7913edadbc 1353 | requires_python: '>=3.8' 1354 | - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda 1355 | sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 1356 | md5: 0caa1af407ecff61170c9437a808404d 1357 | depends: 1358 | - python >=3.10 1359 | - python 1360 | license: PSF-2.0 1361 | license_family: PSF 1362 | purls: 1363 | - pkg:pypi/typing-extensions?source=hash-mapping 1364 | size: 51692 1365 | timestamp: 1756220668932 1366 | - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda 1367 | sha256: 5aaa366385d716557e365f0a4e9c3fca43ba196872abbbe3d56bb610d131e192 1368 | md5: 4222072737ccff51314b5ece9c7d6f5a 1369 | license: LicenseRef-Public-Domain 1370 | purls: [] 1371 | size: 122968 1372 | timestamp: 1742727099393 1373 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.0.1-py314h9891dd4_6.conda 1374 | sha256: ef6753f6febaa74d35253e4e0dd09dc9497af8e370893bd97c479f59346daa57 1375 | md5: 28303a78c48916ab07b95ffdbffdfd6c 1376 | depends: 1377 | - __glibc >=2.17,<3.0.a0 1378 | - cffi 1379 | - libgcc >=14 1380 | - libstdcxx >=14 1381 | - python >=3.14,<3.15.0a0 1382 | - python_abi 3.14.* *_cp314 1383 | license: MIT 1384 | license_family: MIT 1385 | purls: 1386 | - pkg:pypi/ukkonen?source=hash-mapping 1387 | size: 14762 1388 | timestamp: 1761594960135 1389 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.0.1-py314h6b18a25_6.conda 1390 | sha256: 2ef342cc861c52ec3ac464e89b192a37fd7afd79740b2c0773d2588fd8acff26 1391 | md5: 452b75f09bc2a4c5eea4044b769bc659 1392 | depends: 1393 | - __osx >=11.0 1394 | - cffi 1395 | - libcxx >=19 1396 | - python >=3.14,<3.15.0a0 1397 | - python >=3.14,<3.15.0a0 *_cp314 1398 | - python_abi 3.14.* *_cp314 1399 | license: MIT 1400 | license_family: MIT 1401 | purls: 1402 | - pkg:pypi/ukkonen?source=hash-mapping 1403 | size: 14635 1404 | timestamp: 1761595172213 1405 | - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda 1406 | sha256: 4fb9789154bd666ca74e428d973df81087a697dbb987775bc3198d2215f240f8 1407 | md5: 436c165519e140cb08d246a4472a9d6a 1408 | depends: 1409 | - brotli-python >=1.0.9 1410 | - h2 >=4,<5 1411 | - pysocks >=1.5.6,<2.0,!=1.5.7 1412 | - python >=3.9 1413 | - zstandard >=0.18.0 1414 | license: MIT 1415 | license_family: MIT 1416 | purls: 1417 | - pkg:pypi/urllib3?source=hash-mapping 1418 | size: 101735 1419 | timestamp: 1750271478254 1420 | - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.35.4-pyhd8ed1ab_0.conda 1421 | sha256: 77193c99c6626c58446168d3700f9643d8c0dab1f6deb6b9dd039e6872781bfb 1422 | md5: cfccfd4e8d9de82ed75c8e2c91cab375 1423 | depends: 1424 | - distlib >=0.3.7,<1 1425 | - filelock >=3.12.2,<4 1426 | - platformdirs >=3.9.1,<5 1427 | - python >=3.10 1428 | - typing_extensions >=4.13.2 1429 | license: MIT 1430 | license_family: MIT 1431 | purls: 1432 | - pkg:pypi/virtualenv?source=hash-mapping 1433 | size: 4401341 1434 | timestamp: 1761726489722 1435 | - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda 1436 | sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad 1437 | md5: a77f85f77be52ff59391544bfe73390a 1438 | depends: 1439 | - libgcc >=14 1440 | - __glibc >=2.17,<3.0.a0 1441 | license: MIT 1442 | license_family: MIT 1443 | purls: [] 1444 | size: 85189 1445 | timestamp: 1753484064210 1446 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda 1447 | sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac 1448 | md5: 78a0fe9e9c50d2c381e8ee47e3ea437d 1449 | depends: 1450 | - __osx >=11.0 1451 | license: MIT 1452 | license_family: MIT 1453 | purls: [] 1454 | size: 83386 1455 | timestamp: 1753484079473 1456 | - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py314h31f8a6b_0.conda 1457 | sha256: ec4e66b4e042ea9554b9db92b509358f75390f7dcbafb8eead940a2880486a63 1458 | md5: 68bd13651618354987763f746ee1fadc 1459 | depends: 1460 | - python 1461 | - cffi >=1.11 1462 | - zstd >=1.5.7,<1.5.8.0a0 1463 | - libgcc >=14 1464 | - __glibc >=2.17,<3.0.a0 1465 | - zstd >=1.5.7,<1.6.0a0 1466 | - python_abi 3.14.* *_cp314 1467 | license: BSD-3-Clause 1468 | license_family: BSD 1469 | purls: 1470 | - pkg:pypi/zstandard?source=hash-mapping 1471 | size: 127864 1472 | timestamp: 1757930108791 1473 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.25.0-py314h163e31d_0.conda 1474 | sha256: 5b707d7b80d9b410fce776a439273213745ffc3fa4553ec31f264bbaf63a6ec6 1475 | md5: c824d8cd887ce1d7af8963ca4087a764 1476 | depends: 1477 | - python 1478 | - cffi >=1.11 1479 | - zstd >=1.5.7,<1.5.8.0a0 1480 | - __osx >=11.0 1481 | - python 3.14.* *_cp314 1482 | - zstd >=1.5.7,<1.6.0a0 1483 | - python_abi 3.14.* *_cp314 1484 | license: BSD-3-Clause 1485 | license_family: BSD 1486 | purls: 1487 | - pkg:pypi/zstandard?source=hash-mapping 1488 | size: 125883 1489 | timestamp: 1757930173407 1490 | - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda 1491 | sha256: a4166e3d8ff4e35932510aaff7aa90772f84b4d07e9f6f83c614cba7ceefe0eb 1492 | md5: 6432cb5d4ac0046c3ac0a8a0f95842f9 1493 | depends: 1494 | - __glibc >=2.17,<3.0.a0 1495 | - libgcc >=13 1496 | - libstdcxx >=13 1497 | - libzlib >=1.3.1,<2.0a0 1498 | license: BSD-3-Clause 1499 | license_family: BSD 1500 | purls: [] 1501 | size: 567578 1502 | timestamp: 1742433379869 1503 | - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda 1504 | sha256: 0d02046f57f7a1a3feae3e9d1aa2113788311f3cf37a3244c71e61a93177ba67 1505 | md5: e6f69c7bcccdefa417f056fa593b40f0 1506 | depends: 1507 | - __osx >=11.0 1508 | - libzlib >=1.3.1,<2.0a0 1509 | license: BSD-3-Clause 1510 | license_family: BSD 1511 | purls: [] 1512 | size: 399979 1513 | timestamp: 1742433432699 1514 | --------------------------------------------------------------------------------