@@ -519,7 +519,6 @@ typedef struct {
519519#endif
520520 PyObject *astimezone;
521521 PyObject *re_compile;
522- PyObject *get_annotate_from_class_namespace;
523522 uint8_t gc_cycle;
524523} MsgspecState;
525524
@@ -658,6 +657,28 @@ strbuilder_build(strbuilder *self) {
658657 return out;
659658}
660659
660+ static MS_INLINE PyObject *
661+ ms_get_annotate_from_class_namespace(PyObject *namespace) {
662+ /* We replicate the behavior of the standard library utility to avoid
663+ * unnecessary function call overhead.
664+ * https://docs.python.org/3/library/annotationlib.html#annotationlib.get_annotate_from_class_namespace */
665+ PyObject *annotate;
666+
667+ annotate = PyDict_GetItemString(namespace, "__annotate__");
668+ if (annotate != NULL) {
669+ Py_INCREF(annotate);
670+ return annotate;
671+ }
672+
673+ annotate = PyDict_GetItemString(namespace, "__annotate_func__");
674+ if (annotate != NULL) {
675+ Py_INCREF(annotate);
676+ return annotate;
677+ }
678+
679+ Py_RETURN_NONE;
680+ }
681+
661682/*************************************************************************
662683 * PathNode *
663684 *************************************************************************/
@@ -5953,36 +5974,28 @@ structmeta_collect_fields(StructMetaInfo *info, MsgspecState *mod, bool kwonly)
59535974 info->namespace, "__annotations__"
59545975 );
59555976 if (annotations == NULL) {
5956- if (mod->get_annotate_from_class_namespace != NULL) {
5957- PyObject *annotate = PyObject_CallOneArg(
5958- mod->get_annotate_from_class_namespace, info->namespace
5959- );
5960- if (annotate == NULL) {
5961- return -1;
5962- }
5963- if (annotate == Py_None) {
5964- Py_DECREF(annotate);
5965- return 0;
5966- }
5967- PyObject *format = PyLong_FromLong(1); /* annotationlib.Format.VALUE */
5968- if (format == NULL) {
5969- Py_DECREF(annotate);
5970- return -1;
5971- }
5972- annotations = PyObject_CallOneArg(
5973- annotate, format
5974- );
5977+ PyObject *annotate = ms_get_annotate_from_class_namespace(info->namespace);
5978+ if (annotate == NULL) {
5979+ return -1;
5980+ }
5981+ if (annotate == Py_None) {
59755982 Py_DECREF(annotate);
5976- Py_DECREF(format);
5977- if (annotations == NULL) {
5978- return -1;
5979- }
5983+ return 0;
59805984 }
5981- else {
5982- return 0; // No annotations, nothing to do
5985+ PyObject *format = PyLong_FromLong(1); /* annotationlib.Format.VALUE */
5986+ if (format == NULL) {
5987+ Py_DECREF(annotate);
5988+ return -1;
59835989 }
5984- }
5985- else {
5990+ annotations = PyObject_CallOneArg(
5991+ annotate, format
5992+ );
5993+ Py_DECREF(annotate);
5994+ Py_DECREF(format);
5995+ if (annotations == NULL) {
5996+ return -1;
5997+ }
5998+ } else {
59865999 Py_INCREF(annotations);
59876000 }
59886001
@@ -22653,26 +22666,6 @@ PyInit__core(void)
2265322666 Py_DECREF(temp_module);
2265422667 if (st->re_compile == NULL) return NULL;
2265522668
22656- /* annotationlib.get_annotate_from_class_namespace */
22657- temp_module = PyImport_ImportModule("annotationlib");
22658- if (temp_module == NULL) {
22659- if (PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) {
22660- // Below Python 3.14
22661- PyErr_Clear();
22662- st->get_annotate_from_class_namespace = NULL;
22663- }
22664- else {
22665- return NULL;
22666- }
22667- }
22668- else {
22669- st->get_annotate_from_class_namespace = PyObject_GetAttrString(
22670- temp_module, "get_annotate_from_class_namespace"
22671- );
22672- Py_DECREF(temp_module);
22673- if (st->get_annotate_from_class_namespace == NULL) return NULL;
22674- }
22675-
2267622669 /* Initialize cached constant strings */
2267722670#define CACHED_STRING(attr, str) \
2267822671 if ((st->attr = PyUnicode_InternFromString(str)) == NULL) return NULL
0 commit comments