mirror of
https://github.com/datafolklabs/cement.git
synced 2026-02-06 17:56:49 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3527ade7b5 | ||
|
|
dad85d287a | ||
|
|
7c347abe43 | ||
|
|
bfb3b8c01b | ||
|
|
3ee6b5157b | ||
|
|
cc857e70a7 | ||
|
|
ac410db146 | ||
|
|
8b038170d8 | ||
|
|
23b9b95d93 | ||
|
|
9df6b3a3d3 | ||
|
|
bd0d5eb878 | ||
|
|
80da0029ed | ||
|
|
b46ce15833 | ||
|
|
41f2180976 | ||
|
|
8f5eaa817d | ||
|
|
2bc559a30d |
14
.envrc
Normal file
14
.envrc
Normal file
@ -0,0 +1,14 @@
|
||||
# Automatically sets up your devbox environment whenever you cd into this
|
||||
# directory via our direnv integration:
|
||||
|
||||
eval "$(devbox generate direnv --print-envrc)"
|
||||
|
||||
# check out https://www.jetpack.io/devbox/docs/ide_configuration/direnv/
|
||||
# for more details
|
||||
|
||||
source_env_if_exists .envrc.local
|
||||
|
||||
export SMTP_HOST=localhost
|
||||
export SMTP_PORT=1025
|
||||
export MEMCACHED_HOST=localhost
|
||||
export REDIS_HOST=localhost
|
||||
98
.github/workflows/build_and_test.yml
vendored
Normal file
98
.github/workflows/build_and_test.yml
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
name: Build & Test
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
env:
|
||||
SMTP_HOST: localhost
|
||||
SMTP_PORT: 1025
|
||||
MEMCACHED_HOST: localhost
|
||||
REDIS_HOST: localhost
|
||||
|
||||
jobs:
|
||||
comply:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ConorMacBride/install-package@v1
|
||||
with:
|
||||
apt: libmemcached-dev
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
architecture: "x64"
|
||||
- name: Setup PDM
|
||||
uses: pdm-project/setup-pdm@v4
|
||||
- name: Install dependencies
|
||||
run: pdm install
|
||||
- name: Make Comply
|
||||
run: make comply
|
||||
|
||||
test:
|
||||
needs: comply
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ConorMacBride/install-package@v1
|
||||
with:
|
||||
apt: libmemcached-dev
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
architecture: "x64"
|
||||
- uses: hoverkraft-tech/compose-action@v2.0.1
|
||||
with:
|
||||
compose-file: "./docker/compose-services-only.yml"
|
||||
- name: Setup PDM
|
||||
uses: pdm-project/setup-pdm@v4
|
||||
- name: Install dependencies
|
||||
run: pdm install
|
||||
- name: Make Test
|
||||
run: make test
|
||||
|
||||
test-all:
|
||||
needs: test
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
# FIXME ?
|
||||
# os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
os: [ubuntu-latest]
|
||||
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "pypy3.10"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ConorMacBride/install-package@v1
|
||||
with:
|
||||
apt: libmemcached-dev
|
||||
- uses: hoverkraft-tech/compose-action@v2.0.1
|
||||
with:
|
||||
compose-file: "./docker/compose-services-only.yml"
|
||||
- name: Setup PDM
|
||||
uses: pdm-project/setup-pdm@v4
|
||||
- name: Install dependencies
|
||||
run: pdm install
|
||||
- name: Make Test
|
||||
run: make test
|
||||
|
||||
cli-smoke-test:
|
||||
needs: test-all
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: hoverkraft-tech/compose-action@v2.0.1
|
||||
with:
|
||||
compose-file: "./docker-compose.yml"
|
||||
- name: CLI Smoke Tests
|
||||
run: ./scripts/cli-smoke-test.sh
|
||||
- if: always()
|
||||
name: Review Output
|
||||
run: cat ./tmp/cli-smoke-test.out
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -52,7 +52,7 @@ pip-log.txt
|
||||
# Documentation
|
||||
doc/build
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.coverage*
|
||||
htmlcov
|
||||
coverage-report
|
||||
.tox
|
||||
|
||||
24
CHANGELOG.md
24
CHANGELOG.md
@ -1,5 +1,29 @@
|
||||
# ChangeLog
|
||||
|
||||
## 3.0.15 - DEVELOPMENT (will be released as stable/3.0.16)
|
||||
|
||||
Bugs:
|
||||
|
||||
- None
|
||||
|
||||
Features:
|
||||
|
||||
- None
|
||||
|
||||
Refactoring:
|
||||
|
||||
- `[dev]` Python 3.14 Default Development Target
|
||||
- `[dev]` Remove Support for Python 3.8 (EOL)
|
||||
|
||||
Misc:
|
||||
|
||||
- None
|
||||
|
||||
Deprecations:
|
||||
|
||||
- None
|
||||
|
||||
|
||||
## 3.0.14 - May 5, 2025
|
||||
|
||||
Bugs:
|
||||
|
||||
78
CLAUDE.md
Normal file
78
CLAUDE.md
Normal file
@ -0,0 +1,78 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Development Commands
|
||||
|
||||
**Testing and Compliance:**
|
||||
- `make test` - Run full test suite with coverage and PEP8 compliance
|
||||
- `make test-core` - Run only core library tests
|
||||
- `make comply` - Run both ruff and mypy compliance checks
|
||||
- `make comply-ruff` - Run ruff linting
|
||||
- `make comply-ruff-fix` - Auto-fix ruff issues
|
||||
- `make comply-mypy` - Run mypy type checking
|
||||
- `pdm run pytest --cov=cement tests/` - Direct pytest execution
|
||||
- `pdm run pytest --cov=cement.core tests/core` - Test only core components
|
||||
|
||||
**Development Environment:**
|
||||
- `pdm venv create && pdm install` - Set up local development environment
|
||||
- `pdm run cement --help` - Run the cement CLI
|
||||
|
||||
**Documentation:**
|
||||
- `make docs` - Build Sphinx documentation
|
||||
|
||||
**Build and Distribution:**
|
||||
- `pdm build` - Build distribution packages
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
Cement is a CLI application framework built around a handler/interface pattern with the following core concepts:
|
||||
|
||||
**Core Application (`cement.core.foundation.App`):**
|
||||
- The main `App` class in `cement/core/foundation.py` is the central orchestrator
|
||||
- Uses a Meta class pattern for configuration
|
||||
- Manages lifecycle through setup(), run(), and close() methods
|
||||
- Supports signal handling and application reloading
|
||||
|
||||
**Handler System:**
|
||||
- Interface/Handler pattern where interfaces define contracts and handlers provide implementations
|
||||
- Core handlers: arg, config, log, output, cache, controller, extension, plugin, template
|
||||
- Handlers are registered and resolved through `HandlerManager`
|
||||
- Located in `cement/core/` with corresponding modules (arg.py, config.py, etc.)
|
||||
|
||||
**Extensions System:**
|
||||
- Extensions in `cement/ext/` provide additional functionality
|
||||
- Examples: ext_yaml.py, ext_jinja2.py, ext_argparse.py, etc.
|
||||
- Optional dependencies managed through pyproject.toml extras
|
||||
|
||||
**CLI Structure:**
|
||||
- Main CLI application in `cement/cli/main.py`
|
||||
- Uses CementApp class that extends core App
|
||||
- Includes code generation templates in `cement/cli/templates/`
|
||||
|
||||
**Controllers:**
|
||||
- MVC-style controllers handle command routing
|
||||
- Base controller pattern in controllers/base.py files
|
||||
- Support nested sub-commands and argument parsing
|
||||
|
||||
## Key Development Practices
|
||||
|
||||
- 100% test coverage required (pytest with coverage reporting)
|
||||
- 100% PEP8 compliance enforced via ruff
|
||||
- Type annotation compliance via mypy
|
||||
- PDM for dependency management
|
||||
- Zero external dependencies for core framework (optional for extensions)
|
||||
|
||||
## Testing Notes
|
||||
|
||||
- Tests located in `tests/` directory mirroring source structure
|
||||
- Core tests can run independently via `make test-core`
|
||||
- Coverage reports generated in `coverage-report/` directory
|
||||
|
||||
## Extension Development
|
||||
|
||||
When working with extensions:
|
||||
- Check `cement/ext/` for existing extension patterns
|
||||
- Optional dependencies declared in pyproject.toml under `[project.optional-dependencies]`
|
||||
- Extensions follow naming pattern `ext_<name>.py`
|
||||
- Must implement proper interface contracts
|
||||
@ -1,4 +1,4 @@
|
||||
FROM python:3.13-alpine
|
||||
FROM python:3.14-alpine
|
||||
LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>"
|
||||
ENV PS1="\[\e[0;33m\]|> cement <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
|
||||
ENV PATH="${PATH}:/root/.local/bin"
|
||||
|
||||
2
Makefile
2
Makefile
@ -3,11 +3,11 @@
|
||||
dev:
|
||||
docker compose up -d
|
||||
docker compose exec cement pdm install
|
||||
docker compose exec cement-py38 pdm install
|
||||
docker compose exec cement-py39 pdm install
|
||||
docker compose exec cement-py310 pdm install
|
||||
docker compose exec cement-py311 pdm install
|
||||
docker compose exec cement-py312 pdm install
|
||||
docker compose exec cement-py313 pdm install
|
||||
docker compose exec cement /bin/bash
|
||||
|
||||
test: comply
|
||||
|
||||
@ -42,7 +42,7 @@ Cement core features include (but are not limited to):
|
||||
- 100% PEP8 compliance (`ruff`)
|
||||
- Type annotation compliance (`mypy`)
|
||||
- Extensive API Reference (`sphinx`)
|
||||
- Tested on Python 3.8+
|
||||
- Tested on Python 3.9+
|
||||
|
||||
|
||||
## Optional Extensions
|
||||
@ -92,17 +92,17 @@ All execution is done *inside the docker containers*.
|
||||
|
||||
**Testing Alternative Versions of Python**
|
||||
|
||||
The latest stable version of Python 3 is the default, and target version accessible as the `cement` container within Docker Compose. For testing against alternative versions of python, additional containers are created (ex: `cement-py38`, `cement-py39`, etc). You can access these containers via:
|
||||
The latest stable version of Python 3 is the default, and target version accessible as the `cement` container within Docker Compose. For testing against alternative versions of python, additional containers are created (ex: `cement-py39`, `cement-py310`, etc). You can access these containers via:
|
||||
|
||||
```
|
||||
$ docker-compose ps
|
||||
Name Command State Ports
|
||||
-------------------------------------------------------------------------
|
||||
cement_cement-py38_1 /bin/bash Up
|
||||
cement_cement-py39_1 /bin/bash Up
|
||||
cement_cement-py310_1 /bin/bash Up
|
||||
cement_cement-py311_1 /bin/bash Up
|
||||
cement_cement-py312_1 /bin/bash Up
|
||||
cement_cement-py313_1 /bin/bash Up
|
||||
cement_cement_1 /bin/bash Up
|
||||
cement_memcached_1 docker-entrypoint.sh memcached Up 11211/tcp
|
||||
cement_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
|
||||
|
||||
@ -10,3 +10,21 @@ from .ext.ext_argparse import expose as ex
|
||||
from .utils.misc import init_defaults, minimal_logger
|
||||
from .utils import misc, fs, shell
|
||||
from .utils.version import get_version
|
||||
|
||||
__all__ = [
|
||||
"App",
|
||||
"TestApp",
|
||||
"Interface",
|
||||
"Handler",
|
||||
"FrameworkError",
|
||||
"InterfaceError",
|
||||
"CaughtSignal",
|
||||
"Controller",
|
||||
"ex",
|
||||
"init_defaults",
|
||||
"minimal_logger",
|
||||
"misc",
|
||||
"fs",
|
||||
"shell",
|
||||
"get_version",
|
||||
]
|
||||
@ -1,3 +1,3 @@
|
||||
"""Cement core backend module."""
|
||||
|
||||
VERSION = (3, 0, 14, 'final', 0) # pragma: nocover
|
||||
VERSION = (3, 0, 15, 'final', 0) # pragma: nocover
|
||||
|
||||
@ -5,7 +5,6 @@ Cement plugin extension module.
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
import importlib
|
||||
import importlib.util
|
||||
import importlib.machinery
|
||||
import re
|
||||
|
||||
1316
devbox.d/redis/redis.conf
Normal file
1316
devbox.d/redis/redis.conf
Normal file
File diff suppressed because it is too large
Load Diff
24
devbox.json
Normal file
24
devbox.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.14.0/.schema/devbox.schema.json",
|
||||
"packages": {
|
||||
"python": "3.14",
|
||||
"pdm": "latest",
|
||||
"libmemcached": "latest",
|
||||
"zlib": {
|
||||
"version": "latest",
|
||||
"outputs": ["out", "dev"]
|
||||
},
|
||||
"redis": "latest",
|
||||
"memcached": {
|
||||
"version": "latest",
|
||||
"outputs": ["out"]
|
||||
},
|
||||
"mailpit": "latest"
|
||||
},
|
||||
"shell": {
|
||||
"init_hook": [],
|
||||
"scripts": {
|
||||
"test": ["echo \"Error: no test specified\" && exit 1"]
|
||||
}
|
||||
}
|
||||
}
|
||||
402
devbox.lock
Normal file
402
devbox.lock
Normal file
@ -0,0 +1,402 @@
|
||||
{
|
||||
"lockfile_version": "1",
|
||||
"packages": {
|
||||
"github:NixOS/nixpkgs/nixpkgs-unstable": {
|
||||
"resolved": "github:NixOS/nixpkgs/a7fc11be66bdfb5cdde611ee5ce381c183da8386?lastModified=1761880412&narHash=sha256-QoJjGd4NstnyOG4mm4KXF%2BweBzA2AH%2F7gn1Pmpfcb0A%3D"
|
||||
},
|
||||
"libmemcached@latest": {
|
||||
"last_modified": "2025-10-07T08:41:47Z",
|
||||
"resolved": "github:NixOS/nixpkgs/bce5fe2bb998488d8e7e7856315f90496723793c#libmemcached",
|
||||
"source": "devbox-search",
|
||||
"version": "1.0.18",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/hvq13f4g2yzg4ir8zms3qljdg70kx2nk-libmemcached-1.0.18",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/hvq13f4g2yzg4ir8zms3qljdg70kx2nk-libmemcached-1.0.18"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/pgbw4r2l1k6r4jkj3rx9z1sjvffkzlgj-libmemcached-1.0.18",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/pgbw4r2l1k6r4jkj3rx9z1sjvffkzlgj-libmemcached-1.0.18"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/22p6w02llxgwwvzgrjhiawfhprxs0gn1-libmemcached-1.0.18",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/22p6w02llxgwwvzgrjhiawfhprxs0gn1-libmemcached-1.0.18"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/1zqgqb0iv0q53q0laxmwbhbvzrpid72d-libmemcached-1.0.18",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/1zqgqb0iv0q53q0laxmwbhbvzrpid72d-libmemcached-1.0.18"
|
||||
}
|
||||
}
|
||||
},
|
||||
"mailpit@latest": {
|
||||
"last_modified": "2025-10-13T09:56:54Z",
|
||||
"resolved": "github:NixOS/nixpkgs/c12c63cd6c5eb34c7b4c3076c6a99e00fcab86ec#mailpit",
|
||||
"source": "devbox-search",
|
||||
"version": "1.27.10",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/hygcxbx8nbzgmzj2861pq8371sbk9vxx-mailpit-1.27.10",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/hygcxbx8nbzgmzj2861pq8371sbk9vxx-mailpit-1.27.10"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/i562vdjasq196kw3zxsq2faqxk0jia35-mailpit-1.27.10",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/i562vdjasq196kw3zxsq2faqxk0jia35-mailpit-1.27.10"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/iw496lj2zl7yyhr584gl3gmlpwfgwywz-mailpit-1.27.10",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/iw496lj2zl7yyhr584gl3gmlpwfgwywz-mailpit-1.27.10"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/31p7d3r6ngcyy19asv92590aihcpcw2y-mailpit-1.27.10",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/31p7d3r6ngcyy19asv92590aihcpcw2y-mailpit-1.27.10"
|
||||
}
|
||||
}
|
||||
},
|
||||
"memcached@latest": {
|
||||
"last_modified": "2025-10-07T08:41:47Z",
|
||||
"resolved": "github:NixOS/nixpkgs/bce5fe2bb998488d8e7e7856315f90496723793c#memcached",
|
||||
"source": "devbox-search",
|
||||
"version": "1.6.39",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/ihnmlzfs4bj1iza5jrhd69j7cfxk98c9-memcached-1.6.39",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/ihnmlzfs4bj1iza5jrhd69j7cfxk98c9-memcached-1.6.39"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/ikqynsvdx49dyfyvjc9dzal3793x3q12-memcached-1.6.39",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/ikqynsvdx49dyfyvjc9dzal3793x3q12-memcached-1.6.39"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/pmljf231q2z42c3fqphy16nwb1238rvw-memcached-1.6.39",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/pmljf231q2z42c3fqphy16nwb1238rvw-memcached-1.6.39"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/mr6k45aw0srb2vl5azd2ndyh77fdqkp7-memcached-1.6.39",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/mr6k45aw0srb2vl5azd2ndyh77fdqkp7-memcached-1.6.39"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pdm@latest": {
|
||||
"last_modified": "2025-10-07T08:41:47Z",
|
||||
"resolved": "github:NixOS/nixpkgs/bce5fe2bb998488d8e7e7856315f90496723793c#pdm",
|
||||
"source": "devbox-search",
|
||||
"version": "2.25.9",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/fali4xk6c9dv1cfp6yshc83k7knn4jkm-pdm-2.25.9",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/84h5gp6xqz6ivgwdv1hs72nkrhr1jp6w-pdm-2.25.9-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/fali4xk6c9dv1cfp6yshc83k7knn4jkm-pdm-2.25.9"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/d444f8wq1zf4w5vmm95lsh25m60dp3b0-pdm-2.25.9",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/dhx4hdxizq8zrvwajs4qiz26n5bk4g71-pdm-2.25.9-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/d444f8wq1zf4w5vmm95lsh25m60dp3b0-pdm-2.25.9"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/b3628r7jbv1i70jajx3z25q4pwxrq1dg-pdm-2.25.9",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/i4349788frmbv2kcpnnh6dh91hhgcbss-pdm-2.25.9-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/b3628r7jbv1i70jajx3z25q4pwxrq1dg-pdm-2.25.9"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/w9mvh1lpwwyxh1h2z5bypvvvvxwdjbyd-pdm-2.25.9",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dist",
|
||||
"path": "/nix/store/q4dp9wx7g79hknqgly1nccrdwvxr274j-pdm-2.25.9-dist"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/w9mvh1lpwwyxh1h2z5bypvvvvxwdjbyd-pdm-2.25.9"
|
||||
}
|
||||
}
|
||||
},
|
||||
"python@3.14": {
|
||||
"last_modified": "2025-10-08T01:30:28Z",
|
||||
"plugin_version": "0.0.4",
|
||||
"resolved": "github:NixOS/nixpkgs/8b5c9dd8856f0c0cf46cc91f2c21c106a9d42e25#python314",
|
||||
"source": "devbox-search",
|
||||
"version": "3.14.0",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/2sqv05h8017f38w5rvppb2f5wbbisnwp-python3-3.14.0",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/2sqv05h8017f38w5rvppb2f5wbbisnwp-python3-3.14.0"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/zlph3shgrkfmrhkxbgmi6qa26gfzl58q-python3-3.14.0",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"path": "/nix/store/3zmfrpjfpqaxcl68hlg5nfzvx49awjks-python3-3.14.0-debug"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/zlph3shgrkfmrhkxbgmi6qa26gfzl58q-python3-3.14.0"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/bq9ss2vlr05zdrhcfmvclm0gsrc7i6xb-python3-3.14.0",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/bq9ss2vlr05zdrhcfmvclm0gsrc7i6xb-python3-3.14.0"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/76lchhz5hhik0j5hjy6lwwn3ik0x54aa-python3-3.14.0",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"path": "/nix/store/rjm597f2d9bjllyjnv3y20261bwxd108-python3-3.14.0-debug"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/76lchhz5hhik0j5hjy6lwwn3ik0x54aa-python3-3.14.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"redis@latest": {
|
||||
"last_modified": "2025-10-07T08:41:47Z",
|
||||
"plugin_version": "0.0.2",
|
||||
"resolved": "github:NixOS/nixpkgs/bce5fe2bb998488d8e7e7856315f90496723793c#redis",
|
||||
"source": "devbox-search",
|
||||
"version": "8.2.2",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/cnwxss9snn773vwr2vb0b6jx7lznmac2-redis-8.2.2",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/cnwxss9snn773vwr2vb0b6jx7lznmac2-redis-8.2.2"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/nml062djj2nfc7zgn2q93g0swgrbdqbc-redis-8.2.2",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/nml062djj2nfc7zgn2q93g0swgrbdqbc-redis-8.2.2"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/vixhsgdlv2d8hm66jkclqdgyfi3vi86b-redis-8.2.2",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/vixhsgdlv2d8hm66jkclqdgyfi3vi86b-redis-8.2.2"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/z6sw7nrc62l9z1mm05dqx4vz3a65lgb6-redis-8.2.2",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/z6sw7nrc62l9z1mm05dqx4vz3a65lgb6-redis-8.2.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"zlib@latest": {
|
||||
"last_modified": "2025-10-08T10:03:27Z",
|
||||
"resolved": "github:NixOS/nixpkgs/fb5cf53218b987f2703a5bbc292a030c0fe33443#zlib",
|
||||
"source": "devbox-search",
|
||||
"version": "1.3.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/5vnba43n1w87cs2i2dd242zy88k4dwf9-zlib-1.3.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"path": "/nix/store/86xjpgsysygxdhfczssrlj24mi22wxiq-zlib-1.3.1-dev"
|
||||
},
|
||||
{
|
||||
"name": "static",
|
||||
"path": "/nix/store/39mpcp31vw48raa6lj7k2di0ln922bjp-zlib-1.3.1-static"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/5vnba43n1w87cs2i2dd242zy88k4dwf9-zlib-1.3.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/h5gyhqv452n16izdh86s3rvdq1fcg2pb-zlib-1.3.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"path": "/nix/store/c7jl10xakizqzj2wv5arnjggwv1vh3r0-zlib-1.3.1-dev"
|
||||
},
|
||||
{
|
||||
"name": "static",
|
||||
"path": "/nix/store/plix72ay1sq7l91qm97a0ls7haa0hmv8-zlib-1.3.1-static"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/h5gyhqv452n16izdh86s3rvdq1fcg2pb-zlib-1.3.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/yy41r1jfz748y6xq4dc54qm4xlravz95-zlib-1.3.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"path": "/nix/store/kw5wnbgivfxif9m2g8i4ks0whdgnh158-zlib-1.3.1-dev"
|
||||
},
|
||||
{
|
||||
"name": "static",
|
||||
"path": "/nix/store/l6mprw6il6i4dx78pcnn7as09287f9nh-zlib-1.3.1-static"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/yy41r1jfz748y6xq4dc54qm4xlravz95-zlib-1.3.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out",
|
||||
"path": "/nix/store/6qi8skh85ci2k9gvl27nnh3kiy32qnsz-zlib-1.3.1",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "dev",
|
||||
"path": "/nix/store/6fqij3sy1mlsnq1n679bzbl5bkqs7yvk-zlib-1.3.1-dev"
|
||||
},
|
||||
{
|
||||
"name": "static",
|
||||
"path": "/nix/store/b1l0v5czhw4c410nxvk5lbjfv9r8h7h7-zlib-1.3.1-static"
|
||||
}
|
||||
],
|
||||
"store_path": "/nix/store/6qi8skh85ci2k9gvl27nnh3kiy32qnsz-zlib-1.3.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,20 +53,13 @@ services:
|
||||
- memcached
|
||||
- mailpit
|
||||
|
||||
cement-py38:
|
||||
<<: *DEFAULTS
|
||||
image: "cement:dev-py38"
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile.dev-py38
|
||||
|
||||
cement-py39:
|
||||
<<: *DEFAULTS
|
||||
image: "cement:dev-py39"
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile.dev-py39
|
||||
|
||||
|
||||
cement-py310:
|
||||
<<: *DEFAULTS
|
||||
image: "cement:dev-py310"
|
||||
@ -87,3 +80,10 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile.dev-py312
|
||||
|
||||
cement-py313:
|
||||
<<: *DEFAULTS
|
||||
image: "cement:dev-py313"
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile.dev-py313
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
FROM python:3.13-alpine
|
||||
FROM python:3.14-alpine
|
||||
LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>"
|
||||
ENV PS1="\[\e[0;33m\]|> cement-py313 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
|
||||
ENV PS1="\[\e[0;33m\]|> cement-py314 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
|
||||
ENV PATH="${PATH}:/root/.local/bin"
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM python:3.13-rc-alpine
|
||||
FROM python:3.13-alpine
|
||||
LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>"
|
||||
ENV PS1="\[\e[0;33m\]|> cement-py313 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
|
||||
ENV PATH="${PATH}:/root/.local/bin"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
FROM python:3.8-alpine
|
||||
FROM python:3.14-alpine
|
||||
LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>"
|
||||
ENV PS1="\[\e[0;33m\]|> cement-py38 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
|
||||
ENV PS1="\[\e[0;33m\]|> cement-py314 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
|
||||
ENV PATH="${PATH}:/root/.local/bin"
|
||||
|
||||
WORKDIR /src
|
||||
@ -22,7 +22,7 @@ RUN apk update \
|
||||
&& ln -sf /usr/bin/vim /usr/bin/vi
|
||||
RUN pipx install pdm
|
||||
COPY . /src
|
||||
COPY docker/vimrc /root/.vimrc
|
||||
COPY docker/bashrc /root/.bashrc
|
||||
COPY ./docker/vimrc /root/.vimrc
|
||||
COPY ./docker/bashrc /root/.bashrc
|
||||
RUN pdm install
|
||||
CMD ["/bin/bash"]
|
||||
33
docker/compose-services-only.yml
Normal file
33
docker/compose-services-only.yml
Normal file
@ -0,0 +1,33 @@
|
||||
volumes:
|
||||
mailpit-data:
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: redis:latest
|
||||
hostname: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
memcached:
|
||||
image: memcached:latest
|
||||
hostname: memcached
|
||||
ports:
|
||||
- 11211:11211
|
||||
|
||||
mailpit:
|
||||
image: axllent/mailpit
|
||||
hostname: mailpit
|
||||
restart: always
|
||||
volumes:
|
||||
- mailpit-data:/data
|
||||
- ../docker/mailpit:/certificates
|
||||
ports:
|
||||
- 8025:8025
|
||||
- 1025:1025
|
||||
environment:
|
||||
MP_MAX_MESSAGES: 5000
|
||||
MP_DATA_FILE: /data/mailpit.db
|
||||
MP_SMTP_AUTH_ACCEPT_ANY: 1
|
||||
MP_SMTP_AUTH_ALLOW_INSECURE: 1
|
||||
MP_SMTP_TLS_CERT: /certificates/dev-cert.pem
|
||||
MP_SMTP_TLS_KEY: /certificates/dev-key.pem
|
||||
212
pdm.lock
212
pdm.lock
@ -3,12 +3,12 @@
|
||||
|
||||
[metadata]
|
||||
groups = ["default", "alarm", "argparse", "cli", "colorlog", "configparser", "daemon", "dev", "docs", "dummy", "generate", "jinja2", "json", "logging", "memcached", "mustache", "plugin", "print", "redis", "scrub", "smtp", "tabulate", "watchdog", "yaml"]
|
||||
strategy = ["cross_platform", "inherit_metadata"]
|
||||
strategy = ["inherit_metadata"]
|
||||
lock_version = "4.5.0"
|
||||
content_hash = "sha256:edb453570d1f7e2dcd14a71e866fa1814be1c5341a716c96164858feae2e3662"
|
||||
content_hash = "sha256:88e91afb3db1d8d71ebff4abd3d4d3e29b3415592657bd9fe104948d542d1ee5"
|
||||
|
||||
[[metadata.targets]]
|
||||
requires_python = ">=3.8"
|
||||
requires_python = ">=3.9"
|
||||
|
||||
[[package]]
|
||||
name = "alabaster"
|
||||
@ -55,7 +55,7 @@ name = "certifi"
|
||||
version = "2024.2.2"
|
||||
requires_python = ">=3.6"
|
||||
summary = "Python package for providing Mozilla's CA Bundle."
|
||||
groups = ["docs"]
|
||||
groups = ["dev", "docs"]
|
||||
files = [
|
||||
{file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
|
||||
{file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
|
||||
@ -66,7 +66,7 @@ name = "charset-normalizer"
|
||||
version = "3.3.2"
|
||||
requires_python = ">=3.7.0"
|
||||
summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
groups = ["docs"]
|
||||
groups = ["dev", "docs"]
|
||||
files = [
|
||||
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
|
||||
@ -161,7 +161,7 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "colorlog"
|
||||
version = "6.9.0"
|
||||
version = "6.10.1"
|
||||
requires_python = ">=3.6"
|
||||
summary = "Add colours to the output of Python's logging module."
|
||||
groups = ["colorlog"]
|
||||
@ -169,8 +169,8 @@ dependencies = [
|
||||
"colorama; sys_platform == \"win32\"",
|
||||
]
|
||||
files = [
|
||||
{file = "colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff"},
|
||||
{file = "colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2"},
|
||||
{file = "colorlog-6.10.1-py3-none-any.whl", hash = "sha256:2d7e8348291948af66122cff006c9f8da6255d224e7cf8e37d8de2df3bad8c9c"},
|
||||
{file = "colorlog-6.10.1.tar.gz", hash = "sha256:eb4ae5cb65fe7fec7773c2306061a8e63e02efc2c72eba9d27b0fa23c94f1321"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -380,7 +380,7 @@ name = "idna"
|
||||
version = "3.6"
|
||||
requires_python = ">=3.5"
|
||||
summary = "Internationalized Domain Names in Applications (IDNA)"
|
||||
groups = ["docs"]
|
||||
groups = ["dev", "docs"]
|
||||
files = [
|
||||
{file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
|
||||
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
|
||||
@ -429,7 +429,7 @@ name = "jinja2"
|
||||
version = "3.1.6"
|
||||
requires_python = ">=3.7"
|
||||
summary = "A very fast and expressive template engine."
|
||||
groups = ["docs", "jinja2"]
|
||||
groups = ["cli", "docs", "jinja2"]
|
||||
dependencies = [
|
||||
"MarkupSafe>=2.0",
|
||||
]
|
||||
@ -443,7 +443,7 @@ name = "markupsafe"
|
||||
version = "2.1.5"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Safely add untrusted strings to HTML/XML markup."
|
||||
groups = ["docs", "jinja2"]
|
||||
groups = ["cli", "docs", "jinja2"]
|
||||
files = [
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
||||
@ -702,82 +702,91 @@ files = [
|
||||
{file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2024.1"
|
||||
summary = "World timezone definitions, modern and historical"
|
||||
groups = ["docs"]
|
||||
marker = "python_version < \"3.9\""
|
||||
files = [
|
||||
{file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
|
||||
{file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.2"
|
||||
version = "6.0.3"
|
||||
requires_python = ">=3.8"
|
||||
summary = "YAML parser and emitter for Python"
|
||||
groups = ["generate", "yaml"]
|
||||
groups = ["cli", "generate", "yaml"]
|
||||
files = [
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
|
||||
{file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
|
||||
{file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
|
||||
{file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
|
||||
{file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
|
||||
{file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
|
||||
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
|
||||
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
|
||||
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
|
||||
{file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
|
||||
{file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
|
||||
{file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
|
||||
{file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
|
||||
{file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"},
|
||||
{file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "6.0.0"
|
||||
version = "6.1.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Python client for Redis database and key-value store"
|
||||
groups = ["redis"]
|
||||
@ -785,8 +794,8 @@ dependencies = [
|
||||
"async-timeout>=4.0.3; python_full_version < \"3.11.3\"",
|
||||
]
|
||||
files = [
|
||||
{file = "redis-6.0.0-py3-none-any.whl", hash = "sha256:a2e040aee2cdd947be1fa3a32e35a956cd839cc4c1dbbe4b2cdee5b9623fd27c"},
|
||||
{file = "redis-6.0.0.tar.gz", hash = "sha256:5446780d2425b787ed89c91ddbfa1be6d32370a636c8fdb687f11b1c26c1fa88"},
|
||||
{file = "redis-6.1.1-py3-none-any.whl", hash = "sha256:ed44d53d065bbe04ac6d76864e331cfe5c5353f86f6deccc095f8794fd15bb2e"},
|
||||
{file = "redis-6.1.1.tar.gz", hash = "sha256:88c689325b5b41cedcbdbdfd4d937ea86cf6dab2222a83e86d8a466e4b3d2600"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -794,7 +803,7 @@ name = "requests"
|
||||
version = "2.31.0"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Python HTTP for Humans."
|
||||
groups = ["docs"]
|
||||
groups = ["dev", "docs"]
|
||||
dependencies = [
|
||||
"certifi>=2017.4.17",
|
||||
"charset-normalizer<4,>=2",
|
||||
@ -808,29 +817,30 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.11.8"
|
||||
version = "0.14.2"
|
||||
requires_python = ">=3.7"
|
||||
summary = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
groups = ["dev"]
|
||||
files = [
|
||||
{file = "ruff-0.11.8-py3-none-linux_armv6l.whl", hash = "sha256:896a37516c594805e34020c4a7546c8f8a234b679a7716a3f08197f38913e1a3"},
|
||||
{file = "ruff-0.11.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ab86d22d3d721a40dd3ecbb5e86ab03b2e053bc93c700dc68d1c3346b36ce835"},
|
||||
{file = "ruff-0.11.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:258f3585057508d317610e8a412788cf726efeefa2fec4dba4001d9e6f90d46c"},
|
||||
{file = "ruff-0.11.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:727d01702f7c30baed3fc3a34901a640001a2828c793525043c29f7614994a8c"},
|
||||
{file = "ruff-0.11.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3dca977cc4fc8f66e89900fa415ffe4dbc2e969da9d7a54bfca81a128c5ac219"},
|
||||
{file = "ruff-0.11.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c657fa987d60b104d2be8b052d66da0a2a88f9bd1d66b2254333e84ea2720c7f"},
|
||||
{file = "ruff-0.11.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f2e74b021d0de5eceb8bd32919f6ff8a9b40ee62ed97becd44993ae5b9949474"},
|
||||
{file = "ruff-0.11.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9b5ef39820abc0f2c62111f7045009e46b275f5b99d5e59dda113c39b7f4f38"},
|
||||
{file = "ruff-0.11.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1dba3135ca503727aa4648152c0fa67c3b1385d3dc81c75cd8a229c4b2a1458"},
|
||||
{file = "ruff-0.11.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f024d32e62faad0f76b2d6afd141b8c171515e4fb91ce9fd6464335c81244e5"},
|
||||
{file = "ruff-0.11.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d365618d3ad747432e1ae50d61775b78c055fee5936d77fb4d92c6f559741948"},
|
||||
{file = "ruff-0.11.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4d9aaa91035bdf612c8ee7266153bcf16005c7c7e2f5878406911c92a31633cb"},
|
||||
{file = "ruff-0.11.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0eba551324733efc76116d9f3a0d52946bc2751f0cd30661564117d6fd60897c"},
|
||||
{file = "ruff-0.11.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:161eb4cff5cfefdb6c9b8b3671d09f7def2f960cee33481dd898caf2bcd02304"},
|
||||
{file = "ruff-0.11.8-py3-none-win32.whl", hash = "sha256:5b18caa297a786465cc511d7f8be19226acf9c0a1127e06e736cd4e1878c3ea2"},
|
||||
{file = "ruff-0.11.8-py3-none-win_amd64.whl", hash = "sha256:6e70d11043bef637c5617297bdedec9632af15d53ac1e1ba29c448da9341b0c4"},
|
||||
{file = "ruff-0.11.8-py3-none-win_arm64.whl", hash = "sha256:304432e4c4a792e3da85b7699feb3426a0908ab98bf29df22a31b0cdd098fac2"},
|
||||
{file = "ruff-0.11.8.tar.gz", hash = "sha256:6d742d10626f9004b781f4558154bb226620a7242080e11caeffab1a40e99df8"},
|
||||
{file = "ruff-0.14.2-py3-none-linux_armv6l.whl", hash = "sha256:7cbe4e593505bdec5884c2d0a4d791a90301bc23e49a6b1eb642dd85ef9c64f1"},
|
||||
{file = "ruff-0.14.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8d54b561729cee92f8d89c316ad7a3f9705533f5903b042399b6ae0ddfc62e11"},
|
||||
{file = "ruff-0.14.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5c8753dfa44ebb2cde10ce5b4d2ef55a41fb9d9b16732a2c5df64620dbda44a3"},
|
||||
{file = "ruff-0.14.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d0bbeffb8d9f4fccf7b5198d566d0bad99a9cb622f1fc3467af96cb8773c9e3"},
|
||||
{file = "ruff-0.14.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7047f0c5a713a401e43a88d36843d9c83a19c584e63d664474675620aaa634a8"},
|
||||
{file = "ruff-0.14.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bf8d2f9aa1602599217d82e8e0af7fd33e5878c4d98f37906b7c93f46f9a839"},
|
||||
{file = "ruff-0.14.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1c505b389e19c57a317cf4b42db824e2fca96ffb3d86766c1c9f8b96d32048a7"},
|
||||
{file = "ruff-0.14.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a307fc45ebd887b3f26b36d9326bb70bf69b01561950cdcc6c0bdf7bb8e0f7cc"},
|
||||
{file = "ruff-0.14.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:61ae91a32c853172f832c2f40bd05fd69f491db7289fb85a9b941ebdd549781a"},
|
||||
{file = "ruff-0.14.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1967e40286f63ee23c615e8e7e98098dedc7301568bd88991f6e544d8ae096"},
|
||||
{file = "ruff-0.14.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2877f02119cdebf52a632d743a2e302dea422bfae152ebe2f193d3285a3a65df"},
|
||||
{file = "ruff-0.14.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e681c5bc777de5af898decdcb6ba3321d0d466f4cb43c3e7cc2c3b4e7b843a05"},
|
||||
{file = "ruff-0.14.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e21be42d72e224736f0c992cdb9959a2fa53c7e943b97ef5d081e13170e3ffc5"},
|
||||
{file = "ruff-0.14.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b8264016f6f209fac16262882dbebf3f8be1629777cf0f37e7aff071b3e9b92e"},
|
||||
{file = "ruff-0.14.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5ca36b4cb4db3067a3b24444463ceea5565ea78b95fe9a07ca7cb7fd16948770"},
|
||||
{file = "ruff-0.14.2-py3-none-win32.whl", hash = "sha256:41775927d287685e08f48d8eb3f765625ab0b7042cc9377e20e64f4eb0056ee9"},
|
||||
{file = "ruff-0.14.2-py3-none-win_amd64.whl", hash = "sha256:0df3424aa5c3c08b34ed8ce099df1021e3adaca6e90229273496b839e5a7e1af"},
|
||||
{file = "ruff-0.14.2-py3-none-win_arm64.whl", hash = "sha256:ea9d635e83ba21569fbacda7e78afbfeb94911c9434aff06192d9bc23fd5495a"},
|
||||
{file = "ruff-0.14.2.tar.gz", hash = "sha256:98da787668f239313d9c902ca7c523fe11b8ec3f39345553a51b25abc4629c96"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1033,7 +1043,7 @@ name = "urllib3"
|
||||
version = "2.2.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
groups = ["docs"]
|
||||
groups = ["dev", "docs"]
|
||||
files = [
|
||||
{file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"},
|
||||
{file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"},
|
||||
|
||||
19
process-compose.yml
Normal file
19
process-compose.yml
Normal file
@ -0,0 +1,19 @@
|
||||
# Process compose for starting django
|
||||
version: "0.5"
|
||||
|
||||
processes:
|
||||
memcached:
|
||||
command: memcached
|
||||
availability:
|
||||
restart: "always"
|
||||
|
||||
mailpit:
|
||||
command: mailpit
|
||||
availability:
|
||||
restart: "always"
|
||||
environment:
|
||||
- "MP_MAX_MESSAGES=5000"
|
||||
- "MP_SMTP_AUTH_ACCEPT_ANY=1"
|
||||
- "MP_SMTP_AUTH_ALLOW_INSECURE=1"
|
||||
- "MP_SMTP_TLS_CERT=docker/mailpit/dev-cert.pem"
|
||||
- "MP_SMTP_TLS_KEY=docker/mailpit/dev-key.pem"
|
||||
@ -16,7 +16,7 @@ classifiers = [
|
||||
|
||||
dynamic = ["version", "README"]
|
||||
|
||||
requires-python = ">=3.8"
|
||||
requires-python = ">=3.9"
|
||||
dependencies = []
|
||||
|
||||
[project.optional-dependencies]
|
||||
@ -69,7 +69,7 @@ precision = 2
|
||||
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py38"
|
||||
target-version = "py39"
|
||||
line-length = 100
|
||||
indent-width = 4
|
||||
exclude = [
|
||||
@ -107,7 +107,7 @@ unfixable = []
|
||||
# ignore_missing_imports = true
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.8"
|
||||
python_version = "3.9"
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_defs = true
|
||||
disallow_any_unimported = false
|
||||
@ -162,4 +162,5 @@ dev = [
|
||||
"ruff>=0.3.2",
|
||||
"mock>=5.1.0",
|
||||
"pypng>=0.20220715.0",
|
||||
"requests>=2.31.0",
|
||||
]
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
set -e
|
||||
|
||||
[ -z "$CEMENT_VERSION" ] && CEMENT_VERSION="3.0"
|
||||
[ -z "$PYTHON_VERSIONS" ] && PYTHON_VERSIONS="3.8 3.9 3.10 3.11 3.12 3.13"
|
||||
[ -z "$PYTHON_VERSIONS" ] && PYTHON_VERSIONS="3.9 3.10 3.11 3.12 3.13 3.14"
|
||||
|
||||
function smoke-test {
|
||||
pyver=$1
|
||||
@ -19,15 +19,15 @@ function smoke-test {
|
||||
python:$pyver \
|
||||
/bin/bash
|
||||
|
||||
docker exec -it cement-cli-smoke-test /bin/bash -c "cd /src ; pip install `ls dist/cement-*.tar.gz`[cli]"
|
||||
tmp=$(docker exec cement-cli-smoke-test /bin/bash -c "mktemp -d")
|
||||
docker exec cement-cli-smoke-test /bin/bash -c "cd /src ; pip install `ls dist/cement-*.tar.gz`[cli]"
|
||||
tmp=$(docker exec -t cement-cli-smoke-test /bin/bash -c "mktemp -d")
|
||||
|
||||
|
||||
|
||||
### verify help output
|
||||
|
||||
res=$(docker exec cement-cli-smoke-test /bin/bash -c "cement --version")
|
||||
echo "$res" | grep "Cement Framework $CEMENT_VERSION.\d"
|
||||
echo "$res" | grep "Python $pyver.\d"
|
||||
echo "$res" | grep "Cement Framework $CEMENT_VERSION.[0-9]"
|
||||
echo "$res" | grep "Python $pyver.[0-9]"
|
||||
echo "$res" | grep "Platform Linux.*"
|
||||
res=$(docker exec cement-cli-smoke-test /bin/bash -c "cement --help")
|
||||
echo "$res" | grep "Cement Framework Developer Tools"
|
||||
@ -45,37 +45,37 @@ function smoke-test {
|
||||
echo "$res" | grep "destination directory path"
|
||||
echo "$res" | grep -- "-D, --defaults"
|
||||
|
||||
|
||||
|
||||
### generate a project
|
||||
|
||||
docker exec cement-cli-smoke-test /bin/bash -c "cement generate project -D $tmp/myapp"
|
||||
docker exec cement-cli-smoke-test /bin/bash -c "cd $tmp/myapp ; pip install -r requirements.txt"
|
||||
docker exec cement-cli-smoke-test /bin/bash -c "cd $tmp/myapp ; pip install setuptools"
|
||||
docker exec cement-cli-smoke-test /bin/bash -c "cd $tmp/myapp ; python setup.py install"
|
||||
res=$(docker exec cement-cli-smoke-test /bin/bash -c "myapp --version")
|
||||
echo "$res" | grep "Cement Framework $CEMENT_VERSION\.\d"
|
||||
echo "$res" | grep "Python $pyver.\d"
|
||||
res=$(docker exec -t cement-cli-smoke-test /bin/bash -c "myapp --version")
|
||||
echo "$res" | grep "Cement Framework $CEMENT_VERSION\.[0-9]"
|
||||
echo "$res" | grep "Python $pyver.[0-9]"
|
||||
echo "$res" | grep "Platform Linux.*"
|
||||
|
||||
|
||||
|
||||
### generate a script
|
||||
|
||||
docker exec cement-cli-smoke-test /bin/bash -c "cement generate script -D $tmp/myscript"
|
||||
res=$(docker exec cement-cli-smoke-test /bin/bash -c "python $tmp/myscript/myscript.py --version")
|
||||
res=$(docker exec -t cement-cli-smoke-test /bin/bash -c "python $tmp/myscript/myscript.py --version")
|
||||
echo "$res" | grep "myscript v0.0.1"
|
||||
|
||||
|
||||
|
||||
### generate an extension
|
||||
|
||||
docker exec cement-cli-smoke-test /bin/bash -c "cement generate extension -D $tmp/myapp/myapp/ext"
|
||||
res=$(docker exec cement-cli-smoke-test /bin/bash -c "cat $tmp/myapp/myapp/ext/ext_myextension.py")
|
||||
res=$(docker exec -t cement-cli-smoke-test /bin/bash -c "cat $tmp/myapp/myapp/ext/ext_myextension.py")
|
||||
echo "$res" | grep "myextension_pre_run_hook"
|
||||
|
||||
|
||||
### generate a plugin
|
||||
|
||||
docker exec cement-cli-smoke-test /bin/bash -c "cement generate plugin -D $tmp/myapp/myapp/plugins"
|
||||
res=$(docker exec cement-cli-smoke-test /bin/bash -c "cat $tmp/myapp/myapp/plugins/myplugin/controllers/myplugin.py")
|
||||
res=$(docker exec -t cement-cli-smoke-test /bin/bash -c "cat $tmp/myapp/myapp/plugins/myplugin/controllers/myplugin.py")
|
||||
echo "$res" | grep "class MyPlugin(Controller)"
|
||||
|
||||
### finish
|
||||
@ -93,4 +93,4 @@ for pyver in $PYTHON_VERSIONS; do
|
||||
echo -n "python $pyver . . . "
|
||||
smoke-test $pyver 2>> tmp/cli-smoke-test.out 1>> tmp/cli-smoke-test.out
|
||||
echo "ok"
|
||||
done
|
||||
done
|
||||
|
||||
@ -6,6 +6,6 @@ def test_version():
|
||||
# ensure that we bump things properly on version changes
|
||||
assert backend.VERSION[0] == 3
|
||||
assert backend.VERSION[1] == 0
|
||||
assert backend.VERSION[2] == 14
|
||||
assert backend.VERSION[2] == 15
|
||||
assert backend.VERSION[3] == 'final'
|
||||
assert backend.VERSION[4] == 0
|
||||
|
||||
@ -77,24 +77,26 @@ def test_bogus_group(rando):
|
||||
env.switch()
|
||||
|
||||
|
||||
def _daemon_target(pid_file):
|
||||
"""Target function for daemon test subprocess."""
|
||||
with TestApp(argv=['--daemon'], extensions=['daemon']) as app:
|
||||
app.config.set('daemon', 'pid_file', pid_file)
|
||||
|
||||
try:
|
||||
# FIX ME: Can't daemonize, because nose/pytest lose sight of it
|
||||
app.daemonize()
|
||||
app.run()
|
||||
finally:
|
||||
app.close()
|
||||
ext_daemon.cleanup(app)
|
||||
|
||||
|
||||
def test_daemon(tmp):
|
||||
os.remove(tmp.file)
|
||||
from cement.utils import shell
|
||||
|
||||
# Test in a sub-process to avoid hangup
|
||||
def target():
|
||||
with TestApp(argv=['--daemon'], extensions=['daemon']) as app:
|
||||
app.config.set('daemon', 'pid_file', tmp.file)
|
||||
|
||||
try:
|
||||
# FIX ME: Can't daemonize, because nose/pytest lose sight of it
|
||||
app.daemonize()
|
||||
app.run()
|
||||
finally:
|
||||
app.close()
|
||||
ext_daemon.cleanup(app)
|
||||
|
||||
p = shell.spawn_process(target)
|
||||
p = shell.spawn_process(_daemon_target, args=(tmp.file,))
|
||||
p.join()
|
||||
assert p.exitcode == 0
|
||||
|
||||
|
||||
@ -64,8 +64,8 @@ def test_smtp_send(rando):
|
||||
assert msg['To'][0]['Address'] == f'to-{rando}@localhost'
|
||||
assert msg['Subject'] == f'UNIT TEST > {rando}'
|
||||
assert msg['Attachments'] == 0
|
||||
assert msg['Cc'] == []
|
||||
assert msg['Bcc'] == []
|
||||
assert msg['Cc'] in [None, []]
|
||||
assert msg['Bcc'] in [None, []]
|
||||
|
||||
delete_msg(msg['ID'])
|
||||
|
||||
|
||||
@ -21,34 +21,44 @@ class WatchdogApp(TestApp):
|
||||
def test_watchdog(tmp):
|
||||
# The exception is getting raised, but for some reason it's not being
|
||||
# caught by a with raises() block, so I'm mocking it out instead.
|
||||
# Clear any existing mock first
|
||||
if hasattr(MyEventHandler, 'on_any_event'):
|
||||
if hasattr(MyEventHandler.on_any_event, 'reset_mock'):
|
||||
MyEventHandler.on_any_event.reset_mock()
|
||||
MyEventHandler.on_any_event = Mock()
|
||||
with WatchdogApp() as app:
|
||||
app.watchdog.add(tmp.dir, event_handler=MyEventHandler)
|
||||
app.run()
|
||||
try:
|
||||
with WatchdogApp() as app:
|
||||
app.watchdog.add(tmp.dir, event_handler=MyEventHandler)
|
||||
app.run()
|
||||
|
||||
file_path = fs.join(tmp.dir, 'test.file')
|
||||
# trigger an event
|
||||
f = open(file_path, 'w')
|
||||
f.write('test data')
|
||||
f.close()
|
||||
time.sleep(1)
|
||||
file_path = fs.join(tmp.dir, 'test.file')
|
||||
# trigger an event
|
||||
f = open(file_path, 'w')
|
||||
f.write('test data')
|
||||
f.close()
|
||||
time.sleep(1)
|
||||
|
||||
# 5 or 6 separate calls: See print(MyEventHandler.on_any_event.mock_calls)
|
||||
# 5 or 6 separate calls: See print(MyEventHandler.on_any_event.mock_calls)
|
||||
|
||||
# Python < 3.11
|
||||
# Tmp File created
|
||||
# Tmp Dir modified
|
||||
# Tmp File modified
|
||||
# Tmp File closed
|
||||
# Tmp Dir modified
|
||||
# Python < 3.11
|
||||
# Tmp File created
|
||||
# Tmp Dir modified
|
||||
# Tmp File modified
|
||||
# Tmp File closed
|
||||
# Tmp Dir modified
|
||||
|
||||
# In Python >= 3.11 this has one additional
|
||||
# Tmp File opened
|
||||
# In Python >= 3.11 this has one additional
|
||||
# Tmp File opened
|
||||
|
||||
# But on Travis... this isn't resulting in the same counts so
|
||||
# fudging the test a little... it's 5 or 6
|
||||
# But on Travis... this isn't resulting in the same counts so
|
||||
# fudging the test a little... it's 3-6 depending on platform/timing
|
||||
|
||||
assert MyEventHandler.on_any_event.call_count in [5, 6]
|
||||
assert MyEventHandler.on_any_event.call_count in [3, 4, 5, 6]
|
||||
finally:
|
||||
# Reset mock to avoid interfering with other tests
|
||||
if (hasattr(MyEventHandler, 'on_any_event') and
|
||||
hasattr(MyEventHandler.on_any_event, 'reset_mock')):
|
||||
MyEventHandler.on_any_event.reset_mock()
|
||||
|
||||
|
||||
def test_watchdog_app_paths(tmp):
|
||||
@ -60,40 +70,50 @@ def test_watchdog_app_paths(tmp):
|
||||
(tmp.dir, WatchdogEventHandler)
|
||||
]
|
||||
|
||||
# Clear any existing mock first
|
||||
if hasattr(WatchdogEventHandler, 'on_any_event'):
|
||||
if hasattr(WatchdogEventHandler.on_any_event, 'reset_mock'):
|
||||
WatchdogEventHandler.on_any_event.reset_mock()
|
||||
WatchdogEventHandler.on_any_event = Mock()
|
||||
with MyApp() as app:
|
||||
app.run()
|
||||
try:
|
||||
with MyApp() as app:
|
||||
app.run()
|
||||
|
||||
WatchdogEventHandler.on_any_event.reset_mock()
|
||||
# trigger an event
|
||||
f = open(fs.join(tmp.dir, 'test.file'), 'w')
|
||||
f.write('test data')
|
||||
f.close()
|
||||
time.sleep(1)
|
||||
WatchdogEventHandler.on_any_event.reset_mock()
|
||||
# trigger an event
|
||||
f = open(fs.join(tmp.dir, 'test.file'), 'w')
|
||||
f.write('test data')
|
||||
f.close()
|
||||
time.sleep(1)
|
||||
|
||||
# 10 or 12 separate calls
|
||||
# See print(MyEventHandler.on_any_event.mock_calls)
|
||||
# 10 or 12 separate calls
|
||||
# See print(MyEventHandler.on_any_event.mock_calls)
|
||||
|
||||
# Python < 3.11
|
||||
# Tmp File created
|
||||
# Tmp File created
|
||||
# Tmp Dir modified
|
||||
# Tmp Dir modified
|
||||
# Tmp File modified
|
||||
# Tmp File modified
|
||||
# Tmp File closed
|
||||
# Tmp File closed
|
||||
# Tmp Dir modified
|
||||
# Tmp Dir modified
|
||||
# Python < 3.11
|
||||
# Tmp File created
|
||||
# Tmp File created
|
||||
# Tmp Dir modified
|
||||
# Tmp Dir modified
|
||||
# Tmp File modified
|
||||
# Tmp File modified
|
||||
# Tmp File closed
|
||||
# Tmp File closed
|
||||
# Tmp Dir modified
|
||||
# Tmp Dir modified
|
||||
|
||||
# In Python >= 3.11 this has one additional
|
||||
# Tmp File opened
|
||||
# Tmp File opened
|
||||
# In Python >= 3.11 this has one additional
|
||||
# Tmp File opened
|
||||
# Tmp File opened
|
||||
|
||||
# But on Travis... this isn't resulting in the same counts so
|
||||
# fudging the test a little... it's 10 or 12
|
||||
# But on Travis... this isn't resulting in the same counts so
|
||||
# fudging the test a little... it's 6-12 depending on platform/timing
|
||||
|
||||
assert WatchdogEventHandler.on_any_event.call_count in [10, 12]
|
||||
assert WatchdogEventHandler.on_any_event.call_count in [6, 8, 10, 12]
|
||||
finally:
|
||||
# Reset mock to avoid interfering with other tests
|
||||
if (hasattr(WatchdogEventHandler, 'on_any_event') and
|
||||
hasattr(WatchdogEventHandler.on_any_event, 'reset_mock')):
|
||||
WatchdogEventHandler.on_any_event.reset_mock()
|
||||
|
||||
|
||||
def test_watchdog_app_paths_bad_spec(tmp):
|
||||
@ -109,33 +129,43 @@ def test_watchdog_app_paths_bad_spec(tmp):
|
||||
|
||||
|
||||
def test_watchdog_default_event_handler(tmp):
|
||||
# Clear any existing mock first
|
||||
if hasattr(WatchdogEventHandler, 'on_any_event'):
|
||||
if hasattr(WatchdogEventHandler.on_any_event, 'reset_mock'):
|
||||
WatchdogEventHandler.on_any_event.reset_mock()
|
||||
WatchdogEventHandler.on_any_event = Mock()
|
||||
with WatchdogApp() as app:
|
||||
app.watchdog.add(tmp.dir)
|
||||
app.run()
|
||||
try:
|
||||
with WatchdogApp() as app:
|
||||
app.watchdog.add(tmp.dir)
|
||||
app.run()
|
||||
|
||||
f = open(fs.join(tmp.dir, 'test.file'), 'w')
|
||||
f.write('test data')
|
||||
f.close()
|
||||
time.sleep(1)
|
||||
f = open(fs.join(tmp.dir, 'test.file'), 'w')
|
||||
f.write('test data')
|
||||
f.close()
|
||||
time.sleep(1)
|
||||
|
||||
# 5 or 6 separate calls
|
||||
# See print(MyEventHandler.on_any_event.mock_calls)
|
||||
# 5 or 6 separate calls
|
||||
# See print(MyEventHandler.on_any_event.mock_calls)
|
||||
|
||||
# Python < 3.11
|
||||
# Tmp File created
|
||||
# Tmp Dir modified
|
||||
# Tmp File modified
|
||||
# Tmp File closed
|
||||
# Tmp Dir modified
|
||||
# Python < 3.11
|
||||
# Tmp File created
|
||||
# Tmp Dir modified
|
||||
# Tmp File modified
|
||||
# Tmp File closed
|
||||
# Tmp Dir modified
|
||||
|
||||
# In Python >= 3.11 this has one additional
|
||||
# Tmp File opened
|
||||
# In Python >= 3.11 this has one additional
|
||||
# Tmp File opened
|
||||
|
||||
# But on Travis... this isn't resulting in the same counts so
|
||||
# fudging the test a little... it's 5 or 6
|
||||
# But on Travis... this isn't resulting in the same counts so
|
||||
# fudging the test a little... it's 3-6 depending on platform/timing
|
||||
|
||||
assert WatchdogEventHandler.on_any_event.call_count in [5, 6]
|
||||
assert WatchdogEventHandler.on_any_event.call_count in [3, 4, 5, 6]
|
||||
finally:
|
||||
# Reset mock to avoid interfering with other tests
|
||||
if (hasattr(WatchdogEventHandler, 'on_any_event') and
|
||||
hasattr(WatchdogEventHandler.on_any_event, 'reset_mock')):
|
||||
WatchdogEventHandler.on_any_event.reset_mock()
|
||||
|
||||
|
||||
def test_watchdog_bad_path(tmp):
|
||||
|
||||
0
tmp/.gitkeep
Normal file
0
tmp/.gitkeep
Normal file
Loading…
Reference in New Issue
Block a user