|
1 | 1 |
|
2 | 2 |
|
3 | | -import ./pyobject |
| 3 | + |
4 | 4 | import ../Python/call |
5 | | -import ./[stringobject, iterobject, numobjects] |
6 | | -import ./noneobject |
7 | | -import ./exceptions |
| 5 | +import ./[ |
| 6 | + pyobject, |
| 7 | + exceptions, noneobject, |
| 8 | + stringobject, iterobject, |
| 9 | + setobject, |
| 10 | + numobjects, |
| 11 | + ] |
| 12 | +import ./abstract/[iter, dunder,] |
8 | 13 | import ./dictobject |
9 | 14 | export dictobject |
10 | 15 | from ../Utils/utils import DictError, `!!` |
| 16 | +import ../Python/getargs/vargs |
| 17 | +import ../Include/cpython/critical_section |
11 | 18 |
|
12 | 19 | # redeclare this for these are "private" macros |
13 | 20 |
|
@@ -66,3 +73,50 @@ implDictMagic init: |
66 | 73 | pyNone |
67 | 74 | else: |
68 | 75 | errArgNum argsLen, 1 |
| 76 | + |
| 77 | + |
| 78 | +proc fromkeys(mp: PyDictObject, iterable: PyDictObject|PySetObject|PyFrozenSetObject, value: PyObject): PyDictObject = |
| 79 | + for k in iterable: |
| 80 | + ## iterable is already a dict, so its keys must be hashable |
| 81 | + DictError!!(mp[k] = value) |
| 82 | + mp |
| 83 | + |
| 84 | +proc PyDict_FromKeys*(cls: PyObject, iterable, value: PyObject): PyObject = |
| 85 | + ## `_PyDict_FromKeys` |
| 86 | + ## Internal version of dict.from_keys(). It is subclass-friendly |
| 87 | + let d = call(cls) |
| 88 | + retIfExc d |
| 89 | + if d.ofExactPyDictObject: |
| 90 | + let mp = PyDictObject d |
| 91 | + template retFor(T) = |
| 92 | + let it = T iterable |
| 93 | + criticalWrite mp: criticalRead it: |
| 94 | + result = mp.fromkeys(it, value) |
| 95 | + return |
| 96 | + if iterable.ofExactPyDictObject: |
| 97 | + retFor PyDictObject |
| 98 | + elif iterable.ofExactPySetObject: |
| 99 | + retFor PySetObject |
| 100 | + elif iterable.ofExactPyFrozenSetObject: |
| 101 | + let it = PyFrozenSetObject iterable |
| 102 | + criticalWrite mp: # `criticalRead it:` # frozenset has no lock |
| 103 | + result = mp.fromkeys(it, value) |
| 104 | + return |
| 105 | + let it = PyObject_GetIter(iterable) |
| 106 | + retIfExc it |
| 107 | + if d.ofExactPyDictObject: |
| 108 | + let mp = PyDictObject d |
| 109 | + criticalWrite mp: |
| 110 | + pyForIn key, it: |
| 111 | + retIfExc mp.setItem(key, value) |
| 112 | + else: |
| 113 | + pyForIn key, it: |
| 114 | + retIfExc PyObject_SetItem(d, key, value) |
| 115 | + d |
| 116 | + |
| 117 | +implDictMethod fromkeys(*a), [classmethod]: |
| 118 | + var |
| 119 | + iterable: PyObject |
| 120 | + value = pyNone |
| 121 | + PyArg_UnpackTuple("fromkeys", a, 1, 2, iterable, value) |
| 122 | + PyDict_FromKeys(selfNoCast, iterable, value) |
0 commit comments