| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Allow :class:`frozendict` to be assigned to an instance's | ||
| :attr:`~object.__dict__`, enabling immutable instances. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -3999,10 +3999,10 @@ subtype_dict(PyObject *obj, void *context) | |
| int | ||
| _PyObject_SetDict(PyObject *obj, PyObject *value) | ||
| { | ||
| if (value != NULL && !PyDict_Check(value)) { | ||
| if (value != NULL && !PyAnyDict_Check(value)) { | ||
| PyErr_Format(PyExc_TypeError, | ||
| "__dict__ must be set to a dictionary, " | ||
| "not a '%.200s'", Py_TYPE(value)->tp_name); | ||
| "__dict__ must be set to a dict or frozendict, " | ||
| "not a %T", value); | ||
| return -1; | ||
| } | ||
| if (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) { | ||
| Expand Down Expand Up | @@ -8305,15 +8305,24 @@ object___dir___impl(PyObject *self) | |
| if (dict == NULL) { | ||
| dict = PyDict_New(); | ||
| } | ||
| else if (!PyDict_Check(dict)) { | ||
| Py_DECREF(dict); | ||
| dict = PyDict_New(); | ||
| } | ||
| else { | ||
| else if (PyDict_Check(dict)) { | ||
| /* Copy __dict__ to avoid mutating it. */ | ||
| PyObject *temp = PyDict_Copy(dict); | ||
| Py_SETREF(dict, temp); | ||
| } | ||
| else if (PyFrozenDict_Check(dict)) { | ||
| /* Convert frozendict to a mutable dict for merging. */ | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityPlease wait for #145517. If PyDict_Copy() is modified to always return a dict, you can reuse the PyDict_Check() branch for frozendict.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityFor now, you can use _PyDict_CopyAsDict() from Include/internal/pycore_dict.h.
Sorry, something went wrong.
All reactions
|
||
| PyObject *temp = PyDict_New(); | ||
| if (temp != NULL && PyDict_Update(temp, dict) < 0) { | ||
| Py_DECREF(temp); | ||
| temp = NULL; | ||
| } | ||
| Py_SETREF(dict, temp); | ||
| } | ||
| else { | ||
| Py_DECREF(dict); | ||
| dict = PyDict_New(); | ||
| } | ||
|
|
||
| if (dict == NULL) | ||
| goto error; | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityAllowing _PyObject_SetDict() to accept PyAnyDict_Check here makes frozendict assignable to every PyObject_GenericSetDict user, but some of those types still perform internal writes with PyDict_SetItem/PyDict_DelItem (for example descriptor_get_wrapped_attribute and descriptor_set_wrapped_attribute in Objects/funcobject.c for classmethod/staticmethod annotation caching). PyDict_SetItem still rejects frozendict with PyErr_BadInternalCall, so after obj.__dict__ = frozendict(...), operations like reading or updating __annotations__ can now raise SystemError instead of behaving normally or reporting an intentional immutability error.
Useful? React with 👍 / 👎.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.