@@ -5728,6 +5728,50 @@ _PyTypes_AfterFork(void)
57285728#endif
57295729}
57305730
5731+ #ifdef Py_GIL_DISABLED
5732+ // Non-caching version of type lookup, containing a non-locking
5733+ // version of find_name_in_mro().
5734+ static unsigned int
5735+ type_lookup_non_interned (PyTypeObject * type , PyObject * name , _PyStackRef * out )
5736+ {
5737+ PyObject * mro = NULL ;
5738+ Py_hash_t hash = _PyObject_HashFast (name );
5739+ if (hash == -1 ) {
5740+ goto error ;
5741+ }
5742+
5743+ /* Keep a strong reference to mro because type->tp_mro can be replaced
5744+ during dict lookup, e.g. when comparing to non-string keys. */
5745+ mro = _PyType_GetMRO (type );
5746+ if (mro == NULL ) {
5747+ assert (PyType_Ready (type ));
5748+ goto error ;
5749+ }
5750+
5751+ /* Look in tp_dict of types in MRO */
5752+ PyObject * res = NULL ;
5753+ Py_ssize_t n = PyTuple_GET_SIZE (mro );
5754+ for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
5755+ PyObject * base = PyTuple_GET_ITEM (mro , i );
5756+ PyObject * dict = lookup_tp_dict (_PyType_CAST (base ));
5757+ assert (dict && PyDict_Check (dict ));
5758+ if (_PyDict_GetItemRef_KnownHash ((PyDictObject * )dict , name , hash , & res ) < 0 ) {
5759+ goto error ;
5760+ }
5761+ if (res != NULL ) {
5762+ break ;
5763+ }
5764+ }
5765+ Py_DECREF (mro );
5766+ * out = res ? PyStackRef_FromPyObjectSteal (res ) : PyStackRef_NULL ;
5767+ return 0 ;
5768+ error :
5769+ Py_XDECREF (mro );
5770+ * out = PyStackRef_NULL ;
5771+ return 0 ;
5772+ }
5773+ #endif
5774+
57315775/* Internal API to look for a name through the MRO.
57325776 This returns a strong reference, and doesn't set an exception!
57335777 If nonzero, version is set to the value of type->tp_version at the time of
@@ -5750,6 +5794,18 @@ _PyType_LookupRefAndVersion(PyTypeObject *type, PyObject *name, unsigned int *ve
57505794unsigned int
57515795_PyType_LookupStackRefAndVersion (PyTypeObject * type , PyObject * name , _PyStackRef * out )
57525796{
5797+ #ifdef Py_GIL_DISABLED
5798+ // Bypass the type cache in this case since it is very unlikely it will do
5799+ // anything useful with a non-interned name lookup. This typically happens
5800+ // due to a getattr() call on a type with a name that has been constructed.
5801+ // We only have this path for the free-threaded build since cache misses are
5802+ // relatively more expensive for it and also to avoid contention on
5803+ // TYPE_LOCK. For the default build this extra branch is assumed to not be
5804+ // worth it, since this kind of lookup is quite rare.
5805+ if (!PyUnicode_CHECK_INTERNED (name ) && _PyType_IsReady (type )) {
5806+ return type_lookup_non_interned (type , name , out );
5807+ }
5808+ #endif
57535809 unsigned int h = MCACHE_HASH_METHOD (type , name );
57545810 struct type_cache * cache = get_type_cache ();
57555811 struct type_cache_entry * entry = & cache -> hashtable [h ];
0 commit comments