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
@@ -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
============================= 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
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
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
- GitHub issue: #11646
- Fix PR: https://github.com/pydantic/pydantic/pull/11666
- Reproduced locally: No (not executed)
- Last verified: 2026-02-11
- Confidence: 0.80
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.29
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”
“Please provide a MRE of your issue, with sample data if available.”
“I am also now having this issue since updating to 2.11”
“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…”
Failure Signature (Search String)
- ============================= test session starts =============================
Error Message
Stack trace
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
============================= 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.
Fix reference: https://github.com/pydantic/pydantic/pull/11666
Last verified: 2026-02-11. Validate in your environment.
When NOT to Use This Fix
- Do not apply this fix if the model's private attributes are intentionally mocked or altered.
Verify Fix
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.