mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	Issue #26146: marshal.loads() now uses the empty frozenset singleton
This commit is contained in:
		
							parent
							
								
									5ebe2c89fe
								
							
						
					
					
						commit
						1aa78938b0
					
				
					 2 changed files with 50 additions and 32 deletions
				
			
		|  | @ -135,6 +135,13 @@ def test_sets(self): | |||
|         for constructor in (set, frozenset): | ||||
|             self.helper(constructor(self.d.keys())) | ||||
| 
 | ||||
|     @support.cpython_only | ||||
|     def test_empty_frozenset_singleton(self): | ||||
|         # marshal.loads() must reuse the empty frozenset singleton | ||||
|         obj = frozenset() | ||||
|         obj2 = marshal.loads(marshal.dumps(obj)) | ||||
|         self.assertIs(obj2, obj) | ||||
| 
 | ||||
| 
 | ||||
| class BufferTestCase(unittest.TestCase, HelperMixin): | ||||
| 
 | ||||
|  |  | |||
|  | @ -1266,41 +1266,52 @@ r_object(RFILE *p) | |||
|             PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)"); | ||||
|             break; | ||||
|         } | ||||
|         v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); | ||||
|         if (type == TYPE_SET) { | ||||
|             R_REF(v); | ||||
|         } else { | ||||
|             /* must use delayed registration of frozensets because they must
 | ||||
|              * be init with a refcount of 1 | ||||
|              */ | ||||
|             idx = r_ref_reserve(flag, p); | ||||
|             if (idx < 0) | ||||
|                 Py_CLEAR(v); /* signal error */ | ||||
|         } | ||||
|         if (v == NULL) | ||||
|             break; | ||||
| 
 | ||||
|         for (i = 0; i < n; i++) { | ||||
|             v2 = r_object(p); | ||||
|             if ( v2 == NULL ) { | ||||
|                 if (!PyErr_Occurred()) | ||||
|                     PyErr_SetString(PyExc_TypeError, | ||||
|                         "NULL object in marshal data for set"); | ||||
|                 Py_DECREF(v); | ||||
|                 v = NULL; | ||||
|         if (n == 0 && type == TYPE_FROZENSET) { | ||||
|             /* call frozenset() to get the empty frozenset singleton */ | ||||
|             v = PyObject_CallFunction((PyObject*)&PyFrozenSet_Type, NULL); | ||||
|             if (v == NULL) | ||||
|                 break; | ||||
|             } | ||||
|             if (PySet_Add(v, v2) == -1) { | ||||
|                 Py_DECREF(v); | ||||
|                 Py_DECREF(v2); | ||||
|                 v = NULL; | ||||
|                 break; | ||||
|             } | ||||
|             Py_DECREF(v2); | ||||
|             R_REF(v); | ||||
|             retval = v; | ||||
|         } | ||||
|         else { | ||||
|             v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); | ||||
|             if (type == TYPE_SET) { | ||||
|                 R_REF(v); | ||||
|             } else { | ||||
|                 /* must use delayed registration of frozensets because they must
 | ||||
|                  * be init with a refcount of 1 | ||||
|                  */ | ||||
|                 idx = r_ref_reserve(flag, p); | ||||
|                 if (idx < 0) | ||||
|                     Py_CLEAR(v); /* signal error */ | ||||
|             } | ||||
|             if (v == NULL) | ||||
|                 break; | ||||
| 
 | ||||
|             for (i = 0; i < n; i++) { | ||||
|                 v2 = r_object(p); | ||||
|                 if ( v2 == NULL ) { | ||||
|                     if (!PyErr_Occurred()) | ||||
|                         PyErr_SetString(PyExc_TypeError, | ||||
|                             "NULL object in marshal data for set"); | ||||
|                     Py_DECREF(v); | ||||
|                     v = NULL; | ||||
|                     break; | ||||
|                 } | ||||
|                 if (PySet_Add(v, v2) == -1) { | ||||
|                     Py_DECREF(v); | ||||
|                     Py_DECREF(v2); | ||||
|                     v = NULL; | ||||
|                     break; | ||||
|                 } | ||||
|                 Py_DECREF(v2); | ||||
|             } | ||||
|             if (type != TYPE_SET) | ||||
|                 v = r_ref_insert(v, idx, flag, p); | ||||
|             retval = v; | ||||
|         } | ||||
|         if (type != TYPE_SET) | ||||
|             v = r_ref_insert(v, idx, flag, p); | ||||
|         retval = v; | ||||
|         break; | ||||
| 
 | ||||
|     case TYPE_CODE: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner