@@ -52,7 +52,9 @@ get_warnings_attr(const char *attr, int try_import)
52
52
if (warnings_module == NULL ) {
53
53
/* Fallback to the C implementation if we cannot get
54
54
the Python implementation */
55
- PyErr_Clear ();
55
+ if (PyErr_ExceptionMatches (PyExc_ImportError )) {
56
+ PyErr_Clear ();
57
+ }
56
58
return NULL ;
57
59
}
58
60
}
@@ -62,13 +64,11 @@ get_warnings_attr(const char *attr, int try_import)
62
64
return NULL ;
63
65
}
64
66
65
- if (!PyObject_HasAttrString (warnings_module , attr )) {
66
- Py_DECREF (warnings_module );
67
- return NULL ;
68
- }
69
-
70
67
obj = PyObject_GetAttrString (warnings_module , attr );
71
68
Py_DECREF (warnings_module );
69
+ if (obj == NULL && PyErr_ExceptionMatches (PyExc_AttributeError )) {
70
+ PyErr_Clear ();
71
+ }
72
72
return obj ;
73
73
}
74
74
@@ -82,16 +82,18 @@ get_once_registry(void)
82
82
if (registry == NULL ) {
83
83
if (PyErr_Occurred ())
84
84
return NULL ;
85
+ assert (_PyRuntime .warnings .once_registry );
85
86
return _PyRuntime .warnings .once_registry ;
86
87
}
87
88
if (!PyDict_Check (registry )) {
88
- PyErr_SetString (PyExc_TypeError ,
89
- "warnings.onceregistry must be a dict" );
89
+ PyErr_Format (PyExc_TypeError ,
90
+ MODULE_NAME ".onceregistry must be a dict, "
91
+ "not '%.200s'" ,
92
+ Py_TYPE (registry )-> tp_name );
90
93
Py_DECREF (registry );
91
94
return NULL ;
92
95
}
93
- Py_DECREF (_PyRuntime .warnings .once_registry );
94
- _PyRuntime .warnings .once_registry = registry ;
96
+ Py_SETREF (_PyRuntime .warnings .once_registry , registry );
95
97
return registry ;
96
98
}
97
99
@@ -106,6 +108,7 @@ get_default_action(void)
106
108
if (PyErr_Occurred ()) {
107
109
return NULL ;
108
110
}
111
+ assert (_PyRuntime .warnings .default_action );
109
112
return _PyRuntime .warnings .default_action ;
110
113
}
111
114
if (!PyUnicode_Check (default_action )) {
@@ -116,8 +119,7 @@ get_default_action(void)
116
119
Py_DECREF (default_action );
117
120
return NULL ;
118
121
}
119
- Py_DECREF (_PyRuntime .warnings .default_action );
120
- _PyRuntime .warnings .default_action = default_action ;
122
+ Py_SETREF (_PyRuntime .warnings .default_action , default_action );
121
123
return default_action ;
122
124
}
123
125
@@ -137,8 +139,7 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
137
139
return NULL ;
138
140
}
139
141
else {
140
- Py_DECREF (_PyRuntime .warnings .filters );
141
- _PyRuntime .warnings .filters = warnings_filters ;
142
+ Py_SETREF (_PyRuntime .warnings .filters , warnings_filters );
142
143
}
143
144
144
145
PyObject * filters = _PyRuntime .warnings .filters ;
@@ -408,8 +409,10 @@ call_show_warning(PyObject *category, PyObject *text, PyObject *message,
408
409
409
410
warnmsg_cls = get_warnings_attr ("WarningMessage" , 0 );
410
411
if (warnmsg_cls == NULL ) {
411
- PyErr_SetString (PyExc_RuntimeError ,
412
- "unable to get warnings.WarningMessage" );
412
+ if (!PyErr_Occurred ()) {
413
+ PyErr_SetString (PyExc_RuntimeError ,
414
+ "unable to get warnings.WarningMessage" );
415
+ }
413
416
goto error ;
414
417
}
415
418
@@ -837,6 +840,68 @@ warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
837
840
return do_warn (message , category , stacklevel , source );
838
841
}
839
842
843
+ static PyObject *
844
+ get_source_line (PyObject * module_globals , int lineno )
845
+ {
846
+ _Py_IDENTIFIER (get_source );
847
+ _Py_IDENTIFIER (__loader__ );
848
+ _Py_IDENTIFIER (__name__ );
849
+ PyObject * loader ;
850
+ PyObject * module_name ;
851
+ PyObject * get_source ;
852
+ PyObject * source ;
853
+ PyObject * source_list ;
854
+ PyObject * source_line ;
855
+
856
+ /* Check/get the requisite pieces needed for the loader. */
857
+ loader = _PyDict_GetItemIdWithError (module_globals , & PyId___loader__ );
858
+ if (loader == NULL ) {
859
+ return NULL ;
860
+ }
861
+ Py_INCREF (loader );
862
+ module_name = _PyDict_GetItemIdWithError (module_globals , & PyId___name__ );
863
+ if (!module_name ) {
864
+ Py_DECREF (loader );
865
+ return NULL ;
866
+ }
867
+ Py_INCREF (module_name );
868
+
869
+ /* Make sure the loader implements the optional get_source() method. */
870
+ get_source = _PyObject_GetAttrId (loader , & PyId_get_source );
871
+ Py_DECREF (loader );
872
+ if (!get_source ) {
873
+ Py_DECREF (module_name );
874
+ if (PyErr_ExceptionMatches (PyExc_AttributeError )) {
875
+ PyErr_Clear ();
876
+ }
877
+ return NULL ;
878
+ }
879
+ /* Call get_source() to get the source code. */
880
+ source = PyObject_CallFunctionObjArgs (get_source , module_name , NULL );
881
+ Py_DECREF (get_source );
882
+ Py_DECREF (module_name );
883
+ if (!source ) {
884
+ return NULL ;
885
+ }
886
+ if (source == Py_None ) {
887
+ Py_DECREF (source );
888
+ return NULL ;
889
+ }
890
+
891
+ /* Split the source into lines. */
892
+ source_list = PyUnicode_Splitlines (source , 0 );
893
+ Py_DECREF (source );
894
+ if (!source_list ) {
895
+ return NULL ;
896
+ }
897
+
898
+ /* Get the source line. */
899
+ source_line = PyList_GetItem (source_list , lineno - 1 );
900
+ Py_XINCREF (source_line );
901
+ Py_DECREF (source_list );
902
+ return source_line ;
903
+ }
904
+
840
905
static PyObject *
841
906
warnings_warn_explicit (PyObject * self , PyObject * args , PyObject * kwds )
842
907
{
@@ -851,68 +916,24 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
851
916
PyObject * registry = NULL ;
852
917
PyObject * module_globals = NULL ;
853
918
PyObject * sourceobj = NULL ;
919
+ PyObject * source_line = NULL ;
920
+ PyObject * returned ;
854
921
855
922
if (!PyArg_ParseTupleAndKeywords (args , kwds , "OOUi|OOOO:warn_explicit" ,
856
923
kwd_list , & message , & category , & filename , & lineno , & module ,
857
924
& registry , & module_globals , & sourceobj ))
858
925
return NULL ;
859
926
860
927
if (module_globals ) {
861
- _Py_IDENTIFIER (get_source );
862
- PyObject * tmp ;
863
- PyObject * loader ;
864
- PyObject * module_name ;
865
- PyObject * source ;
866
- PyObject * source_list ;
867
- PyObject * source_line ;
868
- PyObject * returned ;
869
-
870
- if ((tmp = _PyUnicode_FromId (& PyId_get_source )) == NULL )
871
- return NULL ;
872
-
873
- /* Check/get the requisite pieces needed for the loader. */
874
- loader = PyDict_GetItemString (module_globals , "__loader__" );
875
- module_name = PyDict_GetItemString (module_globals , "__name__" );
876
-
877
- if (loader == NULL || module_name == NULL )
878
- goto standard_call ;
879
-
880
- /* Make sure the loader implements the optional get_source() method. */
881
- if (!_PyObject_HasAttrId (loader , & PyId_get_source ))
882
- goto standard_call ;
883
- /* Call get_source() to get the source code. */
884
- source = PyObject_CallMethodObjArgs (loader , PyId_get_source .object ,
885
- module_name , NULL );
886
- if (!source )
928
+ source_line = get_source_line (module_globals , lineno );
929
+ if (source_line == NULL && PyErr_Occurred ()) {
887
930
return NULL ;
888
- else if (source == Py_None ) {
889
- Py_DECREF (Py_None );
890
- goto standard_call ;
891
931
}
892
-
893
- /* Split the source into lines. */
894
- source_list = PyUnicode_Splitlines (source , 0 );
895
- Py_DECREF (source );
896
- if (!source_list )
897
- return NULL ;
898
-
899
- /* Get the source line. */
900
- source_line = PyList_GetItem (source_list , lineno - 1 );
901
- if (!source_line ) {
902
- Py_DECREF (source_list );
903
- return NULL ;
904
- }
905
-
906
- /* Handle the warning. */
907
- returned = warn_explicit (category , message , filename , lineno , module ,
908
- registry , source_line , sourceobj );
909
- Py_DECREF (source_list );
910
- return returned ;
911
932
}
912
-
913
- standard_call :
914
- return warn_explicit ( category , message , filename , lineno , module ,
915
- registry , NULL , sourceobj ) ;
933
+ returned = warn_explicit ( category , message , filename , lineno , module ,
934
+ registry , source_line , sourceobj );
935
+ Py_XDECREF ( source_line );
936
+ return returned ;
916
937
}
917
938
918
939
static PyObject *
0 commit comments