@@ -84,17 +84,24 @@ _PySys_GetObjectId(_Py_Identifier *key)
84
84
return sys_get_object_id (tstate , key );
85
85
}
86
86
87
+ static PyObject *
88
+ _PySys_GetObject (PyThreadState * tstate , const char * name )
89
+ {
90
+ PyObject * sysdict = tstate -> interp -> sysdict ;
91
+ if (sysdict == NULL ) {
92
+ return NULL ;
93
+ }
94
+ return _PyDict_GetItemStringWithError (sysdict , name );
95
+ }
96
+
87
97
PyObject *
88
98
PySys_GetObject (const char * name )
89
99
{
90
100
PyThreadState * tstate = _PyThreadState_GET ();
91
- PyObject * sd = tstate -> interp -> sysdict ;
92
- if (sd == NULL ) {
93
- return NULL ;
94
- }
101
+
95
102
PyObject * exc_type , * exc_value , * exc_tb ;
96
103
_PyErr_Fetch (tstate , & exc_type , & exc_value , & exc_tb );
97
- PyObject * value = _PyDict_GetItemStringWithError ( sd , name );
104
+ PyObject * value = _PySys_GetObject ( tstate , name );
98
105
/* XXX Suppress a new exception if it was raised and restore
99
106
* the old one. */
100
107
_PyErr_Restore (tstate , exc_type , exc_value , exc_tb );
@@ -2464,8 +2471,6 @@ static PyStructSequence_Field flags_fields[] = {
2464
2471
{"no_site" , "-S" },
2465
2472
{"ignore_environment" , "-E" },
2466
2473
{"verbose" , "-v" },
2467
- /* {"unbuffered", "-u"}, */
2468
- /* {"skip_first", "-x"}, */
2469
2474
{"bytes_warning" , "-b" },
2470
2475
{"quiet" , "-q" },
2471
2476
{"hash_randomization" , "-R" },
@@ -2482,21 +2487,27 @@ static PyStructSequence_Desc flags_desc = {
2482
2487
15
2483
2488
};
2484
2489
2485
- static PyObject *
2486
- make_flags ( PyThreadState * tstate )
2490
+ static int
2491
+ set_flags_from_config ( PyObject * flags , PyThreadState * tstate )
2487
2492
{
2488
2493
PyInterpreterState * interp = tstate -> interp ;
2489
2494
const PyPreConfig * preconfig = & interp -> runtime -> preconfig ;
2490
2495
const PyConfig * config = _PyInterpreterState_GetConfig (interp );
2491
2496
2492
- PyObject * seq = PyStructSequence_New (& FlagsType );
2493
- if (seq == NULL ) {
2494
- return NULL ;
2495
- }
2496
-
2497
- int pos = 0 ;
2498
- #define SetFlag (flag ) \
2499
- PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag))
2497
+ // _PySys_UpdateConfig() modifies sys.flags in-place:
2498
+ // Py_XDECREF() is needed in this case.
2499
+ Py_ssize_t pos = 0 ;
2500
+ #define SetFlagObj (expr ) \
2501
+ do { \
2502
+ PyObject *value = (expr); \
2503
+ if (value == NULL) { \
2504
+ return -1; \
2505
+ } \
2506
+ Py_XDECREF(PyStructSequence_GET_ITEM(flags, pos)); \
2507
+ PyStructSequence_SET_ITEM(flags, pos, value); \
2508
+ pos++; \
2509
+ } while (0)
2510
+ #define SetFlag (expr ) SetFlagObj(PyLong_FromLong(expr))
2500
2511
2501
2512
SetFlag (config -> parser_debug );
2502
2513
SetFlag (config -> inspect );
@@ -2507,23 +2518,34 @@ make_flags(PyThreadState *tstate)
2507
2518
SetFlag (!config -> site_import );
2508
2519
SetFlag (!config -> use_environment );
2509
2520
SetFlag (config -> verbose );
2510
- /* SetFlag(saw_unbuffered_flag); */
2511
- /* SetFlag(skipfirstline); */
2512
2521
SetFlag (config -> bytes_warning );
2513
2522
SetFlag (config -> quiet );
2514
2523
SetFlag (config -> use_hash_seed == 0 || config -> hash_seed != 0 );
2515
2524
SetFlag (config -> isolated );
2516
- PyStructSequence_SET_ITEM ( seq , pos ++ , PyBool_FromLong (config -> dev_mode ));
2525
+ SetFlagObj ( PyBool_FromLong (config -> dev_mode ));
2517
2526
SetFlag (preconfig -> utf8_mode );
2527
+ #undef SetFlagObj
2518
2528
#undef SetFlag
2529
+ return 0 ;
2530
+ }
2519
2531
2520
- if (_PyErr_Occurred (tstate )) {
2521
- Py_DECREF (seq );
2532
+
2533
+ static PyObject *
2534
+ make_flags (PyThreadState * tstate )
2535
+ {
2536
+ PyObject * flags = PyStructSequence_New (& FlagsType );
2537
+ if (flags == NULL ) {
2522
2538
return NULL ;
2523
2539
}
2524
- return seq ;
2540
+
2541
+ if (set_flags_from_config (flags , tstate ) < 0 ) {
2542
+ Py_DECREF (flags );
2543
+ return NULL ;
2544
+ }
2545
+ return flags ;
2525
2546
}
2526
2547
2548
+
2527
2549
PyDoc_STRVAR (version_info__doc__ ,
2528
2550
"sys.version_info\n\
2529
2551
\n\
@@ -2767,14 +2789,23 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
2767
2789
/* implementation */
2768
2790
SET_SYS ("implementation" , make_impl_info (version_info ));
2769
2791
2770
- /* flags */
2792
+ // sys. flags: updated in-place later by _PySys_UpdateConfig()
2771
2793
if (FlagsType .tp_name == 0 ) {
2772
2794
if (PyStructSequence_InitType2 (& FlagsType , & flags_desc ) < 0 ) {
2773
2795
goto type_init_failed ;
2774
2796
}
2775
2797
}
2776
- /* Set flags to their default values (updated by _PySys_InitMain()) */
2777
2798
SET_SYS ("flags" , make_flags (tstate ));
2799
+ /* prevent user from creating new instances */
2800
+ FlagsType .tp_init = NULL ;
2801
+ FlagsType .tp_new = NULL ;
2802
+ res = PyDict_DelItemString (FlagsType .tp_dict , "__new__" );
2803
+ if (res < 0 ) {
2804
+ if (!_PyErr_ExceptionMatches (tstate , PyExc_KeyError )) {
2805
+ goto err_occurred ;
2806
+ }
2807
+ _PyErr_Clear (tstate );
2808
+ }
2778
2809
2779
2810
#if defined(MS_WINDOWS )
2780
2811
/* getwindowsversion */
@@ -2876,8 +2907,10 @@ sys_create_xoptions_dict(const PyConfig *config)
2876
2907
}
2877
2908
2878
2909
2910
+ // Update sys attributes for a new PyConfig configuration.
2911
+ // This function also adds attributes that _PySys_InitCore() didn't add.
2879
2912
int
2880
- _PySys_InitMain (PyThreadState * tstate )
2913
+ _PySys_UpdateConfig (PyThreadState * tstate )
2881
2914
{
2882
2915
PyObject * sysdict = tstate -> interp -> sysdict ;
2883
2916
const PyConfig * config = _PyInterpreterState_GetConfig (tstate -> interp );
@@ -2914,28 +2947,16 @@ _PySys_InitMain(PyThreadState *tstate)
2914
2947
#undef COPY_LIST
2915
2948
#undef SET_SYS_FROM_WSTR
2916
2949
2917
-
2918
- /* Set flags to their final values */
2919
- SET_SYS ("flags" , make_flags (tstate ));
2920
- /* prevent user from creating new instances */
2921
- FlagsType .tp_init = NULL ;
2922
- FlagsType .tp_new = NULL ;
2923
- res = PyDict_DelItemString (FlagsType .tp_dict , "__new__" );
2924
- if (res < 0 ) {
2925
- if (!_PyErr_ExceptionMatches (tstate , PyExc_KeyError )) {
2926
- return res ;
2927
- }
2928
- _PyErr_Clear (tstate );
2950
+ // sys.flags
2951
+ PyObject * flags = _PySys_GetObject (tstate , "flags" ); // borrowed ref
2952
+ if (flags == NULL ) {
2953
+ return -1 ;
2929
2954
}
2930
-
2931
- SET_SYS ("dont_write_bytecode" , PyBool_FromLong (!config -> write_bytecode ));
2932
-
2933
- if (get_warnoptions (tstate ) == NULL ) {
2955
+ if (set_flags_from_config (flags , tstate ) < 0 ) {
2934
2956
return -1 ;
2935
2957
}
2936
2958
2937
- if (get_xoptions (tstate ) == NULL )
2938
- return -1 ;
2959
+ SET_SYS ("dont_write_bytecode" , PyBool_FromLong (!config -> write_bytecode ));
2939
2960
2940
2961
if (_PyErr_Occurred (tstate )) {
2941
2962
goto err_occurred ;
@@ -2977,8 +2998,8 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict)
2977
2998
}
2978
2999
2979
3000
2980
- /* Create sys module without all attributes: _PySys_InitMain() should be called
2981
- later to add remaining attributes. */
3001
+ /* Create sys module without all attributes.
3002
+ _PySys_UpdateConfig() should be called later to add remaining attributes. */
2982
3003
PyStatus
2983
3004
_PySys_Create (PyThreadState * tstate , PyObject * * sysmod_p )
2984
3005
{
0 commit comments