@@ -510,27 +510,16 @@ _PyDict_MaybeUntrack(PyObject *op)
510510 _PyObject_GC_UNTRACK (op );
511511}
512512
513-
514513/*
515- Internal routine to insert a new item into the table.
516- Used both by the internal resize routine and by the public insert routine.
517- Eats a reference to key and one to value.
518- Returns -1 if an error occurred, or 0 on success.
514+ Internal routine to insert a new item into the table when you have entry object.
515+ Used by insertdict.
519516*/
520517static int
521- insertdict (register PyDictObject * mp , PyObject * key , Py_hash_t hash , PyObject * value )
518+ insertdict_by_entry (register PyDictObject * mp , PyObject * key , Py_hash_t hash ,
519+ PyDictEntry * ep , PyObject * value )
522520{
523521 PyObject * old_value ;
524- register PyDictEntry * ep ;
525- typedef PyDictEntry * (* lookupfunc )(PyDictObject * , PyObject * , Py_hash_t );
526522
527- assert (mp -> ma_lookup != NULL );
528- ep = mp -> ma_lookup (mp , key , hash );
529- if (ep == NULL ) {
530- Py_DECREF (key );
531- Py_DECREF (value );
532- return -1 ;
533- }
534523 MAINTAIN_TRACKING (mp , key , value );
535524 if (ep -> me_value != NULL ) {
536525 old_value = ep -> me_value ;
@@ -553,6 +542,28 @@ insertdict(register PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *v
553542 return 0 ;
554543}
555544
545+
546+ /*
547+ Internal routine to insert a new item into the table.
548+ Used both by the internal resize routine and by the public insert routine.
549+ Eats a reference to key and one to value.
550+ Returns -1 if an error occurred, or 0 on success.
551+ */
552+ static int
553+ insertdict (register PyDictObject * mp , PyObject * key , Py_hash_t hash , PyObject * value )
554+ {
555+ register PyDictEntry * ep ;
556+
557+ assert (mp -> ma_lookup != NULL );
558+ ep = mp -> ma_lookup (mp , key , hash );
559+ if (ep == NULL ) {
560+ Py_DECREF (key );
561+ Py_DECREF (value );
562+ return -1 ;
563+ }
564+ return insertdict_by_entry (mp , key , hash , ep , value );
565+ }
566+
556567/*
557568Internal routine used by dictresize() to insert an item which is
558569known to be absent from the dict. This routine also assumes that
@@ -776,39 +787,26 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key)
776787 return ep -> me_value ;
777788}
778789
779- /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
780- * dictionary if it's merely replacing the value for an existing key.
781- * This means that it's safe to loop over a dictionary with PyDict_Next()
782- * and occasionally replace a value -- but you can't insert new keys or
783- * remove them.
784- */
785- int
786- PyDict_SetItem (register PyObject * op , PyObject * key , PyObject * value )
790+ static int
791+ dict_set_item_by_hash_or_entry (register PyObject * op , PyObject * key ,
792+ Py_hash_t hash , PyDictEntry * ep , PyObject * value )
787793{
788794 register PyDictObject * mp ;
789- register Py_hash_t hash ;
790795 register Py_ssize_t n_used ;
791796
792- if (!PyDict_Check (op )) {
793- PyErr_BadInternalCall ();
794- return -1 ;
795- }
796- assert (key );
797- assert (value );
798797 mp = (PyDictObject * )op ;
799- if (!PyUnicode_CheckExact (key ) ||
800- (hash = ((PyUnicodeObject * ) key )-> hash ) == -1 )
801- {
802- hash = PyObject_Hash (key );
803- if (hash == -1 )
804- return -1 ;
805- }
806798 assert (mp -> ma_fill <= mp -> ma_mask ); /* at least one empty slot */
807799 n_used = mp -> ma_used ;
808800 Py_INCREF (value );
809801 Py_INCREF (key );
810- if (insertdict (mp , key , hash , value ) != 0 )
811- return -1 ;
802+ if (ep == NULL ) {
803+ if (insertdict (mp , key , hash , value ) != 0 )
804+ return -1 ;
805+ }
806+ else {
807+ if (insertdict_by_entry (mp , key , hash , ep , value ) != 0 )
808+ return -1 ;
809+ }
812810 /* If we added a key, we can safely resize. Otherwise just return!
813811 * If fill >= 2/3 size, adjust size. Normally, this doubles or
814812 * quaduples the size, but it's also possible for the dict to shrink
@@ -828,6 +826,36 @@ PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
828826 return dictresize (mp , (mp -> ma_used > 50000 ? 2 : 4 ) * mp -> ma_used );
829827}
830828
829+ /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
830+ * dictionary if it's merely replacing the value for an existing key.
831+ * This means that it's safe to loop over a dictionary with PyDict_Next()
832+ * and occasionally replace a value -- but you can't insert new keys or
833+ * remove them.
834+ */
835+ int
836+ PyDict_SetItem (register PyObject * op , PyObject * key , PyObject * value )
837+ {
838+ register Py_hash_t hash ;
839+
840+ if (!PyDict_Check (op )) {
841+ PyErr_BadInternalCall ();
842+ return -1 ;
843+ }
844+ assert (key );
845+ assert (value );
846+ if (PyUnicode_CheckExact (key )) {
847+ hash = ((PyUnicodeObject * ) key )-> hash ;
848+ if (hash == -1 )
849+ hash = PyObject_Hash (key );
850+ }
851+ else {
852+ hash = PyObject_Hash (key );
853+ if (hash == -1 )
854+ return -1 ;
855+ }
856+ return dict_set_item_by_hash_or_entry (op , key , hash , NULL , value );
857+ }
858+
831859int
832860PyDict_DelItem (PyObject * op , PyObject * key )
833861{
@@ -1797,9 +1825,9 @@ dict_setdefault(register PyDictObject *mp, PyObject *args)
17971825 return NULL ;
17981826 val = ep -> me_value ;
17991827 if (val == NULL ) {
1800- val = failobj ;
1801- if ( PyDict_SetItem (( PyObject * ) mp , key , failobj ))
1802- val = NULL ;
1828+ if ( dict_set_item_by_hash_or_entry (( PyObject * ) mp , key , hash , ep ,
1829+ failobj ) == 0 )
1830+ val = failobj ;
18031831 }
18041832 Py_XINCREF (val );
18051833 return val ;
0 commit comments