Stringify and encode a dict key to its JSON representation, using the * key_memo cache for string keys. Returns a new reference to the encoded * key string on success, Py_None (borrowed, no new reference) for * skipkeys, or NULL on error. */
| 3105 | * key string on success, Py_None (borrowed, no new reference) for |
| 3106 | * skipkeys, or NULL on error. */ |
| 3107 | static PyObject * |
| 3108 | encoder_encode_dict_key(PyEncoderObject *s, PyObject *key) |
| 3109 | { |
| 3110 | PyObject *kstr; |
| 3111 | PyObject *encoded; |
| 3112 | |
| 3113 | kstr = encoder_stringify_key(s, key); |
| 3114 | if (kstr == NULL) |
| 3115 | return NULL; |
| 3116 | if (kstr == Py_None) { |
| 3117 | Py_DECREF(kstr); |
| 3118 | return Py_None; /* skipkeys */ |
| 3119 | } |
| 3120 | |
| 3121 | /* For string keys (PyUnicode on Py3, PyString on Py2), |
| 3122 | * encoder_stringify_key returns Py_INCREF(key) — i.e. kstr IS key. |
| 3123 | * For non-string keys it returns a freshly created string, so |
| 3124 | * kstr != key. Use this identity test to decide whether the |
| 3125 | * key_memo cache applies: caching under a non-string original key |
| 3126 | * would be write-only (the lookup uses kstr, not key). */ |
| 3127 | if (kstr == key) { |
| 3128 | int cached = json_PyDict_GetItemRef(s->key_memo, kstr, &encoded); |
| 3129 | if (cached < 0) { |
| 3130 | Py_DECREF(kstr); |
| 3131 | return NULL; |
| 3132 | } |
| 3133 | if (cached == 0) { |
| 3134 | encoded = encoder_encode_string(s, kstr); |
| 3135 | if (encoded == NULL) { |
| 3136 | Py_DECREF(kstr); |
| 3137 | return NULL; |
| 3138 | } |
| 3139 | if (PyDict_SetItem(s->key_memo, key, encoded)) { |
| 3140 | Py_DECREF(kstr); |
| 3141 | Py_DECREF(encoded); |
| 3142 | return NULL; |
| 3143 | } |
| 3144 | } |
| 3145 | Py_DECREF(kstr); |
| 3146 | } else { |
| 3147 | encoded = encoder_encode_string(s, kstr); |
| 3148 | Py_DECREF(kstr); |
| 3149 | if (encoded == NULL) |
| 3150 | return NULL; |
| 3151 | } |
| 3152 | return encoded; /* new reference */ |
| 3153 | } |
| 3154 | |
| 3155 | /* Write '\n' followed by indent_level copies of s->indent directly to |
| 3156 | * the accumulator, without materializing the combined string as an |
no test coverage detected
searching dependent graphs…