Skip to content

typing: relax ChangelogSourceDict / ChangelogChangeSectionsDict to allow arbitrary section keys#4500

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/relax-changelogtyping-support
Draft

typing: relax ChangelogSourceDict / ChangelogChangeSectionsDict to allow arbitrary section keys#4500
Copilot wants to merge 2 commits into
mainfrom
copilot/relax-changelogtyping-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 11, 2026

ChangelogSourceDict and ChangelogChangeSectionsDict hard-coded the seven current changelog section names as TypedDict fields, blocking a per-entry directory reader where sections are arbitrary runtime-validated strings.

Changes

  • ChangelogSourceDictdict[str, Any]
    TypedDict cannot mix a required typed date field with arbitrary string keys, so a plain alias is the correct shape.

  • ChangelogChangeSectionsDictdict[str, ChangeList]
    Section name → list-of-entries mapping with no hard-coded keys.

  • ChangelogDictdict[str, Any]
    Previously inherited from both BaseChangelogDict and ChangelogChangeSectionsDict; TypedDict cannot inherit from a plain dict alias, so collapsed to a dict alias. The cast(typing.ChangelogDict, …) site in AChangelog.get_data() is unaffected.

  • Removed the # This should match envoy:changelogs/sections.yaml comments; section validation is now a runtime concern.

Purely a typing change — no behavioural impact.

Original prompt

Toolshed PR 1 — Relax ChangelogSourceDict / ChangelogChangeSectionsDict typing

This is the first PR in the implementation plan for per-entry changelog layout support (see issue #4498 and plan at plans/per-entry-changelog-4498.md, PR #4499 for full context).

Background

Envoy is migrating from a single monolithic changelogs/current.yaml to a per-entry layout:

changelogs/current/<section>/<area>__<slug>.rst

Where <section> must match a key in changelogs/sections.yaml. To support this in toolshed, the section names need to be treated as arbitrary runtime-validated strings rather than hard-coded type system keys.

Problem

In py/envoy.base.utils/envoy/base/utils/typing.py:

  • Lines 34–43: ChangelogSourceDict is a TypedDict that hard-codes the seven current section names (changes, behavior_changes, minor_behavior_changes, bug_fixes, removed_config_or_runtime, new_features, deprecated) plus date.
  • Lines 45–54: ChangelogChangeSectionsDict repeats the same hard-coded set.
  • Line 35: A comment even acknowledges the smell: # This should match envoy:changelogs/sections.yaml.

With per-entry files, sections become arbitrary directory names that are validated at runtime against changelogs/sections.yaml. Hard-coding them in the type system blocks PR 2 (the per-entry directory reader) which produces a ChangelogDict whose section keys are not statically known.

Required changes

  1. In py/envoy.base.utils/envoy/base/utils/typing.py:

    • Replace ChangelogChangeSectionsDict so it represents an arbitrary mapping of section name → list of ChangelogChangeDict. The cleanest approach is a type alias:
      ChangelogChangeSectionsDict = Dict[str, List["ChangelogChangeDict"]]
      (Use whichever import style — typing.Dict/List vs PEP 585 dict/list — matches the rest of the file.)
    • Replace ChangelogSourceDict so it carries a required date field plus arbitrary section keys mapping to List[ChangelogChangeDict]. Since TypedDict cannot mix a typed date field with arbitrary string keys, the simplest correct shape is also a plain mapping alias, e.g.:
      ChangelogSourceDict = Dict[str, Any]
      OR keep it as a TypedDict with only date typed and rely on the runtime parser to validate sections. Pick whichever is least disruptive to existing call sites; the goal is simply that arbitrary section names no longer trigger type errors.
    • Remove the now-misleading # This should match envoy:changelogs/sections.yaml comment (or rephrase it to point at the runtime validator).
  2. Verify the only consumer of these types — the cast(ChangelogSourceDict, ...) site in AChangelog.get_data() around line 135 of py/envoy.base.utils/envoy/base/utils/abstract/project/changelog.py — still type-checks. No behavioural change is expected.

  3. Run mypy over py/envoy.base.utils and fix any fallout (there should be none beyond the cast site).

Constraints

  • No behavioural change. This PR is typing-only.
  • No changes to changelog.py parsing logic — that comes in PR 2.
  • No changes to tests unless mypy/pytest currently asserts on the exact TypedDict shape (it shouldn't).
  • Existing CI (lint, mypy, pytest for envoy.base.utils) must remain green.

Acceptance criteria

  • ChangelogSourceDict and ChangelogChangeSectionsDict no longer enumerate the seven hard-coded section keys.
  • mypy passes for py/envoy.base.utils.
  • All existing py/envoy.base.utils tests pass unchanged.
  • Comment on (formerly) line 35 referencing envoy:changelogs/sections.yaml is removed or updated.

Reference

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: seems like we have a plan @envoyproxy/toolshed/files/plans/per-entry-changelog-4498.md

see also @envoyproxy/toolshed/pull/4499 @envoyproxy/toolshed/issues/4498

where do we start

Assistant: Per the plan's suggested landing order, you start with Toolshed PR 1: relax the TypedDict typing in py/envoy.base.utils/envoy/base/utils/typing.py.

Why start there

It's the safest, most isolated change:

  • No behavior change — pure typing only; mypy catches regressions.
  • Unblocks PR 2 — the per-entry directory reader needs ChangelogSourceDict / ChangelogChangeSectionsDict to not hard-code the seven section keys, since with per-entry files sections become arbitrary directory names validated against changelogs/sections.yaml at runtime.
  • Low blast radius — the only consumer is the cast() target in AChangelog.get_data() (line 135 of changelog.py); parsed values are unchanged.

What PR 1...

This pull request was created from Copilot chat.

@netlify
Copy link
Copy Markdown

netlify Bot commented May 11, 2026

Deploy Preview for nifty-bassi-e26446 ready!

Name Link
🔨 Latest commit 49056c2
🔍 Latest deploy log https://app.netlify.com/projects/nifty-bassi-e26446/deploys/6a02037bff9f5f0008ae90ef
😎 Deploy Preview https://deploy-preview-4500--nifty-bassi-e26446.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI changed the title [WIP] Relax ChangelogSourceDict and ChangelogChangeSectionsDict typing typing: relax ChangelogSourceDict / ChangelogChangeSectionsDict to allow arbitrary section keys May 11, 2026
Copilot AI requested a review from phlax May 11, 2026 16:28
Copilot finished work on behalf of phlax May 11, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants