Skip to content

Commit 6dcfd6c

Browse files
authored
gh-78214: marshal: Stabilize FLAG_REF usage (GH-8226)
Use FLAG_REF always for interned strings. Refcounts of interned string is very unstable. When compiling same source, refcounts of interned string in the output may be 1 or >1. It makes FLAG_REF usage unstable. To help reproducible build, use FLAG_REF for interned string even if refcnt(obj)==1.
1 parent dfb1b9d commit 6dcfd6c

File tree

3 files changed

+17
-10
lines changed

3 files changed

+17
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
``marshal.dumps()`` uses ``FLAG_REF`` for all interned strings. This makes
2+
output more deterministic and helps reproducible build.

Programs/test_frozenmain.h

+8-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/marshal.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,14 @@ w_ref(PyObject *v, char *flag, WFILE *p)
298298
if (p->version < 3 || p->hashtable == NULL)
299299
return 0; /* not writing object references */
300300

301-
/* if it has only one reference, it definitely isn't shared */
302-
if (Py_REFCNT(v) == 1)
301+
/* If it has only one reference, it definitely isn't shared.
302+
* But we use TYPE_REF always for interned string, to PYC file stable
303+
* as possible.
304+
*/
305+
if (Py_REFCNT(v) == 1 &&
306+
!(PyUnicode_CheckExact(v) && PyUnicode_CHECK_INTERNED(v))) {
303307
return 0;
308+
}
304309

305310
entry = _Py_hashtable_get_entry(p->hashtable, v);
306311
if (entry != NULL) {

0 commit comments

Comments
 (0)