You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Code objects can contain unmarshallable objects #89290
co_filename should be converted to an actual str, or reject subclasses with an exception
for co_consts, the marshal docs could be updated to add code objects to "containers". The code docs already say co_consts "is a tuple containing the literals"; if someone's putting in non-literals they're voiding the warranty.
I want to propose to keep code objects unrestricted at creation and just improve the error at save time.
Marshal already raises on dump, but the message does not say where the problem is. A code object can contain many values, and with nested code objects it is hard to tell what MyStr refers to.
The error could carry context to make it more helpful:
Traceback (most recent call last):
File "<python-input-1>", line 2, in <module>
marshal.dumps(compile("", MyStr("foo.py"), "exec"))
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ValueError: cannot marshal MyStr objects: 'foo.py' (subclasses of str are not supported)
when marshalling code object field co_filename
when marshalling code object '<module>' (foo.py, line 1)
This covers every path that creates a code object.
Why not reject such objects at creation?
Most code objects are never written to a .pyc (exec, bytecode tools, replace() in tests); restricting creation would break code that works today.
Nothing changes for code that is not saved, so there is no compatibility concern.
It seems Java/.Net use a similar model (allow runtime-only code to reference arbitrary objects and restrict what can be saved). Not sure how much weight 'others do it too' can carry :]
FTR, if someone messes up with code.replace, it is at their own discretion and we do not want to validate their modifications. This is why we closes previous similar issues
I agree with @vasiliyk. We should not restrict the use which does not involve marshalling.
Adding notes to locate error like in pickle and json is also a good idea. It was impossibly to implement it before the changes which were made few days ago -- we did not have a raised exception, only an error code.
The notes follow pickle's convention: one note per enclosing level, innermost first, with the same wording for container items, dict values and set elements.
3 differences with pickle:
a failing dict key gets a note, pickle leaves it unannotated;
a failing slice field is named directly (start, stop, step), pickle reports a tuple index inside the reconstructor arguments;
code object fields are identified by name, qualified name, file and line, pickle rejects code objects.
Activity
encukou commentedon Sep 7, 2021
The
replacemethod ofcodeallows setting e.g.and possibly more weird cases.
This makes code objects unmarshallable.
One way to create such a code object is to call
compileall.compile_filewith a str subclass as path. See the attached reproducers.This hit pip, see: pypa/pip#10358 (comment)
encukou commentedon Sep 7, 2021
How to fix this? I guess:
And so on for all other fields of code objects.
encukou commentedon Sep 7, 2021
See also gh-87005
vasiliyk commentedon Sep 24, 2026
I want to propose to keep code objects unrestricted at creation and just improve the error at save time.
Marshal already raises on
dump, but the message does not say where the problem is. A code object can contain many values, and with nested code objects it is hard to tell whatMyStrrefers to.The error could carry context to make it more helpful:
This covers every path that creates a code object.
Why not reject such objects at creation?
.pyc(exec, bytecode tools,replace()in tests); restricting creation would break code that works today.picnixz commentedon Sep 24, 2026
@serhiy-storchaka
picnixz commentedon Sep 24, 2026
FTR, if someone messes up with code.replace, it is at their own discretion and we do not want to validate their modifications. This is why we closes previous similar issues
serhiy-storchaka commentedon Sep 24, 2026
I agree with @vasiliyk. We should not restrict the use which does not involve marshalling.
Adding notes to locate error like in pickle and json is also a good idea. It was impossibly to implement it before the changes which were made few days ago -- we did not have a raised exception, only an error code.
vasiliyk commentedon Oct 21, 2026
I have implemented the notes support for marshalling, but I am at the open PR limit that was set on Oct 20 for the repo.
The notes follow pickle's convention: one note per enclosing level, innermost first, with the same wording for container items, dict values and set elements.
3 differences with pickle:
current:
with notes:
New tests cover every container type, slice field and code object field.
I will open the PR as soon as one of my open PRs is merged.