Skip to content

fix: prevent shared state between client instances#259

Open
calicube wants to merge 1 commit intoandrewyng:mainfrom
calicube:youkwan/client-shared-state
Open

fix: prevent shared state between client instances#259
calicube wants to merge 1 commit intoandrewyng:mainfrom
calicube:youkwan/client-shared-state

Conversation

@calicube
Copy link

Summary

The provider_configs field in the Client class was using a mutable default argument (dict = {}). This caused shared state issues where modifying the configuration of one Client instance would inadvertently affect all other instances initialized with the default value.

Changes:

  • Changed provider_configs default value from {} to None in Client.__init__.
  • Added logic to initialize self.provider_configs as a new dictionary if None is provided.

Root Cause

Default arguments are evaluated only once at function definition time. Using a mutable object like a dictionary as a default argument leads to a persistent object shared across all calls that do not provide an explicit value.

# Problematic behavior in current implementation:
client_a = ai.Client()
client_b = ai.Client()

client_a.configure({"openai": {"api_key": "sk-example"}})

# client_b now unexpectedly contains client_a's config 
# because they both point to the same internal dictionary object.
print(client_b.provider_configs) 
# Output: {'openai': {'api_key': 'sk-example'}}

Solution

def __init__(
    self,
    provider_configs: dict | None = None,
    extra_param_mode: Literal["strict", "warn", "permissive"] = "warn",
):
    self.providers = {}
    # Ensures a fresh dictionary for every instance
    if provider_configs:
        self.provider_configs = provider_configs
    else:
        self.provider_configs = {}
    # ...

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.

1 participant