Skip to content

Commit f7c324d

Browse files
committed
Remove circular import; import 'uuid' from '_uuid' lazily
1 parent e81f774 commit f7c324d

1 file changed

Lines changed: 49 additions & 48 deletions

File tree

Modules/_uuidmodule.c

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ static int from_hex(uuidobject *self, PyObject *hex);
200200
static int from_bytes_le(uuidobject *self, Py_buffer *bytes_le);
201201
static int from_int(uuidobject *self, PyObject *int_value, int validate);
202202
static int from_fields(uuidobject *self, PyObject *fields);
203+
static PyObject * get_SafeUUID(uuid_state *state);
203204

204205
static uint64_t
205206
uuid_getpid(void) {
@@ -514,8 +515,6 @@ _uuid_UUID___init___impl(uuidobject *self, PyObject *hex, Py_buffer *bytes,
514515
/*[clinic end generated code: output=93a6881c8f79bf9b input=b9c79672fbd76a99]*/
515516

516517
{
517-
uuid_state *state = get_uuid_state_by_cls(Py_TYPE(self));
518-
519518
int passed = 0;
520519
if (hex != NULL) passed++;
521520
if (bytes->obj != NULL) passed++;
@@ -584,13 +583,13 @@ _uuid_UUID___init___impl(uuidobject *self, PyObject *hex, Py_buffer *bytes,
584583
self->bytes[6] |= (version_num << 4);
585584
}
586585

586+
if (is_safe == Py_None) {
587+
// Py_None is immortal; skip decref
588+
is_safe = NULL;
589+
}
587590
if (is_safe != NULL) {
588-
// Validate by calling SafeUUID(is_safe) to ensure it's a valid enum member
589-
PyObject *validated = PyObject_CallOneArg(state->safe_uuid, is_safe);
590-
if (validated == NULL) {
591-
return -1;
592-
}
593-
Py_XSETREF(self->is_safe, validated);
591+
Py_INCREF(is_safe);
592+
Py_XSETREF(self->is_safe, is_safe);
594593
}
595594

596595
return 0;
@@ -937,6 +936,33 @@ get_int(uuidobject *self)
937936
return _PyLong_FromByteArray((unsigned char *)self->bytes, 16, 0, 0);
938937
}
939938

939+
static PyObject *
940+
get_uuidmod_attr(uuid_state *state, const char *name)
941+
{
942+
PyObject *mod = PyImport_ImportModule("uuid");
943+
if (mod == NULL) {
944+
return NULL;
945+
}
946+
947+
PyObject *ret = PyObject_GetAttrString(mod, name);
948+
Py_DECREF(mod);
949+
return ret;
950+
}
951+
952+
static PyObject *
953+
get_SafeUUID(uuid_state *state)
954+
{
955+
if (state->safe_uuid != NULL) {
956+
return Py_NewRef(state->safe_uuid);
957+
}
958+
959+
state->safe_uuid = get_uuidmod_attr(state, "SafeUUID");
960+
if (state->safe_uuid == NULL) {
961+
return NULL;
962+
}
963+
return Py_NewRef(state->safe_uuid);
964+
}
965+
940966
static uuidobject *
941967
make_uuid(PyTypeObject *type)
942968
{
@@ -1024,7 +1050,10 @@ Uuid_get_is_safe(PyObject *o, void *closure)
10241050
uuidobject *self = (uuidobject *)o;
10251051
uuid_state *state = get_uuid_state_by_cls(Py_TYPE(self));
10261052
if (self->is_safe == NULL) {
1027-
return PyObject_GetAttrString(state->safe_uuid, "unknown");
1053+
PyObject *SafeUUID = get_SafeUUID(state);
1054+
PyObject *ret = PyObject_GetAttrString(SafeUUID, "unknown");
1055+
Py_DECREF(SafeUUID);
1056+
return ret;
10281057
}
10291058
return Py_NewRef(self->is_safe);
10301059
}
@@ -1040,19 +1069,6 @@ Uuid_get_hex(PyObject *o, void *closure)
10401069
return PyUnicode_FromStringAndSize(hex, 32);
10411070
}
10421071

1043-
static PyObject *
1044-
get_variant_marker(uuid_state *state, const char *name)
1045-
{
1046-
PyObject *mod = PyImport_ImportModule("uuid");
1047-
if (mod == NULL) {
1048-
return NULL;
1049-
}
1050-
1051-
PyObject *ret = PyObject_GetAttrString(mod, name);
1052-
Py_DECREF(mod);
1053-
return ret;
1054-
}
1055-
10561072
static PyObject *
10571073
Uuid_get_variant(PyObject *o, void *closure)
10581074
{
@@ -1064,23 +1080,23 @@ Uuid_get_variant(PyObject *o, void *closure)
10641080
// xxx - three high bits of variant_byte are unknown
10651081
if (!(variant_byte & 0x80)) { // & 0b1000_0000
10661082
// 0xx - RESERVED_NCS
1067-
return get_variant_marker(state, "RESERVED_NCS");
1083+
return get_uuidmod_attr(state, "RESERVED_NCS");
10681084
}
10691085

10701086
// 1xx -- we know that high bit must be 1
10711087
if (!(variant_byte & 0x40)) { // & 0b0100_0000
10721088
// 10x - RFC_4122
1073-
return get_variant_marker(state, "RFC_4122");
1089+
return get_uuidmod_attr(state, "RFC_4122");
10741090
}
10751091

10761092
// 11x -- we know that two high bits are 1
10771093
if (!(variant_byte & 0x20)) { // & 0b0010_0000
10781094
// 110 - RESERVED_MICROSOFT
1079-
return get_variant_marker(state, "RESERVED_MICROSOFT");
1095+
return get_uuidmod_attr(state, "RESERVED_MICROSOFT");
10801096
}
10811097

10821098
// 111 -- we know that all three high bits are 1 - RESERVED_FUTURE
1083-
return get_variant_marker(state, "RESERVED_FUTURE");
1099+
return get_uuidmod_attr(state, "RESERVED_FUTURE");
10841100
}
10851101

10861102
static int
@@ -1743,13 +1759,11 @@ static int
17431759
uuid_exec(PyObject *module)
17441760
{
17451761
uuid_state *state = get_uuid_state(module);
1746-
PyObject *uuid_mod = NULL;
1747-
PyObject *safe_uuid = NULL;
17481762

17491763
#define ADD_INT(NAME, VALUE) \
17501764
do { \
17511765
if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \
1752-
goto fail; \
1766+
return -1; \
17531767
} \
17541768
} while (0)
17551769

@@ -1779,24 +1793,17 @@ uuid_exec(PyObject *module)
17791793
NULL
17801794
);
17811795
if (state->UuidType == NULL) {
1782-
goto fail;
1796+
return -1;
17831797
}
17841798
if (PyModule_AddType(module, state->UuidType) < 0) {
1785-
goto fail;
1799+
return -1;
17861800
}
17871801

1788-
uuid_mod = PyImport_ImportModule("uuid");
1789-
if (uuid_mod == NULL) {
1790-
goto fail;
1791-
}
1792-
safe_uuid = state->safe_uuid = PyObject_GetAttrString(uuid_mod, "SafeUUID");
1793-
if (safe_uuid == NULL) {
1794-
goto fail;
1795-
}
1802+
state->safe_uuid = NULL;
17961803

17971804
state->uint128_max = compute_uuid_max();
17981805
if (state->uint128_max == NULL) {
1799-
goto fail;
1806+
return -1;
18001807
}
18011808

18021809
state->last_timestamp_v7 = 0;
@@ -1808,20 +1815,14 @@ uuid_exec(PyObject *module)
18081815
state->random_func = NULL;
18091816
state->random_size_int = PyLong_FromSize_t((Py_ssize_t)RANDOM_BUF_SIZE);
18101817
if (state->random_size_int == NULL) {
1811-
goto fail;
1818+
return -1;
18121819
}
1820+
state->random_idx = RANDOM_BUF_SIZE;
18131821

18141822
state->freelist = NULL;
18151823
state->freelist_size = 0;
18161824

1817-
state->random_idx = RANDOM_BUF_SIZE;
1818-
1819-
Py_CLEAR(uuid_mod);
18201825
return 0;
1821-
1822-
fail:
1823-
Py_CLEAR(uuid_mod);
1824-
return -1;
18251826
}
18261827

18271828
static PyMethodDef uuid_methods[] = {

0 commit comments

Comments
 (0)