Skip to content

Commit 23e190e

Browse files
committed
Address code review
1 parent 1f4a350 commit 23e190e

File tree

3 files changed

+52
-18
lines changed

3 files changed

+52
-18
lines changed

Include/internal/pycore_typeobject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,11 @@ extern unsigned int _PyType_GetVersionForCurrentState(PyTypeObject *tp);
269269
PyAPI_FUNC(void) _PyType_SetVersion(PyTypeObject *tp, unsigned int version);
270270
PyTypeObject *_PyType_LookupByVersion(unsigned int version);
271271

272+
// Returns 0 on success or caller-specific error on failure.
273+
typedef int (*_py_validate_type)(PyTypeObject *);
274+
// Returns 0 on success, -1 if no type version could be assigned, or the error returned by validate
275+
extern int _PyType_Validate(PyTypeObject *ty, _py_validate_type validate, unsigned int *tp_version);
276+
272277
#ifdef __cplusplus
273278
}
274279
#endif

Objects/typeobject.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5645,6 +5645,24 @@ _PyType_SetFlags(PyTypeObject *self, unsigned long mask, unsigned long flags)
56455645
END_TYPE_LOCK();
56465646
}
56475647

5648+
int
5649+
_PyType_Validate(PyTypeObject *ty, _py_validate_type validate, unsigned int *tp_version)
5650+
{
5651+
int err;
5652+
BEGIN_TYPE_LOCK();
5653+
err = validate(ty);
5654+
if (!err) {
5655+
if(assign_version_tag(_PyInterpreterState_GET(), ty)) {
5656+
*tp_version = ty->tp_version_tag;
5657+
}
5658+
else {
5659+
err = -1;
5660+
}
5661+
}
5662+
END_TYPE_LOCK();
5663+
return err;
5664+
}
5665+
56485666
static void
56495667
set_flags_recursive(PyTypeObject *self, unsigned long mask, unsigned long flags)
56505668
{

Python/specialize.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,6 +2690,25 @@ to_bool_fail_kind(PyObject *value)
26902690
return SPEC_FAIL_OTHER;
26912691
}
26922692

2693+
static int
2694+
check_type_always_true(PyTypeObject *ty)
2695+
{
2696+
PyNumberMethods *nb = ty->tp_as_number;
2697+
if (nb && nb->nb_bool) {
2698+
return SPEC_FAIL_TO_BOOL_NUMBER;
2699+
}
2700+
PyMappingMethods *mp = ty->tp_as_mapping;
2701+
if (mp && mp->mp_length) {
2702+
return SPEC_FAIL_TO_BOOL_MAPPING;
2703+
}
2704+
PySequenceMethods *sq = ty->tp_as_sequence;
2705+
if (sq && sq->sq_length) {
2706+
return SPEC_FAIL_TO_BOOL_SEQUENCE;
2707+
}
2708+
return 0;
2709+
}
2710+
2711+
26932712
void
26942713
_Py_Specialize_ToBool(_PyStackRef value_o, _Py_CODEUNIT *instr)
26952714
{
@@ -2718,33 +2737,25 @@ _Py_Specialize_ToBool(_PyStackRef value_o, _Py_CODEUNIT *instr)
27182737
return;
27192738
}
27202739
if (PyType_HasFeature(Py_TYPE(value), Py_TPFLAGS_HEAPTYPE)) {
2721-
PyNumberMethods *nb = Py_TYPE(value)->tp_as_number;
2722-
if (nb && nb->nb_bool) {
2723-
unspecialize(instr, SPEC_FAIL_TO_BOOL_NUMBER);
2724-
return;
2725-
}
2726-
PyMappingMethods *mp = Py_TYPE(value)->tp_as_mapping;
2727-
if (mp && mp->mp_length) {
2728-
unspecialize(instr, SPEC_FAIL_TO_BOOL_MAPPING);
2729-
return;
2730-
}
2731-
PySequenceMethods *sq = Py_TYPE(value)->tp_as_sequence;
2732-
if (sq && sq->sq_length) {
2733-
unspecialize(instr, SPEC_FAIL_TO_BOOL_SEQUENCE);
2740+
unsigned int version = 0;
2741+
int err = _PyType_Validate(Py_TYPE(value), check_type_always_true, &version);
2742+
if (err < 0) {
2743+
unspecialize(instr, SPEC_FAIL_OUT_OF_VERSIONS);
27342744
return;
27352745
}
2736-
if (!PyUnstable_Type_AssignVersionTag(Py_TYPE(value))) {
2737-
unspecialize(instr, SPEC_FAIL_OUT_OF_VERSIONS);
2746+
else if (err > 0) {
2747+
unspecialize(instr, err);
27382748
return;
27392749
}
2740-
uint32_t version = Py_TYPE(value)->tp_version_tag;
2750+
2751+
assert(err == 0);
27412752
if (version == 0) {
27422753
unspecialize(instr, SPEC_FAIL_OUT_OF_VERSIONS);
27432754
return;
27442755
}
2745-
specialize(instr, TO_BOOL_ALWAYS_TRUE);
2746-
write_u32(cache->version, version);
27472756
assert(version);
2757+
write_u32(cache->version, version);
2758+
specialize(instr, TO_BOOL_ALWAYS_TRUE);
27482759
return;
27492760
}
27502761
unspecialize(instr, to_bool_fail_kind(value));

0 commit comments

Comments
 (0)