From 6d96f8dbf295ae90bf50f39e00e304b5a8425156 Mon Sep 17 00:00:00 2001 From: Ryan Galloway Date: Thu, 23 Jul 2026 05:37:14 -0700 Subject: [PATCH 1/4] Fix EnvVar template parsing on Python 3.14 and test 3.14 in CI --- .github/workflows/tests.yml | 2 +- .gitignore | 4 +++- lib/envstack/encrypt.py | 1 + lib/envstack/env.py | 2 +- pyproject.toml | 3 +++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9b16a5c..c3ac1f4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/.gitignore b/.gitignore index 3626491..538fad3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,6 @@ venv*/ .vscode/ encrypted.env baketest.env -out.env \ No newline at end of file +out.env +.codex +.agents/ \ No newline at end of file diff --git a/lib/envstack/encrypt.py b/lib/envstack/encrypt.py index 3cb6642..fe28fa9 100644 --- a/lib/envstack/encrypt.py +++ b/lib/envstack/encrypt.py @@ -57,6 +57,7 @@ from cryptography.exceptions import InvalidTag from cryptography.hazmat.primitives import padding from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + CRYPTOGRAPHY_AVAILABLE = True except ImportError as err: log.debug("cryptography module not available: %s", err) diff --git a/lib/envstack/env.py b/lib/envstack/env.py index abea76e..ac877eb 100644 --- a/lib/envstack/env.py +++ b/lib/envstack/env.py @@ -248,7 +248,7 @@ def vars(self): >>> v.vars() ['FOO', 'BAR'] """ - matches = super(EnvVar, self).pattern.findall(str(self.template)) + matches = type(self).pattern.findall(str(self.template)) return [key for match in matches for key in match if key] diff --git a/pyproject.toml b/pyproject.toml index 33528f5..1a44242 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,9 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] keywords = [ "environment", From 524cc1c9662348a8f4b5bf336e7186b99f05d06a Mon Sep 17 00:00:00 2001 From: Ryan Galloway Date: Thu, 23 Jul 2026 05:48:55 -0700 Subject: [PATCH 2/4] Pin cryptography for Python 3.8 support, suppress warnings --- lib/envstack/encrypt.py | 16 ++++++++++++---- pyproject.toml | 3 ++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/envstack/encrypt.py b/lib/envstack/encrypt.py index fe28fa9..20d3a2f 100644 --- a/lib/envstack/encrypt.py +++ b/lib/envstack/encrypt.py @@ -37,6 +37,7 @@ import binascii import os import secrets +import warnings from base64 import b64decode, b64encode from functools import wraps @@ -53,10 +54,17 @@ algorithms = None modes = None try: - from cryptography.fernet import Fernet, InvalidToken - from cryptography.exceptions import InvalidTag - from cryptography.hazmat.primitives import padding - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + # cryptography emits a Python 3.8 deprecation warning during import. + with warnings.catch_warnings(): + warnings.filterwarnings( + "ignore", + message="Python 3\\.8 is no longer supported by the Python core team.*", + category=Warning, + ) + from cryptography.fernet import Fernet, InvalidToken + from cryptography.exceptions import InvalidTag + from cryptography.hazmat.primitives import padding + from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes CRYPTOGRAPHY_AVAILABLE = True except ImportError as err: diff --git a/pyproject.toml b/pyproject.toml index 1a44242..3f37790 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,8 @@ license = { text = "BSD 3-Clause License" } authors = [{ name = "Ryan Galloway", email = "ryan@rsgalloway.com" }] dependencies = [ "PyYAML>=5.1.2", - "cryptography>=43.0.1", + 'cryptography>=43.0.1,<47; python_version < "3.9"', + 'cryptography>=43.0.1; python_version >= "3.9"', ] classifiers = [ "Development Status :: 4 - Beta", From 455854852093126e7bd77cd406dbf012ad1d3185 Mon Sep 17 00:00:00 2001 From: Ryan Galloway Date: Thu, 23 Jul 2026 06:00:44 -0700 Subject: [PATCH 3/4] Bump version to 1.0.3 and update changelog --- CHANGELOG.md | 14 ++++++++++++++ lib/envstack/__init__.py | 2 +- pyproject.toml | 2 +- pytest.ini | 2 ++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c185d42..c1c49a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- +## [1.0.3] - 2026-07-23 + +### Changed +- add Python 3.14 to the GitHub Actions test matrix +- update published Python version classifiers through 3.14 +- constrain `cryptography` to `<47` on Python 3.8 while allowing newer runtimes to resolve current releases +- limit pytest discovery to the `tests/` suite and ignore `tmp/` helper files + +### Fixed +- restore Python 3.14 compatibility in `EnvVar.vars()` by avoiding `string.Template` pattern access that now raises under 3.14 +- suppress the `cryptography` Python 3.8 deprecation warning during import so `envstack` subprocess tests and CLI startup remain quiet on supported 3.8 installs + +--- + ## [1.0.2] - 2026-04-01 ### Changed diff --git a/lib/envstack/__init__.py b/lib/envstack/__init__.py index 8d9385a..4a26f98 100644 --- a/lib/envstack/__init__.py +++ b/lib/envstack/__init__.py @@ -34,7 +34,7 @@ """ __prog__ = "envstack" -__version__ = "1.0.2" +__version__ = "1.0.3" from envstack.env import clear, init, revert, save # noqa: F401 from envstack.env import load_environ, resolve_environ # noqa: F401 diff --git a/pyproject.toml b/pyproject.toml index 3f37790..21bfd2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "envstack" -version = "1.0.2" +version = "1.0.3" description = "Environment variable composition layer for tools and processes." readme = { file = "README.md", content-type = "text/markdown" } requires-python = ">=3.6" diff --git a/pytest.ini b/pytest.ini index 2f5246f..4d7cb7b 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,5 @@ [pytest] markers = integration: tests that run real subprocesses (slower / OS-dependent) +testpaths = tests +norecursedirs = tmp From 892ab4c5091f2ed4350149ab6094824bda8df322 Mon Sep 17 00:00:00 2001 From: Ryan Galloway Date: Thu, 23 Jul 2026 06:08:59 -0700 Subject: [PATCH 4/4] Tighten warning filter to DeprecationWarning, add roadmap doc --- docs/index.md | 10 ++++++++++ docs/roadmap.md | 40 ++++++++++++++++++++++++++++++++++++++++ lib/envstack/encrypt.py | 5 +++-- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 docs/roadmap.md diff --git a/docs/index.md b/docs/index.md index 89033d4..0b9d852 100644 --- a/docs/index.md +++ b/docs/index.md @@ -71,6 +71,16 @@ envstack is commonly used for: - Pipeline and DCC tooling - Shared, hierarchical environment configuration +## Project docs + +- [API](api.md) +- [Comparison](comparison.md) +- [Design](design.md) +- [Examples](examples.md) +- [FAQ](faq.md) +- [Roadmap](roadmap.md) +- [Secrets](secrets.md) + ## A simple example ```yaml diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000..230a882 --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,40 @@ +# Roadmap + +This document tracks likely near-term improvements and areas we want to +explore as envstack evolves. + +## Near-term backlog + +The following items are active candidates for near-term roadmap work: + +- API documentation source structure +- ternary-style expansion modifier +- regex expansion modifier +- version tag support + +## Performance and benchmarking + +envstack does not yet have dedicated benchmark tooling or performance +regression coverage. + +This is likely worth adding soon, especially before larger changes to +environment resolution, shell startup, or subprocess wrapping. + +Two possible directions: + +- Build custom benchmark tools tailored to envstack, similar to the benchmark + utilities used in sibling projects like `pyseq` and `snapfs` +- Evaluate an off-the-shelf benchmark framework such as `asv` for repeatable + performance tracking over time + +Initial benchmark candidates: + +- stack loading and environment resolution +- repeated `envstack -- [COMMAND]` subprocess startup cost +- shell launch overhead +- variable tracing and path expansion on larger environment stacks + +Future benchmark work should ideally cover both: + +- one-off profiling for targeted optimization work +- regression checks that help catch performance drift across releases diff --git a/lib/envstack/encrypt.py b/lib/envstack/encrypt.py index 20d3a2f..ac2061f 100644 --- a/lib/envstack/encrypt.py +++ b/lib/envstack/encrypt.py @@ -58,8 +58,9 @@ with warnings.catch_warnings(): warnings.filterwarnings( "ignore", - message="Python 3\\.8 is no longer supported by the Python core team.*", - category=Warning, + message=r"Python 3\.8 is no longer supported by the Python core team.*", + category=DeprecationWarning, + module=r"cryptography(\..*)?$", ) from cryptography.fernet import Fernet, InvalidToken from cryptography.exceptions import InvalidTag