Jump to solution
Verify

The Fix

Ensures that `__pydantic_private__` exists before setting private attributes, resolving an AttributeError in Pydantic V2.11.0.

Based on closed pydantic/pydantic issue #11646 · PR/commit linked

Jump to Verify Open PR/Commit
@@ -99,10 +99,20 @@ def _model_field_setattr_handler(model: BaseModel, name: str, val: Any) -> None: +def _private_setattr_handler(model: BaseModel, name: str, val: Any) -> None: + if getattr(model, '__pydantic_private__', None) is None: + # While the attribute should be present at this point, this may not be the case if
repro.py
============================= test session starts ============================= collecting ... collected 1 item unittests\client\test_client.py::TestIPFClient::test_ipf ========================= 1 error in 69.48s (0:01:09) ========================= ERROR [100%] test setup failed module_mocker = <pytest_mock.plugin.MockerFixture object at 0x000001D1E2ABBB30> loaded_snap = {'creatorUsername': None, 'deviceAddedCount': 0, 'deviceRemovedCount': 0, 'disabled_graph_cache': False, ...} @pytest.fixture(scope="module") def ipf(module_mocker: MockerFixture, loaded_snap) -> IPFClient: module_mocker.patch.object(IPFabricAPI, "model_post_init") module_mocker.patch.object(Intent, "model_post_init") module_mocker.patch.object(Snapshots, "model_post_init", return_value=None) ipf = IPFClient() ipf._client = module_mocker.MagicMock() ipf.base_url = httpx.URL("") ipf.api_version = API_VERSION ipf._os_version = VERSION ipf._oas = OAS(client=ipf, local_oas=True) ipf._user = User(username="test") ipf._snapshots = Snapshots(client=ipf) loaded = Snapshot(client=ipf, **loaded_snap) ipf._snapshots._snapshots = OrderedDict( [ ("$last", loaded), (loaded_snap["id"], loaded), ] ) unittests\client\test_client.py:31: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ..\.venv\Lib\site-packages\pydantic\main.py:991: in __setattr__ setattr_handler(self, name, value) # call here to not memo on possibly unknown fields _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ model = Snapshots(client=IPFClient(base_url='')), name = '_snapshots' val = OrderedDict({'$last': Snapshot(client=IPFClient(base_url=''), snapshot_id='936509a3-780b-4eec-b608-d6f41df537ad', name...460, unloaded_size=0, disabled_graph_cache=False, disabled_historical_data=False, disabled_intent_verification=False)}) 'private': lambda model, name, val: model.__pydantic_private__.__setitem__(name, val), # pyright: ignore[reportOptionalMemberAccess] 'cached_property': lambda model, name, val: model.__dict__.__setitem__(name, val), 'extra_known': lambda model, name, val: _object_setattr(model, name, val), } E AttributeError: 'NoneType' object has no attribute '__setitem__'. Did you mean: '__setattr__'? ..\.venv\Lib\site-packages\pydantic\main.py:105: AttributeError
verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
fix.md
Option A — Apply the official fix\nEnsures that `__pydantic_private__` exists before setting private attributes, resolving an AttributeError in Pydantic V2.11.0.\nWhen NOT to use: Do not apply this fix if the model's private attributes are intentionally mocked or altered.\n\n

Why This Fix Works in Production

  • Trigger: ============================= test session starts =============================
  • Mechanism: The '__pydantic_private__' attribute was not initialized, causing an AttributeError when accessed

Why This Breaks in Prod

  • Shows up under Python 3.11 in real deployments (not just unit tests).
  • The '__pydantic_private__' attribute was not initialized, causing an AttributeError when accessed
  • Surfaces as: ============================= test session starts =============================

Proof / Evidence

Discussion

High-signal excerpts from the issue thread (symptoms, repros, edge-cases).

“Thanks @justin-jeffery-ipf, this will be fixed in https://github.com/pydantic/pydantic/pull/11666”
@Viicos · 2025-04-01 · confirmation · source
“Please provide a MRE of your issue, with sample data if available.”
@Viicos · 2025-03-28 · source
“I am also now having this issue since updating to 2.11”
Issue thread · 2025-03-31 · source
“Using pydantic indirectly with openai. Not sure how I can customize as you suggested @Viicos. I have used the earlier version pydantic (pydantic==2.10.6) to fix…”
@goudakrishna · 2025-04-01 · source

Failure Signature (Search String)

  • ============================= test session starts =============================

Error Message

Stack trace
error.txt
Error Message ------------- ============================= test session starts ============================= collecting ... collected 1 item unittests\client\test_client.py::TestIPFClient::test_ipf ========================= 1 error in 69.48s (0:01:09) ========================= ERROR [100%] test setup failed module_mocker = <pytest_mock.plugin.MockerFixture object at 0x000001D1E2ABBB30> loaded_snap = {'creatorUsername': None, 'deviceAddedCount': 0, 'deviceRemovedCount': 0, 'disabled_graph_cache': False, ...} @pytest.fixture(scope="module") def ipf(module_mocker: MockerFixture, loaded_snap) -> IPFClient: module_mocker.patch.object(IPFabricAPI, "model_post_init") module_mocker.patch.object(Intent, "model_post_init") module_mocker.patch.object(Snapshots, "model_post_init", return_value=None) ipf = IPFClient() ipf._client = module_mocker.MagicMock() ipf.base_url = httpx.URL("") ipf.api_version = API_VERSION ipf._os_version = VERSION ipf._oas = OAS(client=ipf, local_oas=True) ipf._user = User(username="test") ipf._snapshots = Snapshots(client=ipf) loaded = Snapshot(client=ipf, **loaded_snap) ipf._snapshots._snapshots = OrderedDict( [ ("$last", loaded), (loaded_snap["id"], loaded), ] ) unittests\client\test_client.py:31: _ _ _ ... (truncated) ...

Minimal Reproduction

repro.py
============================= test session starts ============================= collecting ... collected 1 item unittests\client\test_client.py::TestIPFClient::test_ipf ========================= 1 error in 69.48s (0:01:09) ========================= ERROR [100%] test setup failed module_mocker = <pytest_mock.plugin.MockerFixture object at 0x000001D1E2ABBB30> loaded_snap = {'creatorUsername': None, 'deviceAddedCount': 0, 'deviceRemovedCount': 0, 'disabled_graph_cache': False, ...} @pytest.fixture(scope="module") def ipf(module_mocker: MockerFixture, loaded_snap) -> IPFClient: module_mocker.patch.object(IPFabricAPI, "model_post_init") module_mocker.patch.object(Intent, "model_post_init") module_mocker.patch.object(Snapshots, "model_post_init", return_value=None) ipf = IPFClient() ipf._client = module_mocker.MagicMock() ipf.base_url = httpx.URL("") ipf.api_version = API_VERSION ipf._os_version = VERSION ipf._oas = OAS(client=ipf, local_oas=True) ipf._user = User(username="test") ipf._snapshots = Snapshots(client=ipf) loaded = Snapshot(client=ipf, **loaded_snap) ipf._snapshots._snapshots = OrderedDict( [ ("$last", loaded), (loaded_snap["id"], loaded), ] ) unittests\client\test_client.py:31: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ..\.venv\Lib\site-packages\pydantic\main.py:991: in __setattr__ setattr_handler(self, name, value) # call here to not memo on possibly unknown fields _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ model = Snapshots(client=IPFClient(base_url='')), name = '_snapshots' val = OrderedDict({'$last': Snapshot(client=IPFClient(base_url=''), snapshot_id='936509a3-780b-4eec-b608-d6f41df537ad', name...460, unloaded_size=0, disabled_graph_cache=False, disabled_historical_data=False, disabled_intent_verification=False)}) 'private': lambda model, name, val: model.__pydantic_private__.__setitem__(name, val), # pyright: ignore[reportOptionalMemberAccess] 'cached_property': lambda model, name, val: model.__dict__.__setitem__(name, val), 'extra_known': lambda model, name, val: _object_setattr(model, name, val), } E AttributeError: 'NoneType' object has no attribute '__setitem__'. Did you mean: '__setattr__'? ..\.venv\Lib\site-packages\pydantic\main.py:105: AttributeError

Environment

  • Python: 3.11
  • Pydantic: 2

What Broke

Users experienced AttributeError when attempting to set private attributes in Pydantic models.

Why It Broke

The '__pydantic_private__' attribute was not initialized, causing an AttributeError when accessed

Fix Options (Details)

Option A — Apply the official fix

Ensures that `__pydantic_private__` exists before setting private attributes, resolving an AttributeError in Pydantic V2.11.0.

When NOT to use: Do not apply this fix if the model's private attributes are intentionally mocked or altered.

Fix reference: https://github.com/pydantic/pydantic/pull/11666

Last verified: 2026-02-11. Validate in your environment.

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • Do not apply this fix if the model's private attributes are intentionally mocked or altered.

Verify Fix

verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.

Did This Fix Work in Your Case?

Quick signal helps us prioritize which fixes to verify and improve.

Prevention

  • Add a CI check that diffs key outputs after upgrades (OpenAPI schema snapshots, JSON payload shapes, CLI output).
  • Upgrade behind a canary and run integration tests against the canary before 100% rollout.

Related Issues

No related fixes found.

Sources

We don’t republish the full GitHub discussion text. Use the links above for context.