@@ -2820,6 +2820,8 @@ AssocList_Sort(AssocList* list) {
28202820#define MS_TYPE_TYPEDDICT (1ull << 33)
28212821#define MS_TYPE_DATACLASS (1ull << 34)
28222822#define MS_TYPE_NAMEDTUPLE (1ull << 35)
2823+ #define MS_TYPE_BOOLLITERAL_TRUE (1ull << 36)
2824+ #define MS_TYPE_BOOLLITERAL_FALSE (1ull << 37)
28232825/* Constraints */
28242826#define MS_CONSTR_INT_MIN (1ull << 42)
28252827#define MS_CONSTR_INT_MAX (1ull << 43)
@@ -2943,6 +2945,8 @@ typedef struct {
29432945 PyObject *int_lookup;
29442946 PyObject *str_lookup;
29452947 bool literal_none;
2948+ bool literal_bool_true;
2949+ bool literal_bool_false;
29462950} LiteralInfo;
29472951
29482952typedef struct {
@@ -3543,6 +3547,8 @@ typedef struct {
35433547 PyObject *literal_str_values;
35443548 PyObject *literal_str_lookup;
35453549 bool literal_none;
3550+ bool literal_bool_true;
3551+ bool literal_bool_false;
35463552 /* Constraints */
35473553 int64_t c_int_min;
35483554 int64_t c_int_max;
@@ -4433,6 +4439,14 @@ typenode_collect_literal(TypeNodeCollectState *state, PyObject *literal) {
44334439 if (obj == Py_None || obj == NONE_TYPE) {
44344440 state->literal_none = true;
44354441 }
4442+ else if (type == &PyBool_Type) {
4443+ if (obj == Py_True) {
4444+ state->literal_bool_true = true;
4445+ }
4446+ else {
4447+ state->literal_bool_false = true;
4448+ }
4449+ }
44364450 else if (type == &PyLong_Type) {
44374451 if (state->literal_int_values == NULL) {
44384452 state->literal_int_values = PySet_New(NULL);
@@ -4469,7 +4483,7 @@ typenode_collect_literal(TypeNodeCollectState *state, PyObject *literal) {
44694483invalid:
44704484 PyErr_Format(
44714485 PyExc_TypeError,
4472- "Literal may only contain None/integers/strings - %R is not supported",
4486+ "Literal may only contain None/booleans/ integers/strings - %R is not supported",
44734487 literal
44744488 );
44754489
@@ -4507,6 +4521,12 @@ typenode_collect_convert_literals(TypeNodeCollectState *state) {
45074521 if (info->literal_none) {
45084522 state->types |= MS_TYPE_NONE;
45094523 }
4524+ if (info->literal_bool_true) {
4525+ state->types |= MS_TYPE_BOOLLITERAL_TRUE;
4526+ }
4527+ if (info->literal_bool_false) {
4528+ state->types |= MS_TYPE_BOOLLITERAL_FALSE;
4529+ }
45104530 Py_DECREF(cached);
45114531 return 0;
45124532 }
@@ -4535,6 +4555,12 @@ typenode_collect_convert_literals(TypeNodeCollectState *state) {
45354555 if (state->literal_none) {
45364556 state->types |= MS_TYPE_NONE;
45374557 }
4558+ if (state->literal_bool_true) {
4559+ state->types |= MS_TYPE_BOOLLITERAL_TRUE;
4560+ }
4561+ if (state->literal_bool_false) {
4562+ state->types |= MS_TYPE_BOOLLITERAL_FALSE;
4563+ }
45384564
45394565 if (n == 1) {
45404566 /* A single `Literal` object, cache the lookups on it */
@@ -4545,6 +4571,8 @@ typenode_collect_convert_literals(TypeNodeCollectState *state) {
45454571 Py_XINCREF(state->literal_str_lookup);
45464572 info->str_lookup = state->literal_str_lookup;
45474573 info->literal_none = state->literal_none;
4574+ info->literal_bool_true = state->literal_bool_true;
4575+ info->literal_bool_false = state->literal_bool_false;
45484576 PyObject_GC_Track(info);
45494577 PyObject *literal = PyList_GET_ITEM(state->literals, 0);
45504578 int status = PyObject_SetAttr(
@@ -15338,6 +15366,14 @@ mpack_decode_bool(DecoderState *self, PyObject *val, TypeNode *type, PathNode *p
1533815366 Py_INCREF(val);
1533915367 return val;
1534015368 }
15369+ if (val == Py_True && (type->types & MS_TYPE_BOOLLITERAL_TRUE)) {
15370+ Py_INCREF(Py_True);
15371+ return Py_True;
15372+ }
15373+ if (val == Py_False && (type->types & MS_TYPE_BOOLLITERAL_FALSE)) {
15374+ Py_INCREF(Py_False);
15375+ return Py_False;
15376+ }
1534115377 return ms_validation_error("bool", type, path);
1534215378}
1534315379
@@ -16963,7 +16999,7 @@ json_decode_true(JSONDecoderState *self, TypeNode *type, PathNode *path) {
1696316999 if (MS_UNLIKELY(c1 != 'r' || c2 != 'u' || c3 != 'e')) {
1696417000 return json_err_invalid(self, "invalid character");
1696517001 }
16966- if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL)) {
17002+ if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL | MS_TYPE_BOOLLITERAL_TRUE )) {
1696717003 Py_INCREF(Py_True);
1696817004 return Py_True;
1696917005 }
@@ -16984,7 +17020,7 @@ json_decode_false(JSONDecoderState *self, TypeNode *type, PathNode *path) {
1698417020 if (MS_UNLIKELY(c1 != 'a' || c2 != 'l' || c3 != 's' || c4 != 'e')) {
1698517021 return json_err_invalid(self, "invalid character");
1698617022 }
16987- if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL)) {
17023+ if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL | MS_TYPE_BOOLLITERAL_FALSE )) {
1698817024 Py_INCREF(Py_False);
1698917025 return Py_False;
1699017026 }
@@ -20635,6 +20671,14 @@ convert_bool(
2063520671 Py_INCREF(obj);
2063620672 return obj;
2063720673 }
20674+ if (obj == Py_True && (type->types & MS_TYPE_BOOLLITERAL_TRUE)) {
20675+ Py_INCREF(Py_True);
20676+ return Py_True;
20677+ }
20678+ if (obj == Py_False && (type->types & MS_TYPE_BOOLLITERAL_FALSE)) {
20679+ Py_INCREF(Py_False);
20680+ return Py_False;
20681+ }
2063820682 return ms_validation_error("bool", type, path);
2063920683}
2064020684
0 commit comments