Skip to content

Commit f326cda

Browse files
committed
feat(method): dict.fromkeys
1 parent 01456d1 commit f326cda

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

Objects/dictobjectImpl.nim

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11

22

3-
import ./pyobject
3+
44
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,]
813
import ./dictobject
914
export dictobject
1015
from ../Utils/utils import DictError, `!!`
16+
import ../Python/getargs/vargs
17+
import ../Include/cpython/critical_section
1118

1219
# redeclare this for these are "private" macros
1320

@@ -66,3 +73,50 @@ implDictMagic init:
6673
pyNone
6774
else:
6875
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

Comments
 (0)