dict_ops.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. """Primitive dict ops."""
  2. from __future__ import annotations
  3. from mypyc.ir.ops import ERR_FALSE, ERR_MAGIC, ERR_NEVER
  4. from mypyc.ir.rtypes import (
  5. bit_rprimitive,
  6. bool_rprimitive,
  7. c_int_rprimitive,
  8. c_pyssize_t_rprimitive,
  9. dict_next_rtuple_pair,
  10. dict_next_rtuple_single,
  11. dict_rprimitive,
  12. int_rprimitive,
  13. list_rprimitive,
  14. object_rprimitive,
  15. )
  16. from mypyc.primitives.registry import (
  17. ERR_NEG_INT,
  18. binary_op,
  19. custom_op,
  20. function_op,
  21. load_address_op,
  22. method_op,
  23. )
  24. # Get the 'dict' type object.
  25. load_address_op(name="builtins.dict", type=object_rprimitive, src="PyDict_Type")
  26. # Construct an empty dictionary via dict().
  27. function_op(
  28. name="builtins.dict",
  29. arg_types=[],
  30. return_type=dict_rprimitive,
  31. c_function_name="PyDict_New",
  32. error_kind=ERR_MAGIC,
  33. )
  34. # Construct an empty dictionary.
  35. dict_new_op = custom_op(
  36. arg_types=[], return_type=dict_rprimitive, c_function_name="PyDict_New", error_kind=ERR_MAGIC
  37. )
  38. # Construct a dictionary from keys and values.
  39. # Positional argument is the number of key-value pairs
  40. # Variable arguments are (key1, value1, ..., keyN, valueN).
  41. dict_build_op = custom_op(
  42. arg_types=[c_pyssize_t_rprimitive],
  43. return_type=dict_rprimitive,
  44. c_function_name="CPyDict_Build",
  45. error_kind=ERR_MAGIC,
  46. var_arg_type=object_rprimitive,
  47. )
  48. # Construct a dictionary from another dictionary.
  49. function_op(
  50. name="builtins.dict",
  51. arg_types=[dict_rprimitive],
  52. return_type=dict_rprimitive,
  53. c_function_name="PyDict_Copy",
  54. error_kind=ERR_MAGIC,
  55. priority=2,
  56. )
  57. # Generic one-argument dict constructor: dict(obj)
  58. dict_copy = function_op(
  59. name="builtins.dict",
  60. arg_types=[object_rprimitive],
  61. return_type=dict_rprimitive,
  62. c_function_name="CPyDict_FromAny",
  63. error_kind=ERR_MAGIC,
  64. )
  65. # dict[key]
  66. dict_get_item_op = method_op(
  67. name="__getitem__",
  68. arg_types=[dict_rprimitive, object_rprimitive],
  69. return_type=object_rprimitive,
  70. c_function_name="CPyDict_GetItem",
  71. error_kind=ERR_MAGIC,
  72. )
  73. # dict[key] = value
  74. dict_set_item_op = method_op(
  75. name="__setitem__",
  76. arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
  77. return_type=c_int_rprimitive,
  78. c_function_name="CPyDict_SetItem",
  79. error_kind=ERR_NEG_INT,
  80. )
  81. # key in dict
  82. binary_op(
  83. name="in",
  84. arg_types=[object_rprimitive, dict_rprimitive],
  85. return_type=c_int_rprimitive,
  86. c_function_name="PyDict_Contains",
  87. error_kind=ERR_NEG_INT,
  88. truncated_type=bool_rprimitive,
  89. ordering=[1, 0],
  90. )
  91. # dict1.update(dict2)
  92. dict_update_op = method_op(
  93. name="update",
  94. arg_types=[dict_rprimitive, dict_rprimitive],
  95. return_type=c_int_rprimitive,
  96. c_function_name="CPyDict_Update",
  97. error_kind=ERR_NEG_INT,
  98. priority=2,
  99. )
  100. # Operation used for **value in dict displays.
  101. # This is mostly like dict.update(obj), but has customized error handling.
  102. dict_update_in_display_op = custom_op(
  103. arg_types=[dict_rprimitive, object_rprimitive],
  104. return_type=c_int_rprimitive,
  105. c_function_name="CPyDict_UpdateInDisplay",
  106. error_kind=ERR_NEG_INT,
  107. )
  108. # dict.update(obj)
  109. method_op(
  110. name="update",
  111. arg_types=[dict_rprimitive, object_rprimitive],
  112. return_type=c_int_rprimitive,
  113. c_function_name="CPyDict_UpdateFromAny",
  114. error_kind=ERR_NEG_INT,
  115. )
  116. # dict.get(key, default)
  117. method_op(
  118. name="get",
  119. arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
  120. return_type=object_rprimitive,
  121. c_function_name="CPyDict_Get",
  122. error_kind=ERR_MAGIC,
  123. )
  124. # dict.get(key)
  125. dict_get_method_with_none = method_op(
  126. name="get",
  127. arg_types=[dict_rprimitive, object_rprimitive],
  128. return_type=object_rprimitive,
  129. c_function_name="CPyDict_GetWithNone",
  130. error_kind=ERR_MAGIC,
  131. )
  132. # dict.setdefault(key, default)
  133. dict_setdefault_op = method_op(
  134. name="setdefault",
  135. arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
  136. return_type=object_rprimitive,
  137. c_function_name="CPyDict_SetDefault",
  138. error_kind=ERR_MAGIC,
  139. )
  140. # dict.setdefault(key)
  141. method_op(
  142. name="setdefault",
  143. arg_types=[dict_rprimitive, object_rprimitive],
  144. return_type=object_rprimitive,
  145. c_function_name="CPyDict_SetDefaultWithNone",
  146. error_kind=ERR_MAGIC,
  147. )
  148. # dict.setdefault(key, empty tuple/list/set)
  149. # The third argument marks the data type of the second argument.
  150. # 1: list 2: dict 3: set
  151. # Other number would lead to an error.
  152. dict_setdefault_spec_init_op = custom_op(
  153. arg_types=[dict_rprimitive, object_rprimitive, c_int_rprimitive],
  154. return_type=object_rprimitive,
  155. c_function_name="CPyDict_SetDefaultWithEmptyDatatype",
  156. error_kind=ERR_MAGIC,
  157. )
  158. # dict.keys()
  159. method_op(
  160. name="keys",
  161. arg_types=[dict_rprimitive],
  162. return_type=object_rprimitive,
  163. c_function_name="CPyDict_KeysView",
  164. error_kind=ERR_MAGIC,
  165. )
  166. # dict.values()
  167. method_op(
  168. name="values",
  169. arg_types=[dict_rprimitive],
  170. return_type=object_rprimitive,
  171. c_function_name="CPyDict_ValuesView",
  172. error_kind=ERR_MAGIC,
  173. )
  174. # dict.items()
  175. method_op(
  176. name="items",
  177. arg_types=[dict_rprimitive],
  178. return_type=object_rprimitive,
  179. c_function_name="CPyDict_ItemsView",
  180. error_kind=ERR_MAGIC,
  181. )
  182. # dict.clear()
  183. method_op(
  184. name="clear",
  185. arg_types=[dict_rprimitive],
  186. return_type=bit_rprimitive,
  187. c_function_name="CPyDict_Clear",
  188. error_kind=ERR_FALSE,
  189. )
  190. # dict.copy()
  191. method_op(
  192. name="copy",
  193. arg_types=[dict_rprimitive],
  194. return_type=dict_rprimitive,
  195. c_function_name="CPyDict_Copy",
  196. error_kind=ERR_MAGIC,
  197. )
  198. # list(dict.keys())
  199. dict_keys_op = custom_op(
  200. arg_types=[dict_rprimitive],
  201. return_type=list_rprimitive,
  202. c_function_name="CPyDict_Keys",
  203. error_kind=ERR_MAGIC,
  204. )
  205. # list(dict.values())
  206. dict_values_op = custom_op(
  207. arg_types=[dict_rprimitive],
  208. return_type=list_rprimitive,
  209. c_function_name="CPyDict_Values",
  210. error_kind=ERR_MAGIC,
  211. )
  212. # list(dict.items())
  213. dict_items_op = custom_op(
  214. arg_types=[dict_rprimitive],
  215. return_type=list_rprimitive,
  216. c_function_name="CPyDict_Items",
  217. error_kind=ERR_MAGIC,
  218. )
  219. # PyDict_Next() fast iteration
  220. dict_key_iter_op = custom_op(
  221. arg_types=[dict_rprimitive],
  222. return_type=object_rprimitive,
  223. c_function_name="CPyDict_GetKeysIter",
  224. error_kind=ERR_MAGIC,
  225. )
  226. dict_value_iter_op = custom_op(
  227. arg_types=[dict_rprimitive],
  228. return_type=object_rprimitive,
  229. c_function_name="CPyDict_GetValuesIter",
  230. error_kind=ERR_MAGIC,
  231. )
  232. dict_item_iter_op = custom_op(
  233. arg_types=[dict_rprimitive],
  234. return_type=object_rprimitive,
  235. c_function_name="CPyDict_GetItemsIter",
  236. error_kind=ERR_MAGIC,
  237. )
  238. dict_next_key_op = custom_op(
  239. arg_types=[object_rprimitive, int_rprimitive],
  240. return_type=dict_next_rtuple_single,
  241. c_function_name="CPyDict_NextKey",
  242. error_kind=ERR_NEVER,
  243. )
  244. dict_next_value_op = custom_op(
  245. arg_types=[object_rprimitive, int_rprimitive],
  246. return_type=dict_next_rtuple_single,
  247. c_function_name="CPyDict_NextValue",
  248. error_kind=ERR_NEVER,
  249. )
  250. dict_next_item_op = custom_op(
  251. arg_types=[object_rprimitive, int_rprimitive],
  252. return_type=dict_next_rtuple_pair,
  253. c_function_name="CPyDict_NextItem",
  254. error_kind=ERR_NEVER,
  255. )
  256. # check that len(dict) == const during iteration
  257. dict_check_size_op = custom_op(
  258. arg_types=[dict_rprimitive, int_rprimitive],
  259. return_type=bit_rprimitive,
  260. c_function_name="CPyDict_CheckSize",
  261. error_kind=ERR_FALSE,
  262. )
  263. dict_ssize_t_size_op = custom_op(
  264. arg_types=[dict_rprimitive],
  265. return_type=c_pyssize_t_rprimitive,
  266. c_function_name="PyDict_Size",
  267. error_kind=ERR_NEVER,
  268. )
  269. # Delete an item from a dict
  270. dict_del_item = custom_op(
  271. arg_types=[object_rprimitive, object_rprimitive],
  272. return_type=c_int_rprimitive,
  273. c_function_name="PyDict_DelItem",
  274. error_kind=ERR_NEG_INT,
  275. )
  276. supports_mapping_protocol = custom_op(
  277. arg_types=[object_rprimitive],
  278. return_type=c_int_rprimitive,
  279. c_function_name="CPyMapping_Check",
  280. error_kind=ERR_NEVER,
  281. )
  282. mapping_has_key = custom_op(
  283. arg_types=[object_rprimitive, object_rprimitive],
  284. return_type=c_int_rprimitive,
  285. c_function_name="PyMapping_HasKey",
  286. error_kind=ERR_NEVER,
  287. )