← Back to changelog
Release v0.6.0

Pyvider 0.6.0: Correctness at the protocol boundary

Pyvider 0.6.0 focused on correctness: failures that previously looked successful now stop at the boundary where Pyvider can explain them. It also added the planning and migration primitives provider authors need as their schemas evolve.

Breaking changes

  • a_obj() now preserves the nested schema. Object attributes are represented as Schema.Attribute.nested_type, so Terraform can see each member’s required, optional, and computed flags. An object type that also carries block types is rejected instead of being published as a different schema than its author declared.
  • Inert requires_replace declarations are rejected. The flag never had an effect on write-only attributes or inside nested blocks and object-typed attributes. Those declarations now fail where they are written, with an alternative for each case.
  • Identity attributes cannot declare defaults. Identity is assigned by the provider and returned unchanged on import, leaving no point at which an identity default could apply.

Added

  • Recursive PvsAttribute.default resolution. Defaults are applied to decoded configuration and reconciled into plans, including inside object attributes and nested blocks at any depth. A default implies Computed, and removing a configured argument returns it to its default.
  • Replacement planning. A schema attribute can set requires_replace=True for ordinary immutable values, while a plan hook can call ctx.require_replace(path) when replacement depends on the values themselves. Create and destroy plans do not receive invalid replacement paths, and an unknown planned value is treated as a change.
  • Versioned resource-state migration. s_resource(..., version=N) declares the current state version, and BaseResource.upgrade_state(version, raw_state) can migrate state written under an earlier one. Resources that stay at the default version continue to use the existing behavior.
  • Validation after an upgrade. Migrated state is checked against the current schema before Pyvider returns it. Invalid migrations produce a diagnostic and leave the stored state untouched.

Fixed

The release’s audit concentrated on paths where the operation could succeed while returning, storing, or hiding the wrong result:

  • Function arguments with Python defaults are now bound correctly instead of being converted and then dropped.
  • A short WriteStateBytes stream is rejected before it can replace valid state with truncated bytes.
  • ReadStateBytes backend failures now carry the range Terraform expects, so Terraform can report the diagnostic instead of panicking. State-store path encoding also handles names ending in a dot without relying on platform-specific filename behavior.
  • Values loaded from pyvider.toml, including the private-state secret and documented logging level, now participate in typed configuration instead of being parsed and ignored.
  • MoveResourceState is authorized by the target resource instead of accepting every cross-type move and copying state blindly.
  • @requires_capability injects capabilities into synchronous methods as well as asynchronous ones.
  • The _delegate safety net resolves the correct RPC response type, so missing handlers and escaped exceptions become diagnostics instead of gRPC or serialization failures.
  • Refinement validation accepts valid unknown-to-known transitions across objects, lists, tuples, maps, and sets.
  • Defaults inside list and set elements stay paired with the configuration element they came from.
  • Replacement rules are actionable: unsupported write-only and nested declarations fail early and point authors to a companion version attribute or ctx.require_replace().
  • Diagnostic attribute paths use CtyPath.parse, preserving names such as retention-days and rejecting malformed paths.
  • State-store filesystem work no longer blocks the event loop during validation and configuration.
  • tfprotov6.adapters is a regular packaged module, so stricter build backends cannot omit it from a wheel.

Changed

  • The minimum pyvider-cty version is now 0.5.2, providing schema-aware CtyPath parsing.
  • Ruff gates on defect-oriented rules rather than a blanket style policy.
  • Every function under src/ is held below a McCabe complexity of 8, with branch and statement limits enabled and no per-file exemptions.
  • UpgradeResourceState resolves the requested resource strictly and reports an unregistered type instead of passing its state through.

The complete audit trail is in the Pyvider v0.6.0 release.