Skip to content

Preserve an empty TLS table in envconfig dict conversion - #2054

Open
Jackmeson1 wants to merge 1 commit into
temporalio:mainfrom
Jackmeson1:fix/temporal-envconfig-empty-tls
Open

Jackmeson1 wants to merge 1 commit into
temporalio:mainfrom
Jackmeson1:fix/temporal-envconfig-empty-tls

Conversation

@Jackmeson1

Copy link
Copy Markdown

What was changed

ClientConfigProfile.to_dict() now keeps tls whenever the profile has a TLS config, and ClientConfigTLS.from_dict() distinguishes an empty dictionary from None. This preserves an empty TLS table through profile and whole-config dictionary round trips.

A hand-written {"tls": {}} now gives ClientConfigTLS(), matching an empty TLS table in TOML. None still means no TLS configuration.

Why?

On 01af1f6, an empty [profile.default.tls] table loads as ClientConfigTLS(), but two truthiness checks lose it during dictionary conversion: to_dict() omits the empty dictionary, and from_dict({}) returns None.

The reproduced round trip leaves the profile's connect config without a tls key. From the client configuration code, this disables TLS for a host:port address without an API key or an explicit TLS override. API-key profiles still enable TLS automatically. Direct loading, absent TLS, explicit disabled = false/true, and populated TLS tables retain their behavior.

Checklist

  1. Related: none. This is a small bug fix.

  2. How was this tested:

    Outside-sandbox validation on Linux x86_64 (Colab), using the Rust bridge built from this checkout and pytest 9.1.1:

    • The new tests check direct empty/absent TLS conversion and whole-config round trips for no TLS table, an empty table, and disabled = false/true. They use the real bridge loader and compare connection configurations; they do not make network connections.
    • Against 01af1f6, the direct test and empty-table case fail because tls is missing; the three controls pass. Fixing either conversion direction alone still leaves two failures.
    • I ran pytest tests/test_envconfig.py: 44 passed on 01af1f6; 49 passed with the fix on Python 3.13.16, 3.10.22 and 3.14.8.
    • I ran the full suite, pytest -n 4 --dist=worksteal, on Python 3.13.16: 1549 passed, 5 skipped on 01af1f6; 1554 passed, 5 skipped with the fix. The saved JUnit reports show five added cases and no changed statuses among existing tests.
    • poe lint passed with ruff 0.15.22, pyright 1.1.403, mypy 1.18.2, basedpyright 1.34.0 and pydocstyle 6.3.0.

    Other operating systems were not run.

  3. Any docs updates needed?

    Updated the ClientConfigTLS.from_dict() docstring and added changelog/fixed/persistent-pelican.md.

AI disclosure: this was prepared with AI assistance (Claude Opus 5.5).

🤖 Generated with Claude Code

ClientConfigProfile.to_dict() left out "tls" when the TLS config had no
fields set, and ClientConfigTLS.from_dict() returned None for an empty
dictionary, so an empty [profile.x.tls] table was lost when a loaded
profile went through a dictionary. Keep "tls" whenever the profile has a
TLS config, and return None only for None.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019TTGAv6fe859ebbCLLfLHP
Signed-off-by: Jackmeson1 <130693642+Jackmeson1@users.noreply.github.com>
@Jackmeson1
Jackmeson1 requested a review from a team as a code owner October 31, 2026 06:28
@CLAassistant

CLAassistant commented Oct 31, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

This branch has not been deployed

No deployments
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