numba-cuda 0.23.0__cp313-cp313-win_amd64.whl → 0.24.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. numba_cuda/VERSION +1 -1
  2. numba_cuda/numba/cuda/__init__.py +4 -1
  3. numba_cuda/numba/cuda/_compat.py +47 -0
  4. numba_cuda/numba/cuda/cext/_dispatcher.cp313-win_amd64.pyd +0 -0
  5. numba_cuda/numba/cuda/cext/_dispatcher.cpp +8 -2
  6. numba_cuda/numba/cuda/cext/_hashtable.cpp +5 -0
  7. numba_cuda/numba/cuda/cext/_helperlib.cp313-win_amd64.pyd +0 -0
  8. numba_cuda/numba/cuda/cext/_pymodule.h +1 -1
  9. numba_cuda/numba/cuda/cext/_typeconv.cp313-win_amd64.pyd +0 -0
  10. numba_cuda/numba/cuda/cext/_typeof.cpp +56 -8
  11. numba_cuda/numba/cuda/cext/mviewbuf.c +7 -1
  12. numba_cuda/numba/cuda/cext/mviewbuf.cp313-win_amd64.pyd +0 -0
  13. numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +4 -5
  14. numba_cuda/numba/cuda/codegen.py +4 -2
  15. numba_cuda/numba/cuda/compiler.py +5 -5
  16. numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +1 -1
  17. numba_cuda/numba/cuda/core/base.py +6 -10
  18. numba_cuda/numba/cuda/core/bytecode.py +21 -13
  19. numba_cuda/numba/cuda/core/byteflow.py +336 -90
  20. numba_cuda/numba/cuda/core/compiler.py +3 -4
  21. numba_cuda/numba/cuda/core/compiler_machinery.py +3 -3
  22. numba_cuda/numba/cuda/core/config.py +5 -7
  23. numba_cuda/numba/cuda/core/controlflow.py +17 -9
  24. numba_cuda/numba/cuda/core/inline_closurecall.py +11 -10
  25. numba_cuda/numba/cuda/core/interpreter.py +255 -96
  26. numba_cuda/numba/cuda/core/ir_utils.py +8 -17
  27. numba_cuda/numba/cuda/core/pythonapi.py +3 -0
  28. numba_cuda/numba/cuda/core/rewrites/static_binop.py +1 -1
  29. numba_cuda/numba/cuda/core/ssa.py +2 -2
  30. numba_cuda/numba/cuda/core/transforms.py +4 -6
  31. numba_cuda/numba/cuda/core/typed_passes.py +1 -1
  32. numba_cuda/numba/cuda/core/typeinfer.py +3 -3
  33. numba_cuda/numba/cuda/core/untyped_passes.py +11 -10
  34. numba_cuda/numba/cuda/cpython/unicode.py +2 -2
  35. numba_cuda/numba/cuda/cpython/unicode_support.py +1 -3
  36. numba_cuda/numba/cuda/cudadrv/devicearray.py +4 -4
  37. numba_cuda/numba/cuda/cudadrv/driver.py +13 -11
  38. numba_cuda/numba/cuda/cudadrv/nvrtc.py +71 -32
  39. numba_cuda/numba/cuda/debuginfo.py +10 -79
  40. numba_cuda/numba/cuda/deviceufunc.py +3 -6
  41. numba_cuda/numba/cuda/dispatcher.py +5 -19
  42. numba_cuda/numba/cuda/libdeviceimpl.py +1 -2
  43. numba_cuda/numba/cuda/lowering.py +0 -28
  44. numba_cuda/numba/cuda/memory_management/nrt.py +1 -1
  45. numba_cuda/numba/cuda/np/arrayobj.py +7 -9
  46. numba_cuda/numba/cuda/np/numpy_support.py +7 -10
  47. numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +4 -3
  48. numba_cuda/numba/cuda/testing.py +4 -8
  49. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +66 -4
  50. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +1 -1
  51. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +2 -2
  52. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +1 -1
  53. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +26 -4
  54. numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +61 -9
  55. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +6 -0
  56. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +12 -1
  57. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +13 -0
  58. numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +1 -1
  59. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +1 -1
  60. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +12 -7
  61. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +1 -1
  62. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1 -1
  63. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +37 -35
  64. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +8 -7
  65. numba_cuda/numba/cuda/tests/support.py +11 -0
  66. numba_cuda/numba/cuda/types/cuda_functions.py +1 -1
  67. numba_cuda/numba/cuda/typing/asnumbatype.py +37 -2
  68. numba_cuda/numba/cuda/typing/typeof.py +9 -16
  69. {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/METADATA +4 -13
  70. {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/RECORD +74 -73
  71. {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/WHEEL +0 -0
  72. {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/licenses/LICENSE +0 -0
  73. {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/licenses/LICENSE.numba +0 -0
  74. {numba_cuda-0.23.0.dist-info → numba_cuda-0.24.0.dist-info}/top_level.txt +0 -0
@@ -34,7 +34,7 @@ _NO_RAISE_OPS = frozenset(
34
34
  }
35
35
  )
36
36
 
37
- if PYVERSION in ((3, 12), (3, 13)):
37
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
38
38
  from enum import Enum
39
39
 
40
40
  # Operands for CALL_INTRINSIC_1
@@ -161,7 +161,7 @@ class Flow(object):
161
161
  self.block_infos[state.pc_initial] = si = adapt_state_infos(state)
162
162
  _logger.debug("block_infos %s:\n%s", state, si)
163
163
 
164
- if PYVERSION in ((3, 11), (3, 12), (3, 13)):
164
+ if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
165
165
 
166
166
  def _run_handle_exception(self, runner, state):
167
167
  if not state.in_with() and (
@@ -324,20 +324,29 @@ class Flow(object):
324
324
  else:
325
325
  return False
326
326
 
327
- def _guard_with_as(self, state):
328
- """Checks if the next instruction after a SETUP_WITH is something other
329
- than a POP_TOP, if it is something else it'll be some sort of store
330
- which is not supported (this corresponds to `with CTXMGR as VAR(S)`)."""
331
- current_inst = state.get_inst()
332
- if current_inst.opname in {"SETUP_WITH", "BEFORE_WITH"}:
333
- next_op = self._bytecode[current_inst.next].opname
334
- if next_op != "POP_TOP":
335
- msg = (
336
- "The 'with (context manager) as "
337
- "(variable):' construct is not "
338
- "supported."
339
- )
340
- raise UnsupportedBytecodeError(msg)
327
+ if PYVERSION in ((3, 14),):
328
+
329
+ def _guard_with_as(self, state):
330
+ # Handled as part of `LOAD_SPECIAL` as of 3.14.
331
+ pass
332
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
333
+
334
+ def _guard_with_as(self, state):
335
+ """Checks if the next instruction after a SETUP_WITH is something
336
+ other than a POP_TOP, if it is something else it'll be some sort of
337
+ store which is not supported (this corresponds to `with CTXMGR as
338
+ VAR(S)`)."""
339
+ current_inst = state.get_inst()
340
+ if current_inst.opname in {"SETUP_WITH", "BEFORE_WITH"}:
341
+ next_op = self._bytecode[current_inst.next].opname
342
+ if next_op != "POP_TOP":
343
+ msg = (
344
+ "The 'with (context manager) as (variable):' "
345
+ "construct is not supported."
346
+ )
347
+ raise UnsupportedBytecodeError(msg)
348
+ else:
349
+ raise NotImplementedError(PYVERSION)
341
350
 
342
351
 
343
352
  def _is_null_temp_reg(reg):
@@ -356,7 +365,7 @@ class TraceRunner(object):
356
365
  return Loc(self.debug_filename, lineno)
357
366
 
358
367
  def dispatch(self, state):
359
- if PYVERSION in ((3, 11), (3, 12), (3, 13)):
368
+ if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
360
369
  if state._blockstack:
361
370
  state: State
362
371
  while state._blockstack:
@@ -409,6 +418,14 @@ class TraceRunner(object):
409
418
  def op_NOP(self, state, inst):
410
419
  state.append(inst)
411
420
 
421
+ if PYVERSION in ((3, 14),):
422
+ # New in 3.14
423
+ op_NOT_TAKEN = op_NOP
424
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
425
+ pass
426
+ else:
427
+ raise NotImplementedError(PYVERSION)
428
+
412
429
  def op_RESUME(self, state, inst):
413
430
  state.append(inst)
414
431
 
@@ -435,15 +452,18 @@ class TraceRunner(object):
435
452
  state.push(state.make_temp())
436
453
  state.append(inst)
437
454
 
438
- if PYVERSION in ((3, 13),):
455
+ if PYVERSION in ((3, 13), (3, 14)):
439
456
 
440
457
  def op_FORMAT_SIMPLE(self, state, inst):
441
- assert PYVERSION == (3, 13)
442
458
  value = state.pop()
443
459
  strvar = state.make_temp()
444
460
  res = state.make_temp()
445
461
  state.append(inst, value=value, res=res, strvar=strvar)
446
462
  state.push(res)
463
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)):
464
+ pass
465
+ else:
466
+ raise NotImplementedError(PYVERSION)
447
467
 
448
468
  def op_FORMAT_VALUE(self, state, inst):
449
469
  """
@@ -484,18 +504,27 @@ class TraceRunner(object):
484
504
  def op_POP_TOP(self, state, inst):
485
505
  state.pop()
486
506
 
487
- if PYVERSION in ((3, 13),):
507
+ if PYVERSION in ((3, 14),):
508
+ # New in 3.14
509
+ op_POP_ITER = op_POP_TOP
510
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
511
+ pass
512
+ else:
513
+ raise NotImplementedError(PYVERSION)
514
+
515
+ if PYVERSION in ((3, 13), (3, 14)):
488
516
 
489
517
  def op_TO_BOOL(self, state, inst):
490
518
  res = state.make_temp()
491
519
  tos = state.pop()
492
520
  state.append(inst, val=tos, res=res)
493
521
  state.push(res)
494
-
495
- elif PYVERSION < (3, 13):
522
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)):
496
523
  pass
524
+ else:
525
+ raise NotImplementedError(PYVERSION)
497
526
 
498
- if PYVERSION in ((3, 13),):
527
+ if PYVERSION in ((3, 13), (3, 14)):
499
528
 
500
529
  def op_LOAD_GLOBAL(self, state, inst):
501
530
  # Ordering of the global value and NULL is swapped in Py3.13
@@ -545,10 +574,22 @@ class TraceRunner(object):
545
574
  state.push(res)
546
575
  state.append(inst, res=res)
547
576
 
577
+ if PYVERSION in ((3, 14),):
578
+ # New in 3.14
579
+ def op_LOAD_SMALL_INT(self, state, inst):
580
+ assert 0 <= inst.arg < 256
581
+ res = state.make_temp("const") + f".{inst.arg}"
582
+ state.push(res)
583
+ state.append(inst, res=res)
584
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
585
+ pass
586
+ else:
587
+ raise NotImplementedError(PYVERSION)
588
+
548
589
  def op_LOAD_ATTR(self, state, inst):
549
590
  item = state.pop()
550
591
  res = state.make_temp()
551
- if PYVERSION in ((3, 13),):
592
+ if PYVERSION in ((3, 13), (3, 14)):
552
593
  state.push(res) # the attr
553
594
  if inst.arg & 1:
554
595
  state.push(state.make_null())
@@ -563,8 +604,7 @@ class TraceRunner(object):
563
604
  state.append(inst, item=item, res=res)
564
605
 
565
606
  def op_LOAD_FAST(self, state, inst):
566
- assert PYVERSION <= (3, 13)
567
- if PYVERSION in ((3, 13),):
607
+ if PYVERSION in ((3, 13), (3, 14)):
568
608
  try:
569
609
  name = state.get_varname(inst)
570
610
  except IndexError: # oparg is out of range
@@ -583,13 +623,15 @@ class TraceRunner(object):
583
623
  state.append(inst, res=res, as_load_deref=True)
584
624
  state.push(res)
585
625
  return
586
- else:
626
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)):
587
627
  name = state.get_varname(inst)
628
+ else:
629
+ raise NotImplementedError(PYVERSION)
588
630
  res = state.make_temp(name)
589
631
  state.append(inst, res=res)
590
632
  state.push(res)
591
633
 
592
- if PYVERSION in ((3, 13),):
634
+ if PYVERSION in ((3, 13), (3, 14)):
593
635
 
594
636
  def op_LOAD_FAST_LOAD_FAST(self, state, inst):
595
637
  oparg = inst.arg
@@ -623,7 +665,7 @@ class TraceRunner(object):
623
665
  else:
624
666
  raise NotImplementedError(PYVERSION)
625
667
 
626
- if PYVERSION in ((3, 12), (3, 13)):
668
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
627
669
  op_LOAD_FAST_CHECK = op_LOAD_FAST
628
670
  op_LOAD_FAST_AND_CLEAR = op_LOAD_FAST
629
671
  elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
@@ -631,6 +673,15 @@ class TraceRunner(object):
631
673
  else:
632
674
  raise NotImplementedError(PYVERSION)
633
675
 
676
+ if PYVERSION in ((3, 14),):
677
+ # New in 3.14.
678
+ op_LOAD_FAST_BORROW = op_LOAD_FAST
679
+ op_LOAD_FAST_BORROW_LOAD_FAST_BORROW = op_LOAD_FAST_LOAD_FAST
680
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
681
+ pass
682
+ else:
683
+ raise NotImplementedError(PYVERSION)
684
+
634
685
  def op_DELETE_FAST(self, state, inst):
635
686
  state.append(inst)
636
687
 
@@ -889,7 +940,7 @@ class TraceRunner(object):
889
940
  )
890
941
  state.push(res)
891
942
 
892
- if PYVERSION in ((3, 12), (3, 13)):
943
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
893
944
 
894
945
  def op_BINARY_SLICE(self, state, inst):
895
946
  end = state.pop()
@@ -913,7 +964,7 @@ class TraceRunner(object):
913
964
  else:
914
965
  raise NotImplementedError(PYVERSION)
915
966
 
916
- if PYVERSION in ((3, 12), (3, 13)):
967
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
917
968
 
918
969
  def op_STORE_SLICE(self, state, inst):
919
970
  end = state.pop()
@@ -952,7 +1003,7 @@ class TraceRunner(object):
952
1003
  op_POP_JUMP_IF_TRUE = _op_POP_JUMP_IF
953
1004
  op_POP_JUMP_IF_FALSE = _op_POP_JUMP_IF
954
1005
 
955
- if PYVERSION in ((3, 12), (3, 13)):
1006
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
956
1007
  op_POP_JUMP_IF_NONE = _op_POP_JUMP_IF
957
1008
  op_POP_JUMP_IF_NOT_NONE = _op_POP_JUMP_IF
958
1009
  elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
@@ -1018,7 +1069,7 @@ class TraceRunner(object):
1018
1069
  state.append(inst, retval=state.pop(), castval=state.make_temp())
1019
1070
  state.terminate()
1020
1071
 
1021
- if PYVERSION in ((3, 12), (3, 13)):
1072
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
1022
1073
 
1023
1074
  def op_RETURN_CONST(self, state, inst):
1024
1075
  res = state.make_temp("const")
@@ -1035,7 +1086,7 @@ class TraceRunner(object):
1035
1086
  state.append(inst, value=val, res=res)
1036
1087
  state.push(res)
1037
1088
 
1038
- if PYVERSION in ((3, 11), (3, 12), (3, 13)):
1089
+ if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
1039
1090
 
1040
1091
  def op_RAISE_VARARGS(self, state, inst):
1041
1092
  if inst.arg == 0:
@@ -1098,7 +1149,7 @@ class TraceRunner(object):
1098
1149
  blk = state.pop_block()
1099
1150
  state.reset_stack(blk["entry_stack"])
1100
1151
 
1101
- if PYVERSION in ((3, 13),):
1152
+ if PYVERSION in ((3, 13), (3, 14)):
1102
1153
 
1103
1154
  def op_END_FOR(self, state, inst):
1104
1155
  state.pop()
@@ -1146,35 +1197,43 @@ class TraceRunner(object):
1146
1197
  )
1147
1198
  )
1148
1199
 
1149
- def op_BEFORE_WITH(self, state, inst):
1150
- # Almost the same as py3.10 SETUP_WITH just lacking the finally block.
1151
- cm = state.pop() # the context-manager
1152
-
1153
- yielded = state.make_temp()
1154
- exitfn = state.make_temp(prefix="setup_with_exitfn")
1155
-
1156
- state.push(exitfn)
1157
- state.push(yielded)
1158
-
1159
- # Gather all exception entries for this WITH. There maybe multiple
1160
- # entries; esp. for nested WITHs.
1161
- bc = state._bytecode
1162
- ehhead = bc.find_exception_entry(inst.next)
1163
- ehrelated = [ehhead]
1164
- for eh in bc.exception_entries:
1165
- if eh.target == ehhead.target:
1166
- ehrelated.append(eh)
1167
- end = max(eh.end for eh in ehrelated)
1168
- state.append(inst, contextmanager=cm, exitfn=exitfn, end=end)
1200
+ if PYVERSION in ((3, 14),):
1201
+ # Replaced by LOAD_SPECIAL in 3.14.
1202
+ pass
1203
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
1204
+
1205
+ def op_BEFORE_WITH(self, state, inst):
1206
+ # Almost the same as py3.10 SETUP_WITH just lacking the finally
1207
+ # block.
1208
+ cm = state.pop() # the context-manager
1209
+
1210
+ yielded = state.make_temp()
1211
+ exitfn = state.make_temp(prefix="setup_with_exitfn")
1212
+
1213
+ state.push(exitfn)
1214
+ state.push(yielded)
1215
+
1216
+ # Gather all exception entries for this WITH. There maybe multiple
1217
+ # entries; esp. for nested WITHs.
1218
+ bc = state._bytecode
1219
+ ehhead = bc.find_exception_entry(inst.next)
1220
+ ehrelated = [ehhead]
1221
+ ehrelated.extend(
1222
+ eh for eh in bc.exception_entries if eh.target == ehhead.target
1223
+ )
1224
+ end = max(eh.end for eh in ehrelated)
1225
+ state.append(inst, contextmanager=cm, exitfn=exitfn, end=end)
1169
1226
 
1170
- state.push_block(
1171
- state.make_block(
1172
- kind="WITH",
1173
- end=end,
1227
+ state.push_block(
1228
+ state.make_block(
1229
+ kind="WITH",
1230
+ end=end,
1231
+ )
1174
1232
  )
1175
- )
1176
- # Forces a new block
1177
- state.fork(pc=inst.next)
1233
+ # Forces a new block
1234
+ state.fork(pc=inst.next)
1235
+ else:
1236
+ raise NotImplementedError(PYVERSION)
1178
1237
 
1179
1238
  def op_SETUP_WITH(self, state, inst):
1180
1239
  cm = state.pop() # the context-manager
@@ -1229,7 +1288,7 @@ class TraceRunner(object):
1229
1288
  end=inst.get_jump_target(),
1230
1289
  )
1231
1290
 
1232
- if PYVERSION in ((3, 11), (3, 12), (3, 13)):
1291
+ if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
1233
1292
 
1234
1293
  def op_POP_EXCEPT(self, state, inst):
1235
1294
  state.pop()
@@ -1262,12 +1321,19 @@ class TraceRunner(object):
1262
1321
  state.append(inst, kind="with")
1263
1322
  state.fork(pc=inst.next)
1264
1323
 
1265
- def op_BINARY_SUBSCR(self, state, inst):
1266
- index = state.pop()
1267
- target = state.pop()
1268
- res = state.make_temp()
1269
- state.append(inst, index=index, target=target, res=res)
1270
- state.push(res)
1324
+ if PYVERSION in ((3, 14),):
1325
+ # Removed in 3.14 -- replaced with BINARY_OP and []
1326
+ pass
1327
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
1328
+
1329
+ def op_BINARY_SUBSCR(self, state, inst):
1330
+ index = state.pop()
1331
+ target = state.pop()
1332
+ res = state.make_temp()
1333
+ state.append(inst, index=index, target=target, res=res)
1334
+ state.push(res)
1335
+ else:
1336
+ raise NotImplementedError(PYVERSION)
1271
1337
 
1272
1338
  def op_STORE_SUBSCR(self, state, inst):
1273
1339
  index = state.pop()
@@ -1283,7 +1349,7 @@ class TraceRunner(object):
1283
1349
  def op_CALL(self, state, inst):
1284
1350
  narg = inst.arg
1285
1351
  args = list(reversed([state.pop() for _ in range(narg)]))
1286
- if PYVERSION == (3, 13):
1352
+ if PYVERSION in ((3, 13), (3, 14)):
1287
1353
  null_or_self = state.pop()
1288
1354
  # position of the callable is fixed
1289
1355
  callable = state.pop()
@@ -1326,7 +1392,7 @@ class TraceRunner(object):
1326
1392
  state.append(inst, func=func, args=args, names=names, res=res)
1327
1393
  state.push(res)
1328
1394
 
1329
- if PYVERSION in ((3, 13),):
1395
+ if PYVERSION in ((3, 13), (3, 14)):
1330
1396
 
1331
1397
  def op_CALL_KW(self, state, inst):
1332
1398
  narg = inst.arg
@@ -1348,7 +1414,25 @@ class TraceRunner(object):
1348
1414
  else:
1349
1415
  raise NotImplementedError(PYVERSION)
1350
1416
 
1351
- if PYVERSION in ((3, 13),):
1417
+ if PYVERSION in ((3, 14),):
1418
+
1419
+ def op_CALL_FUNCTION_EX(self, state, inst):
1420
+ # (func, unused, callargs, kwargs -- result))
1421
+ # In 3.14 CALL_FUNCTION_EX always take a kwargs argument
1422
+ # https://github.com/python/cpython/pull/129226
1423
+ varkwarg = state.pop()
1424
+ if _is_null_temp_reg(varkwarg):
1425
+ varkwarg = None
1426
+ vararg = state.pop()
1427
+ state.pop() # unused
1428
+ func = state.pop()
1429
+
1430
+ res = state.make_temp()
1431
+ state.append(
1432
+ inst, func=func, vararg=vararg, varkwarg=varkwarg, res=res
1433
+ )
1434
+ state.push(res)
1435
+ elif PYVERSION in ((3, 13),):
1352
1436
 
1353
1437
  def op_CALL_FUNCTION_EX(self, state, inst):
1354
1438
  # (func, unused, callargs, kwargs if (oparg & 1) -- result))
@@ -1408,7 +1492,7 @@ class TraceRunner(object):
1408
1492
  for val in duped:
1409
1493
  state.push(val)
1410
1494
 
1411
- if PYVERSION in ((3, 12), (3, 13)):
1495
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
1412
1496
 
1413
1497
  def op_CALL_INTRINSIC_1(self, state, inst):
1414
1498
  # See https://github.com/python/cpython/blob/v3.12.0rc2/Include/
@@ -1603,6 +1687,13 @@ class TraceRunner(object):
1603
1687
  state.append(inst, items=items, res=res)
1604
1688
  state.push(res)
1605
1689
 
1690
+ def op_SET_ADD(self, state, inst):
1691
+ value = state.pop()
1692
+ target = state.get_tos()
1693
+ addvar = state.make_temp()
1694
+ res = state.make_temp()
1695
+ state.append(inst, value=value, target=target, addvar=addvar, res=res)
1696
+
1606
1697
  def op_SET_UPDATE(self, state, inst):
1607
1698
  value = state.pop()
1608
1699
  index = inst.arg
@@ -1639,7 +1730,7 @@ class TraceRunner(object):
1639
1730
  )
1640
1731
  state.push(indval)
1641
1732
  end = inst.get_jump_target()
1642
- if PYVERSION in ((3, 12), (3, 13)):
1733
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
1643
1734
  # Changed in version 3.12: Up until 3.11 the iterator was
1644
1735
  # popped when it was exhausted. Now this is handled using END_FOR
1645
1736
  # op code.
@@ -1665,10 +1756,17 @@ class TraceRunner(object):
1665
1756
  op = dis._nb_ops[inst.arg][1]
1666
1757
  rhs = state.pop()
1667
1758
  lhs = state.pop()
1668
- op_name = ALL_BINOPS_TO_OPERATORS[op].__name__
1669
- res = state.make_temp(prefix=f"binop_{op_name}")
1670
- state.append(inst, op=op, lhs=lhs, rhs=rhs, res=res)
1671
- state.push(res)
1759
+ if op == "[]":
1760
+ # Special case 3.14 -- body of BINARY_SUBSCR now here
1761
+ assert PYVERSION == (3, 14)
1762
+ res = state.make_temp()
1763
+ state.append(inst, op=op, lhs=lhs, rhs=rhs, res=res)
1764
+ state.push(res)
1765
+ else:
1766
+ op_name = ALL_BINOPS_TO_OPERATORS[op].__name__
1767
+ res = state.make_temp(prefix=f"binop_{op_name}")
1768
+ state.append(inst, op=op, lhs=lhs, rhs=rhs, res=res)
1769
+ state.push(res)
1672
1770
 
1673
1771
  def _unaryop(self, state, inst):
1674
1772
  val = state.pop()
@@ -1725,7 +1823,7 @@ class TraceRunner(object):
1725
1823
  op_BINARY_XOR = _binaryop
1726
1824
 
1727
1825
  def op_MAKE_FUNCTION(self, state, inst, MAKE_CLOSURE=False):
1728
- if PYVERSION in ((3, 11), (3, 12), (3, 13)):
1826
+ if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
1729
1827
  # https://github.com/python/cpython/commit/2f180ce
1730
1828
  # name set via co_qualname
1731
1829
  name = None
@@ -1738,7 +1836,7 @@ class TraceRunner(object):
1738
1836
  raise NotImplementedError(PYVERSION)
1739
1837
  code = state.pop()
1740
1838
  closure = annotations = kwdefaults = defaults = None
1741
- if PYVERSION in ((3, 13),):
1839
+ if PYVERSION in ((3, 13), (3, 14)):
1742
1840
  assert inst.arg is None
1743
1841
  # SET_FUNCTION_ATTRIBUTE is responsible for setting
1744
1842
  # closure, annotations, kwdefaults and defaults.
@@ -1765,7 +1863,7 @@ class TraceRunner(object):
1765
1863
  state.push(res)
1766
1864
 
1767
1865
  def op_SET_FUNCTION_ATTRIBUTE(self, state, inst):
1768
- assert PYVERSION in ((3, 13),)
1866
+ assert PYVERSION in ((3, 13), (3, 14))
1769
1867
  make_func_stack = state.pop()
1770
1868
  data = state.pop()
1771
1869
  if inst.arg == 0x1:
@@ -1793,10 +1891,17 @@ class TraceRunner(object):
1793
1891
  state.append(inst, res=res)
1794
1892
  state.push(res)
1795
1893
 
1796
- def op_LOAD_ASSERTION_ERROR(self, state, inst):
1797
- res = state.make_temp("assertion_error")
1798
- state.append(inst, res=res)
1799
- state.push(res)
1894
+ if PYVERSION in ((3, 14),):
1895
+ # Removed in 3.14
1896
+ pass
1897
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
1898
+
1899
+ def op_LOAD_ASSERTION_ERROR(self, state, inst):
1900
+ res = state.make_temp("assertion_error")
1901
+ state.append(inst, res=res)
1902
+ state.push(res)
1903
+ else:
1904
+ raise NotImplementedError(PYVERSION)
1800
1905
 
1801
1906
  def op_CHECK_EXC_MATCH(self, state, inst):
1802
1907
  pred = state.make_temp("predicate")
@@ -1815,7 +1920,7 @@ class TraceRunner(object):
1815
1920
  state.fork(pc=inst.next)
1816
1921
  state.fork(pc=inst.get_jump_target())
1817
1922
 
1818
- if PYVERSION in ((3, 11), (3, 12), (3, 13)):
1923
+ if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
1819
1924
 
1820
1925
  def op_RERAISE(self, state, inst):
1821
1926
  # This isn't handled, but the state is set up anyway
@@ -1845,7 +1950,7 @@ class TraceRunner(object):
1845
1950
  # NOTE: Please see notes in `interpreter.py` surrounding the implementation
1846
1951
  # of LOAD_METHOD and CALL_METHOD.
1847
1952
 
1848
- if PYVERSION in ((3, 12), (3, 13)):
1953
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
1849
1954
  # LOAD_METHOD has become a pseudo-instruction in 3.12
1850
1955
  pass
1851
1956
  elif PYVERSION in ((3, 11),):
@@ -1870,6 +1975,147 @@ class TraceRunner(object):
1870
1975
  def op_CALL_METHOD(self, state, inst):
1871
1976
  self.op_CALL_FUNCTION(state, inst)
1872
1977
 
1978
+ if PYVERSION in ((3, 14),):
1979
+ # New in 3.14, replaces BEFORE_WITH.
1980
+ def op_LOAD_SPECIAL(self, state, inst):
1981
+ # The "special" methods mapping for LOAD_SPECIAL is:
1982
+ #
1983
+ # special_methods = {
1984
+ # 0: '__enter__',
1985
+ # 1: '__exit__',
1986
+ # 2: '__aenter__',
1987
+ # 3: '__aexit__',
1988
+ # }
1989
+ if dis._special_method_names[inst.arg] not in [
1990
+ "__enter__",
1991
+ "__exit__",
1992
+ ]:
1993
+ raise NotImplementedError("async special methods not supported")
1994
+
1995
+ # This implementation of LOAD_SPECIAL is somewhat unusual for a
1996
+ # Numba bytecode handler.
1997
+ #
1998
+ # Essentially this comes from the insight, that with Python 3.14
1999
+ # the bytecode `BEFORE_WITH` is replaced by `LOAD_SPECIAL`. But
2000
+ # this is not a simple replacement. In fact, the single
2001
+ # `BEFORE_WITH` is replaced by the following sequence of bytecodes:
2002
+ #
2003
+ # COPY(arg=1, lineno=X)
2004
+ # LOAD_SPECIAL(arg=1, lineno=X) -- loading __exit__ --
2005
+ # SWAP(arg=2, lineno=X)
2006
+ # SWAP(arg=3, lineno=X)
2007
+ # LOAD_SPECIAL(arg=0, lineno=X) -- loading __enter__ --
2008
+ # CALL(arg=0, lineno=X) -- calling __enter__ --
2009
+ # POP_TOP(arg=None, lineno=X)
2010
+ #
2011
+ # Basically, after seeing the first `LOAD_SPECIAL` we can consume
2012
+ # all the bytecodes up until the `POP_TOP` and leave the stack
2013
+ # with a single copy of current TOS + the temp var to denote the
2014
+ # `__exit__` function. We can also reject syntax of the form:
2015
+ #
2016
+ # with context as c:
2017
+ # pass
2018
+ #
2019
+ # Using the fact that the `CALL` to `__enter__` must be followed by
2020
+ # as POP_TOP, otherwise it's using `with as`.
2021
+
2022
+ # Pop top of stack once for first LOAD_SPECIAL
2023
+ tos = state.pop()
2024
+ # Pop top of stack second time for second LOAD_SPECIAL
2025
+ _ = state.pop()
2026
+
2027
+ # Fake an exit method, will not be called and removed from Numba IR
2028
+ # before final processing is complete. Only need this such that the
2029
+ # `CALL` op when closing the with-block can be simulated as a stack
2030
+ # effect.
2031
+ method = state.make_temp(prefix="setup_with_exitfn")
2032
+ # Cache current instruction (the LOAD_SPECIAL).
2033
+ old_inst = inst
2034
+
2035
+ # Now we need to consume the instructions in the known sequence.
2036
+ for i, a in (
2037
+ ("SWAP", 2),
2038
+ ("SWAP", 3),
2039
+ ("LOAD_SPECIAL", 0),
2040
+ ("CALL", 0),
2041
+ ):
2042
+ state.advance_pc()
2043
+ inst = state.get_inst()
2044
+ if inst.opname != i or inst.arg != a:
2045
+ raise UnsupportedBytecodeError(
2046
+ "Unsupported bytecode pattern for 'LOAD_SPECIAL'."
2047
+ )
2048
+
2049
+ # POP_TOP
2050
+ state.advance_pc()
2051
+ inst = state.get_inst()
2052
+ # Special case, the `CALL` must be followed by a `POP_TOP`.
2053
+ # Otherwise this is an unsupported construct.
2054
+ #
2055
+ # See: `_guard_with_as` for how this is handled for 3.13 and below.
2056
+ if inst.opname != "POP_TOP":
2057
+ msg = (
2058
+ "The 'with (context manager) as "
2059
+ "(variable):' construct is not "
2060
+ "supported."
2061
+ )
2062
+ raise UnsupportedBytecodeError(msg)
2063
+ assert inst.arg is None
2064
+
2065
+ # Finished consuming bytecode pattern.
2066
+
2067
+ # Find the end of the with-block using the exception tables using
2068
+ # the instruction offset of the `POP_TOP` instruction.
2069
+ bc = state._bytecode
2070
+ ehhead = bc.find_exception_entry(inst.offset)
2071
+ ehrelated = [ehhead]
2072
+ ehrelated.extend(
2073
+ eh for eh in bc.exception_entries if eh.target == ehhead.target
2074
+ )
2075
+ end = max(eh.end for eh in ehrelated)
2076
+
2077
+ # Push the `__exit__` method (or null) to the stack,
2078
+ # followed by the original tos (which is the instatiated context
2079
+ # manager). This is such that the `CALL` after the with-block can
2080
+ # be simulated.
2081
+ state.push(method)
2082
+ state.push(tos)
2083
+ # Record the instruction.
2084
+ state.append(
2085
+ old_inst, contextmanager=tos, exit_method=method, block_end=end
2086
+ )
2087
+
2088
+ # Insert WITH-block.
2089
+ state.push_block(
2090
+ state.make_block(
2091
+ kind="WITH",
2092
+ end=end,
2093
+ )
2094
+ )
2095
+ # And fork to force a new block.
2096
+ state.fork(pc=inst.next)
2097
+
2098
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
2099
+ pass
2100
+ else:
2101
+ raise NotImplementedError(PYVERSION)
2102
+
2103
+ if PYVERSION in ((3, 14),):
2104
+
2105
+ def op_LOAD_COMMON_CONSTANT(self, state, inst):
2106
+ oparg = inst.arg
2107
+ if isinstance(dis._common_constants[oparg], AssertionError):
2108
+ name = "assertion_error"
2109
+ else:
2110
+ raise NotImplementedError
2111
+ res = state.make_temp(name)
2112
+ state.append(inst, res=res, idx=oparg)
2113
+ state.push(res)
2114
+ elif PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
2115
+ pass
2116
+ else:
2117
+ raise NotImplementedError(PYVERSION)
2118
+
1873
2119
 
1874
2120
  @total_ordering
1875
2121
  class _State(object):
@@ -2118,7 +2364,7 @@ class _State(object):
2118
2364
  stack.append(self.make_temp())
2119
2365
  # Handle changes on the blockstack
2120
2366
  blockstack = list(self._blockstack)
2121
- if PYVERSION in ((3, 11), (3, 12), (3, 13)):
2367
+ if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
2122
2368
  # pop expired block in destination pc
2123
2369
  while blockstack:
2124
2370
  top = blockstack[-1]
@@ -2229,7 +2475,7 @@ class StatePy313(StatePy311):
2229
2475
  return self._make_func_attrs[make_func_res]
2230
2476
 
2231
2477
 
2232
- if PYVERSION in ((3, 13),):
2478
+ if PYVERSION in ((3, 13), (3, 14)):
2233
2479
  State = StatePy313
2234
2480
  elif PYVERSION in ((3, 11), (3, 12)):
2235
2481
  State = StatePy311
@@ -2273,7 +2519,7 @@ def adapt_state_infos(state):
2273
2519
  data.update(state.get_function_attributes(data["res"]))
2274
2520
  return offset, data
2275
2521
 
2276
- if PYVERSION in ((3, 13),):
2522
+ if PYVERSION in ((3, 13), (3, 14)):
2277
2523
  insts = tuple(map(process_function_attributes, state.instructions))
2278
2524
  elif PYVERSION in ((3, 9), (3, 10), (3, 11), (3, 12)):
2279
2525
  insts = tuple(state.instructions)