Skip to content

Commit ec27cf1

Browse files
committed
Merge branch 'main' into try-find-rename
2 parents ddf2623 + 8dde2ed commit ec27cf1

2 files changed

Lines changed: 54 additions & 45 deletions

File tree

src/pysorteddict/sorted_dict_type.cc

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,51 @@ static PyTypeObject* PyWindowsPath_Type;
6262
static PyTypeObject* PyStructTime_Type;
6363
static PyTypeObject* PyUUID_Type;
6464

65+
/**
66+
* Try to set the key type of the sorted dictionary. It should not already be
67+
* set. The provided argument should not be a null pointer.
68+
*
69+
* @param key_type Key type.
70+
*
71+
* @return `true` if successful, else `false`.
72+
*/
73+
bool SortedDictType::try_set_key_type(PyObject* key_type)
74+
{
75+
static PyTypeObject* allowed_key_types[] = {
76+
&PyBool_Type,
77+
&PyBytes_Type,
78+
&PyFloat_Type,
79+
&PyLong_Type,
80+
&PyUnicode_Type,
81+
// The following types are not built-in.
82+
PyDate_Type = import_python_type("datetime", "date"),
83+
PyTimeDelta_Type = import_python_type("datetime", "timedelta"),
84+
PyDecimal_Type = import_python_type("decimal", "Decimal"),
85+
PyFraction_Type = import_python_type("fractions", "Fraction"),
86+
PyIPv4Address_Type = import_python_type("ipaddress", "IPv4Address"),
87+
PyIPv4Interface_Type = import_python_type("ipaddress", "IPv4Interface"),
88+
PyIPv4Network_Type = import_python_type("ipaddress", "IPv4Network"),
89+
PyIPv6Address_Type = import_python_type("ipaddress", "IPv6Address"),
90+
PyIPv6Interface_Type = import_python_type("ipaddress", "IPv6Interface"),
91+
PyIPv6Network_Type = import_python_type("ipaddress", "IPv6Network"),
92+
PyPosixPath_Type = import_python_type("pathlib", "PosixPath"),
93+
PyPurePosixPath_Type = import_python_type("pathlib", "PurePosixPath"),
94+
PyPureWindowsPath_Type = import_python_type("pathlib", "PureWindowsPath"),
95+
PyWindowsPath_Type = import_python_type("pathlib", "WindowsPath"),
96+
PyStructTime_Type = import_python_type("time", "struct_time"),
97+
PyUUID_Type = import_python_type("uuid", "UUID"),
98+
};
99+
for (PyTypeObject* allowed_key_type : allowed_key_types)
100+
{
101+
if (allowed_key_type != nullptr && Py_Is(key_type, reinterpret_cast<PyObject*>(allowed_key_type)))
102+
{
103+
this->key_type = allowed_key_type;
104+
return true;
105+
}
106+
}
107+
return false;
108+
}
109+
65110
/**
66111
* Check whether the given key can be inserted into this sorted dictionary. For
67112
* instance, NaN cannot be compared with other floating-point numbers, so it
@@ -125,8 +170,10 @@ bool SortedDictType::are_key_type_and_key_value_pair_good(PyObject* key, PyObjec
125170
}
126171

127172
// The first key-value pair is being inserted.
128-
if (this->set_key_type(reinterpret_cast<PyObject*>(Py_TYPE(key)), key) == -1)
173+
PyObject* key_type = reinterpret_cast<PyObject*>(Py_TYPE(key));
174+
if (!this->try_set_key_type(key_type))
129175
{
176+
PyErr_Format(PyExc_TypeError, "got key %R of unsupported type %R", key, key_type);
130177
return false;
131178
}
132179
key_type_set_here = true;
@@ -637,7 +684,7 @@ PyObject* SortedDictType::get_key_type(void)
637684
return Py_NewRef(this->key_type); // 🆕
638685
}
639686

640-
int SortedDictType::set_key_type(PyObject* key_type, PyObject* key)
687+
int SortedDictType::set_key_type(PyObject* key_type)
641688
{
642689
if (key_type == nullptr)
643690
{
@@ -655,51 +702,12 @@ int SortedDictType::set_key_type(PyObject* key_type, PyObject* key)
655702
return -1;
656703
}
657704

658-
static PyTypeObject* allowed_key_types[] = {
659-
&PyBool_Type,
660-
&PyBytes_Type,
661-
&PyFloat_Type,
662-
&PyLong_Type,
663-
&PyUnicode_Type,
664-
// The following types are not built-in.
665-
PyDate_Type = import_python_type("datetime", "date"),
666-
PyTimeDelta_Type = import_python_type("datetime", "timedelta"),
667-
PyDecimal_Type = import_python_type("decimal", "Decimal"),
668-
PyFraction_Type = import_python_type("fractions", "Fraction"),
669-
PyIPv4Address_Type = import_python_type("ipaddress", "IPv4Address"),
670-
PyIPv4Interface_Type = import_python_type("ipaddress", "IPv4Interface"),
671-
PyIPv4Network_Type = import_python_type("ipaddress", "IPv4Network"),
672-
PyIPv6Address_Type = import_python_type("ipaddress", "IPv6Address"),
673-
PyIPv6Interface_Type = import_python_type("ipaddress", "IPv6Interface"),
674-
PyIPv6Network_Type = import_python_type("ipaddress", "IPv6Network"),
675-
PyPosixPath_Type = import_python_type("pathlib", "PosixPath"),
676-
PyPurePosixPath_Type = import_python_type("pathlib", "PurePosixPath"),
677-
PyPureWindowsPath_Type = import_python_type("pathlib", "PureWindowsPath"),
678-
PyWindowsPath_Type = import_python_type("pathlib", "WindowsPath"),
679-
PyStructTime_Type = import_python_type("time", "struct_time"),
680-
PyUUID_Type = import_python_type("uuid", "UUID"),
681-
};
682-
for (PyTypeObject* allowed_key_type : allowed_key_types)
705+
if (!this->try_set_key_type(key_type))
683706
{
684-
if (allowed_key_type != nullptr && Py_Is(key_type, reinterpret_cast<PyObject*>(allowed_key_type)))
685-
{
686-
this->key_type = allowed_key_type;
687-
return 0;
688-
}
689-
}
690-
691-
if (key != nullptr)
692-
{
693-
// The user supplied a key of the wrong type.
694-
PyErr_Format(PyExc_TypeError, "got key %R of unsupported type %R", key, key_type);
695-
}
696-
else
697-
{
698-
// The user supplied a wrong value (which should have been a supported
699-
// type).
700707
PyErr_Format(PyExc_ValueError, "got %R, want a supported key type", key_type);
708+
return -1;
701709
}
702-
return -1;
710+
return 0;
703711
}
704712

705713
int SortedDictType::init(PyObject* args, PyObject* kwargs)

src/pysorteddict/sorted_dict_type.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ private:
6363
Py_ssize_t known_referrers;
6464

6565
private:
66+
bool try_set_key_type(PyObject*);
6667
bool is_key_good(PyObject*);
6768
bool are_key_type_and_key_value_pair_good(PyObject*, PyObject* value = nullptr);
6869
bool is_deletion_allowed(void);
@@ -93,7 +94,7 @@ public:
9394
PyObject* update(PyObject* const*, Py_ssize_t, PyObject*);
9495
PyObject* values(PyTypeObject*);
9596
PyObject* get_key_type(void);
96-
int set_key_type(PyObject*, PyObject* key = nullptr);
97+
int set_key_type(PyObject*);
9798
int init(PyObject*, PyObject*);
9899
static PyObject* New(PyTypeObject*, PyObject*, PyObject*);
99100

0 commit comments

Comments
 (0)