Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Lib/test/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2993,6 +2993,12 @@ def test_type_doc(self):
A.__doc__ = doc
self.assertEqual(A.__doc__, doc)

def test_type_frozendict(self):
A = type('A', (), frozendict({'x': 4, 'y': 2}))
self.assertEqual(A.x, 4)
self.assertEqual(A.y, 2)
self.assertEqual(A.__name__, 'A')

def test_bad_args(self):
with self.assertRaises(TypeError):
type()
Expand Down
7 changes: 7 additions & 0 deletions Lib/test/test_str.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,13 @@ def test_maketrans_translate(self):
self.assertEqual("[a\xe9]".translate(str.maketrans({'a': '<\u20ac>'})),
"[<\u20ac>\xe9]")

# with frozendict
tbl = self.type2test.maketrans(frozendict({'s': 'S', 'T': 't'}))
self.assertEqual(tbl, {ord('s'): 'S', ord('T'): 't'})
self.assertEqual('sTan'.translate(tbl), 'Stan')
tbl = self.type2test.maketrans(frozendict({'a': None, 'b': '<i>'}))
self.checkequalnofix('<i><i><i>c', 'abababc', 'translate', tbl)

# invalid Unicode characters
invalid_char = 0x10ffff+1
for before in "a\xe9\u20ac\U0010ffff":
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:meth:`str.maketrans` and :func:`type` now accept :class:`frozendict`.
28 changes: 23 additions & 5 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -4872,9 +4872,21 @@ type_new_get_slots(type_new_ctx *ctx, PyObject *dict)
static PyTypeObject*
type_new_init(type_new_ctx *ctx)
{
PyObject *dict = PyDict_Copy(ctx->orig_dict);
if (dict == NULL) {
goto error;
PyObject *dict;
if (PyFrozenDict_Check(ctx->orig_dict)) {
Comment thread
eendebakpt marked this conversation as resolved.
dict = PyDict_New();
if (dict == NULL) {
goto error;
}
if (PyDict_Merge(dict, ctx->orig_dict, 1) < 0) {
goto error;
}
}
else {
dict = PyDict_Copy(ctx->orig_dict);
if (dict == NULL) {
goto error;
}
}

if (type_new_get_slots(ctx, dict) < 0) {
Expand Down Expand Up @@ -5037,13 +5049,19 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)

/* Parse arguments: (name, bases, dict) */
PyObject *name, *bases, *orig_dict;
if (!PyArg_ParseTuple(args, "UO!O!:type.__new__",
if (!PyArg_ParseTuple(args, "UO!O:type.__new__",
&name,
&PyTuple_Type, &bases,
&PyDict_Type, &orig_dict))
&orig_dict))
{
return NULL;
}
if (!PyAnyDict_Check(orig_dict)) {
PyErr_Format(PyExc_TypeError,
"type.__new__() argument 3 must be dict, not %T",
Comment thread
StanFromIreland marked this conversation as resolved.
Outdated
orig_dict);
return NULL;
}

type_new_ctx ctx = {
.metatype = metatype,
Expand Down
2 changes: 1 addition & 1 deletion Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -13149,7 +13149,7 @@ unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z)
const void *data;

/* x must be a dict */
if (!PyDict_CheckExact(x)) {
if (!PyAnyDict_CheckExact(x)) {
PyErr_SetString(PyExc_TypeError, "if you give only one argument "
"to maketrans it must be a dict");
goto err;
Expand Down
Loading