Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb936cf4

Browse files
authored
gh-108634: PyInterpreterState_New() no longer calls Py_FatalError() (#108748)
pycore_create_interpreter() now returns a status, rather thancalling Py_FatalError().* PyInterpreterState_New() now calls Py_ExitStatusException() instead of calling Py_FatalError() directly.* Replace Py_FatalError() with PyStatus in init_interpreter() and _PyObject_InitState().* _PyErr_SetFromPyStatus() now raises RuntimeError, instead of ValueError. It can now call PyErr_NoMemory(), raise MemoryError, if it detects _PyStatus_NO_MEMORY() error message.
1 parent844f4c2 commitb936cf4

File tree

7 files changed

+99
-51
lines changed

7 files changed

+99
-51
lines changed

‎Include/internal/pycore_initconfig.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ struct pyruntimestate;
2222
#endif
2323

2424
#define_PyStatus_OK() \
25-
(PyStatus){._type = _PyStatus_TYPE_OK,}
25+
(PyStatus){._type = _PyStatus_TYPE_OK}
2626
/* other fields are set to 0 */
2727
#define_PyStatus_ERR(ERR_MSG) \
2828
(PyStatus){ \
2929
._type = _PyStatus_TYPE_ERROR, \
3030
.func = _PyStatus_GET_FUNC(), \
3131
.err_msg = (ERR_MSG)}
3232
/* other fields are set to 0 */
33-
#define_PyStatus_NO_MEMORY() _PyStatus_ERR("memory allocation failed")
33+
#define_PyStatus_NO_MEMORY_ERRMSG "memory allocation failed"
34+
#define_PyStatus_NO_MEMORY() _PyStatus_ERR(_PyStatus_NO_MEMORY_ERRMSG)
3435
#define_PyStatus_EXIT(EXITCODE) \
3536
(PyStatus){ \
3637
._type = _PyStatus_TYPE_EXIT, \
@@ -45,7 +46,7 @@ struct pyruntimestate;
4546
do { (err).func = _PyStatus_GET_FUNC(); } while (0)
4647

4748
// Export for '_testinternalcapi' shared extension
48-
PyAPI_FUNC(PyObject*)_PyErr_SetFromPyStatus(PyStatusstatus);
49+
PyAPI_FUNC(void)_PyErr_SetFromPyStatus(PyStatusstatus);
4950

5051

5152
/* --- PyWideStringList ------------------------------------------------ */

‎Include/internal/pycore_interp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ might not be allowed in the current interpreter (i.e. os.fork() would fail).
311311
externint_PyInterpreterState_HasFeature(PyInterpreterState*interp,
312312
unsigned longfeature);
313313

314+
PyAPI_FUNC(PyStatus)_PyInterpreterState_New(
315+
PyThreadState*tstate,
316+
PyInterpreterState**pinterp);
317+
314318

315319
#ifdef__cplusplus
316320
}

‎Include/internal/pycore_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ _PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
182182

183183
externvoid_PyType_InitCache(PyInterpreterState*interp);
184184

185-
externvoid_PyObject_InitState(PyInterpreterState*interp);
185+
externPyStatus_PyObject_InitState(PyInterpreterState*interp);
186186
externvoid_PyObject_FiniState(PyInterpreterState*interp);
187187
externbool_PyRefchain_IsTraced(PyInterpreterState*interp,PyObject*obj);
188188

‎Objects/object.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,7 +2034,7 @@ PyObject _Py_NotImplementedStruct = {
20342034
};
20352035

20362036

2037-
void
2037+
PyStatus
20382038
_PyObject_InitState(PyInterpreterState*interp)
20392039
{
20402040
#ifdefPy_TRACE_REFS
@@ -2048,9 +2048,10 @@ _PyObject_InitState(PyInterpreterState *interp)
20482048
_Py_hashtable_hash_ptr,_Py_hashtable_compare_direct,
20492049
NULL,NULL,&alloc);
20502050
if (REFCHAIN(interp)==NULL) {
2051-
Py_FatalError("_PyObject_InitState() memory allocation failure");
2051+
return_PyStatus_NO_MEMORY();
20522052
}
20532053
#endif
2054+
return_PyStatus_OK();
20542055
}
20552056

20562057
void

‎Python/initconfig.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,21 +335,34 @@ int PyStatus_IsExit(PyStatus status)
335335
intPyStatus_Exception(PyStatusstatus)
336336
{return_PyStatus_EXCEPTION(status); }
337337

338-
PyObject*
338+
void
339339
_PyErr_SetFromPyStatus(PyStatusstatus)
340340
{
341341
if (!_PyStatus_IS_ERROR(status)) {
342342
PyErr_Format(PyExc_SystemError,
343-
"%s()expectsan error PyStatus",
344-
_PyStatus_GET_FUNC());
343+
"_PyErr_SetFromPyStatus()status is notan error");
344+
return;
345345
}
346-
elseif (status.func) {
347-
PyErr_Format(PyExc_ValueError,"%s: %s",status.func,status.err_msg);
346+
347+
constchar*err_msg=status.err_msg;
348+
if (err_msg==NULL||strlen(err_msg)==0) {
349+
PyErr_Format(PyExc_SystemError,
350+
"_PyErr_SetFromPyStatus() status has no error message");
351+
return;
352+
}
353+
354+
if (strcmp(err_msg,_PyStatus_NO_MEMORY_ERRMSG)==0) {
355+
PyErr_NoMemory();
356+
return;
357+
}
358+
359+
constchar*func=status.func;
360+
if (func) {
361+
PyErr_Format(PyExc_RuntimeError,"%s: %s",func,err_msg);
348362
}
349363
else {
350-
PyErr_Format(PyExc_ValueError,"%s",status.err_msg);
364+
PyErr_Format(PyExc_RuntimeError,"%s",err_msg);
351365
}
352-
returnNULL;
353366
}
354367

355368

‎Python/pylifecycle.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,10 +629,12 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
629629
PyThreadState**tstate_p)
630630
{
631631
PyStatusstatus;
632-
PyInterpreterState*interp=PyInterpreterState_New();
633-
if (interp==NULL) {
634-
return_PyStatus_ERR("can't make main interpreter");
632+
PyInterpreterState*interp;
633+
status=_PyInterpreterState_New(NULL,&interp);
634+
if (_PyStatus_EXCEPTION(status)) {
635+
returnstatus;
635636
}
637+
assert(interp!=NULL);
636638
assert(_Py_IsMainInterpreter(interp));
637639

638640
status=_PyConfig_Copy(&interp->config,src_config);

‎Python/pystate.c

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -426,13 +426,11 @@ init_runtime(_PyRuntimeState *runtime,
426426
Py_ssize_tunicode_next_index,
427427
PyThread_type_locklocks[NUMLOCKS])
428428
{
429-
if (runtime->_initialized) {
430-
Py_FatalError("runtime already initialized");
431-
}
432-
assert(!runtime->preinitializing&&
433-
!runtime->preinitialized&&
434-
!runtime->core_initialized&&
435-
!runtime->initialized);
429+
assert(!runtime->preinitializing);
430+
assert(!runtime->preinitialized);
431+
assert(!runtime->core_initialized);
432+
assert(!runtime->initialized);
433+
assert(!runtime->_initialized);
436434

437435
runtime->open_code_hook=open_code_hook;
438436
runtime->open_code_userdata=open_code_userdata;
@@ -476,6 +474,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
476474
// Py_Initialize() must be running again.
477475
// Reset to _PyRuntimeState_INIT.
478476
memcpy(runtime,&initial,sizeof(*runtime));
477+
assert(!runtime->_initialized);
479478
}
480479

481480
if (gilstate_tss_init(runtime)!=0) {
@@ -647,14 +646,14 @@ free_interpreter(PyInterpreterState *interp)
647646
main interpreter. We fix those fields here, in addition
648647
to the other dynamically initialized fields.
649648
*/
650-
staticvoid
649+
staticPyStatus
651650
init_interpreter(PyInterpreterState*interp,
652651
_PyRuntimeState*runtime,int64_tid,
653652
PyInterpreterState*next,
654653
PyThread_type_lockpending_lock)
655654
{
656655
if (interp->_initialized) {
657-
Py_FatalError("interpreter already initialized");
656+
return_PyStatus_ERR("interpreter already initialized");
658657
}
659658

660659
assert(runtime!=NULL);
@@ -675,7 +674,10 @@ init_interpreter(PyInterpreterState *interp,
675674
memcpy(&interp->obmalloc.pools.used,temp,sizeof(temp));
676675
}
677676

678-
_PyObject_InitState(interp);
677+
PyStatusstatus=_PyObject_InitState(interp);
678+
if (_PyStatus_EXCEPTION(status)) {
679+
returnstatus;
680+
}
679681

680682
_PyEval_InitState(interp,pending_lock);
681683
_PyGC_InitState(&interp->gc);
@@ -701,42 +703,44 @@ init_interpreter(PyInterpreterState *interp,
701703
}
702704
interp->f_opcode_trace_set= false;
703705
interp->_initialized=1;
706+
return_PyStatus_OK();
704707
}
705708

706-
PyInterpreterState*
707-
PyInterpreterState_New(void)
709+
710+
PyStatus
711+
_PyInterpreterState_New(PyThreadState*tstate,PyInterpreterState**pinterp)
708712
{
709-
PyInterpreterState*interp;
713+
*pinterp=NULL;
714+
715+
// Don't get runtime from tstate since tstate can be NULL
710716
_PyRuntimeState*runtime=&_PyRuntime;
711-
PyThreadState*tstate=current_fast_get(runtime);
712717

713-
/* tstate is NULL when Py_InitializeFromConfig() calls
714-
PyInterpreterState_New() to create the main interpreter. */
715-
if (_PySys_Audit(tstate,"cpython.PyInterpreterState_New",NULL)<0) {
716-
returnNULL;
718+
// tstate is NULL when pycore_create_interpreter() calls
719+
// _PyInterpreterState_New() to create the main interpreter.
720+
if (tstate!=NULL) {
721+
if (_PySys_Audit(tstate,"cpython.PyInterpreterState_New",NULL)<0) {
722+
return_PyStatus_ERR("sys.audit failed");
723+
}
717724
}
718725

719726
PyThread_type_lockpending_lock=PyThread_allocate_lock();
720727
if (pending_lock==NULL) {
721-
if (tstate!=NULL) {
722-
_PyErr_NoMemory(tstate);
723-
}
724-
returnNULL;
728+
return_PyStatus_NO_MEMORY();
725729
}
726730

727-
/* Don't get runtime from tstate since tstate can be NULL. */
728-
structpyinterpreters*interpreters=&runtime->interpreters;
729-
730731
/* We completely serialize creation of multiple interpreters, since
731732
it simplifies things here and blocking concurrent calls isn't a problem.
732733
Regardless, we must fully block subinterpreter creation until
733734
after the main interpreter is created. */
734735
HEAD_LOCK(runtime);
735736

737+
structpyinterpreters*interpreters=&runtime->interpreters;
736738
int64_tid=interpreters->next_id;
737739
interpreters->next_id+=1;
738740

739741
// Allocate the interpreter and add it to the runtime state.
742+
PyInterpreterState*interp;
743+
PyStatusstatus;
740744
PyInterpreterState*old_head=interpreters->head;
741745
if (old_head==NULL) {
742746
// We are creating the main interpreter.
@@ -755,36 +759,59 @@ PyInterpreterState_New(void)
755759

756760
interp=alloc_interpreter();
757761
if (interp==NULL) {
762+
status=_PyStatus_NO_MEMORY();
758763
gotoerror;
759764
}
760765
// Set to _PyInterpreterState_INIT.
761-
memcpy(interp,&initial._main_interpreter,
762-
sizeof(*interp));
766+
memcpy(interp,&initial._main_interpreter,sizeof(*interp));
763767

764768
if (id<0) {
765769
/* overflow or Py_Initialize() not called yet! */
766-
if (tstate!=NULL) {
767-
_PyErr_SetString(tstate,PyExc_RuntimeError,
768-
"failed to get an interpreter ID");
769-
}
770+
status=_PyStatus_ERR("failed to get an interpreter ID");
770771
gotoerror;
771772
}
772773
}
773774
interpreters->head=interp;
774775

775-
init_interpreter(interp,runtime,id,old_head,pending_lock);
776+
status=init_interpreter(interp,runtime,
777+
id,old_head,pending_lock);
778+
if (_PyStatus_EXCEPTION(status)) {
779+
gotoerror;
780+
}
781+
pending_lock=NULL;
776782

777783
HEAD_UNLOCK(runtime);
778-
returninterp;
784+
785+
assert(interp!=NULL);
786+
*pinterp=interp;
787+
return_PyStatus_OK();
779788

780789
error:
781790
HEAD_UNLOCK(runtime);
782791

783-
PyThread_free_lock(pending_lock);
792+
if (pending_lock!=NULL) {
793+
PyThread_free_lock(pending_lock);
794+
}
784795
if (interp!=NULL) {
785796
free_interpreter(interp);
786797
}
787-
returnNULL;
798+
returnstatus;
799+
}
800+
801+
802+
PyInterpreterState*
803+
PyInterpreterState_New(void)
804+
{
805+
// tstate can be NULL
806+
PyThreadState*tstate=current_fast_get(&_PyRuntime);
807+
808+
PyInterpreterState*interp;
809+
PyStatusstatus=_PyInterpreterState_New(tstate,&interp);
810+
if (_PyStatus_EXCEPTION(status)) {
811+
Py_ExitStatusException(status);
812+
}
813+
assert(interp!=NULL);
814+
returninterp;
788815
}
789816

790817

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp