Skip to content

Commit 10911d6

Browse files
authored
Merge pull request #1312 from aisk/sys_flags
using cpython's `sys.flags` inplementation
2 parents 586a8c6 + c7b8aa6 commit 10911d6

File tree

1 file changed

+92
-45
lines changed

1 file changed

+92
-45
lines changed

src/runtime/builtin_modules/sys.cpp

Lines changed: 92 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ extern "C" {
4242
int Py_BytesWarningFlag = 0;
4343
int Py_DivisionWarningFlag = 0;
4444
int Py_HashRandomizationFlag = 0;
45+
int Py_DebugFlag = 0;
46+
int _Py_QnewFlag = 0;
47+
int Py_DontWriteBytecodeFlag = 0;
48+
int Py_NoUserSiteDirectory = 0;
4549
}
4650

4751
Box* sysExcInfo() {
@@ -229,35 +233,6 @@ void prependToSysPath(llvm::StringRef path) {
229233
NULL, NULL));
230234
}
231235

232-
static BoxedClass* sys_flags_cls;
233-
class BoxedSysFlags : public Box {
234-
public:
235-
Box* division_warning, *bytes_warning, *no_user_site, *optimize;
236-
237-
BoxedSysFlags() {
238-
auto zero = boxInt(0);
239-
assert(zero);
240-
division_warning = incref(zero);
241-
bytes_warning = incref(zero);
242-
no_user_site = incref(zero);
243-
optimize = incref(zero);
244-
Py_DECREF(zero);
245-
}
246-
247-
DEFAULT_CLASS(sys_flags_cls);
248-
249-
static Box* __new__(Box* cls, Box* args, Box* kwargs) {
250-
raiseExcHelper(TypeError, "cannot create 'sys.flags' instances");
251-
}
252-
253-
static void dealloc(BoxedSysFlags* self) {
254-
Py_DECREF(self->division_warning);
255-
Py_DECREF(self->bytes_warning);
256-
Py_DECREF(self->no_user_site);
257-
Py_DECREF(self->optimize);
258-
}
259-
};
260-
261236
static std::string generateVersionString() {
262237
std::ostringstream oss;
263238
oss << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << '.' << PY_MICRO_VERSION;
@@ -570,6 +545,87 @@ static PyMethodDef sys_methods[] = {
570545
{ "getsizeof", (PyCFunction)sys_getsizeof, METH_VARARGS | METH_KEYWORDS, getsizeof_doc },
571546
};
572547

548+
PyDoc_STRVAR(flags__doc__, "sys.flags\n\
549+
\n\
550+
Flags provided through command line arguments or environment vars.");
551+
552+
static struct _typeobject FlagsType;
553+
554+
static PyStructSequence_Field flags_fields[] = {
555+
{ "debug", "-d" },
556+
{ "py3k_warning", "-3" },
557+
{ "division_warning", "-Q" },
558+
{ "division_new", "-Qnew" },
559+
{ "inspect", "-i" },
560+
{ "interactive", "-i" },
561+
{ "optimize", "-O or -OO" },
562+
{ "dont_write_bytecode", "-B" },
563+
{ "no_user_site", "-s" },
564+
{ "no_site", "-S" },
565+
{ "ignore_environment", "-E" },
566+
{ "tabcheck", "-t or -tt" },
567+
{ "verbose", "-v" },
568+
#ifdef RISCOS
569+
{ "riscos_wimp", "???" },
570+
#endif
571+
/* {"unbuffered", "-u"}, */
572+
{ "unicode", "-U" },
573+
/* {"skip_first", "-x"}, */
574+
{ "bytes_warning", "-b" },
575+
{ "hash_randomization", "-R" },
576+
{ 0, 0 },
577+
};
578+
579+
static PyStructSequence_Desc flags_desc = { "sys.flags", /* name */
580+
flags__doc__, /* doc */
581+
flags_fields, /* fields */
582+
#ifdef RISCOS
583+
17
584+
#else
585+
16
586+
#endif
587+
};
588+
589+
static PyObject* make_flags(void) {
590+
int pos = 0;
591+
PyObject* seq;
592+
593+
seq = PyStructSequence_New(&FlagsType);
594+
if (seq == NULL)
595+
return NULL;
596+
597+
#define SetFlag(flag) PyStructSequence_SET_ITEM(seq, pos++, PyInt_FromLong(flag))
598+
599+
SetFlag(Py_DebugFlag);
600+
SetFlag(Py_Py3kWarningFlag);
601+
SetFlag(Py_DivisionWarningFlag);
602+
SetFlag(_Py_QnewFlag);
603+
SetFlag(Py_InspectFlag);
604+
SetFlag(Py_InteractiveFlag);
605+
SetFlag(Py_OptimizeFlag);
606+
SetFlag(Py_DontWriteBytecodeFlag);
607+
SetFlag(Py_NoUserSiteDirectory);
608+
SetFlag(Py_NoSiteFlag);
609+
SetFlag(Py_IgnoreEnvironmentFlag);
610+
SetFlag(Py_TabcheckFlag);
611+
SetFlag(Py_VerboseFlag);
612+
#ifdef RISCOS
613+
SetFlag(Py_RISCOSWimpFlag);
614+
#endif
615+
/* SetFlag(saw_unbuffered_flag); */
616+
SetFlag(Py_UnicodeFlag);
617+
/* SetFlag(skipfirstline); */
618+
SetFlag(Py_BytesWarningFlag);
619+
SetFlag(Py_HashRandomizationFlag);
620+
#undef SetFlag
621+
622+
if (PyErr_Occurred()) {
623+
Py_DECREF(seq);
624+
return NULL;
625+
}
626+
return seq;
627+
}
628+
573629
PyDoc_STRVAR(version_info__doc__, "sys.version_info\n\
574630
\n\
575631
Version information as a named tuple.");
@@ -811,20 +867,6 @@ void setupSys() {
811867
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
812868
sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX));
813869

814-
sys_flags_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSysFlags), false, "flags", false, NULL,
815-
NULL, false);
816-
sys_flags_cls->giveAttr(
817-
"__new__", new BoxedFunction(FunctionMetadata::create((void*)BoxedSysFlags::__new__, UNKNOWN, 1, true, true)));
818-
sys_flags_cls->tp_dealloc = (destructor)BoxedSysFlags::dealloc;
819-
820-
sys_flags_cls->giveAttr("ignore_environment", boxInt(Py_IgnoreEnvironmentFlag));
821-
#define ADD(name) sys_flags_cls->giveAttrMember(STRINGIFY(name), T_OBJECT, offsetof(BoxedSysFlags, name));
822-
ADD(division_warning);
823-
ADD(bytes_warning);
824-
ADD(no_user_site);
825-
ADD(optimize);
826-
#undef ADD
827-
828870
#define SET_SYS_FROM_STRING(key, value) sys_module->giveAttr((key), (value))
829871
#ifdef Py_USING_UNICODE
830872
SET_SYS_FROM_STRING("maxunicode", PyInt_FromLong(PyUnicode_GetMax()));
@@ -837,15 +879,13 @@ void setupSys() {
837879
SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("legacy"));
838880
#endif
839881

840-
sys_flags_cls->freeze();
841882

842883
auto sys_str = getStaticString("sys");
843884
for (auto& md : sys_methods) {
844885
sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, NULL, sys_str));
845886
}
846887

847888
sys_module->giveAttrBorrowed("__displayhook__", sys_module->getattr(autoDecref(internStringMortal("displayhook"))));
848-
sys_module->giveAttr("flags", new BoxedSysFlags());
849889
}
850890

851891
void setupSysEnd() {
@@ -889,6 +929,13 @@ void setupSysEnd() {
889929
/* float_info */
890930
if (FloatInfoType.tp_name == 0)
891931
PyStructSequence_InitType((PyTypeObject*)&FloatInfoType, &float_info_desc);
932+
/* flags */
933+
if (FlagsType.tp_name == 0)
934+
PyStructSequence_InitType((PyTypeObject*)&FlagsType, &flags_desc);
935+
SET_SYS_FROM_STRING("flags", make_flags());
936+
/* prevent user from creating new instances */
937+
FlagsType.tp_init = NULL;
938+
FlagsType.tp_new = NULL;
892939
/* prevent user from creating new instances */
893940
FloatInfoType.tp_init = NULL;
894941
FloatInfoType.tp_new = NULL;

0 commit comments

Comments
 (0)