numba-cuda 0.21.1__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 (110) 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/api.py +4 -1
  5. numba_cuda/numba/cuda/cext/_dispatcher.cp313-win_amd64.pyd +0 -0
  6. numba_cuda/numba/cuda/cext/_dispatcher.cpp +8 -40
  7. numba_cuda/numba/cuda/cext/_hashtable.cpp +5 -0
  8. numba_cuda/numba/cuda/cext/_helperlib.cp313-win_amd64.pyd +0 -0
  9. numba_cuda/numba/cuda/cext/_pymodule.h +1 -1
  10. numba_cuda/numba/cuda/cext/_typeconv.cp313-win_amd64.pyd +0 -0
  11. numba_cuda/numba/cuda/cext/_typeof.cpp +56 -119
  12. numba_cuda/numba/cuda/cext/mviewbuf.c +7 -1
  13. numba_cuda/numba/cuda/cext/mviewbuf.cp313-win_amd64.pyd +0 -0
  14. numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +4 -5
  15. numba_cuda/numba/cuda/codegen.py +46 -12
  16. numba_cuda/numba/cuda/compiler.py +15 -9
  17. numba_cuda/numba/cuda/core/analysis.py +29 -21
  18. numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +1 -1
  19. numba_cuda/numba/cuda/core/annotations/type_annotations.py +4 -4
  20. numba_cuda/numba/cuda/core/base.py +12 -11
  21. numba_cuda/numba/cuda/core/bytecode.py +21 -13
  22. numba_cuda/numba/cuda/core/byteflow.py +336 -90
  23. numba_cuda/numba/cuda/core/compiler.py +3 -4
  24. numba_cuda/numba/cuda/core/compiler_machinery.py +3 -3
  25. numba_cuda/numba/cuda/core/config.py +5 -7
  26. numba_cuda/numba/cuda/core/consts.py +1 -1
  27. numba_cuda/numba/cuda/core/controlflow.py +17 -9
  28. numba_cuda/numba/cuda/core/cuda_errors.py +917 -0
  29. numba_cuda/numba/cuda/core/errors.py +4 -912
  30. numba_cuda/numba/cuda/core/inline_closurecall.py +82 -67
  31. numba_cuda/numba/cuda/core/interpreter.py +334 -160
  32. numba_cuda/numba/cuda/core/ir.py +191 -119
  33. numba_cuda/numba/cuda/core/ir_utils.py +149 -128
  34. numba_cuda/numba/cuda/core/postproc.py +8 -8
  35. numba_cuda/numba/cuda/core/pythonapi.py +3 -0
  36. numba_cuda/numba/cuda/core/rewrites/ir_print.py +6 -3
  37. numba_cuda/numba/cuda/core/rewrites/static_binop.py +1 -1
  38. numba_cuda/numba/cuda/core/rewrites/static_getitem.py +5 -5
  39. numba_cuda/numba/cuda/core/rewrites/static_raise.py +3 -3
  40. numba_cuda/numba/cuda/core/ssa.py +5 -5
  41. numba_cuda/numba/cuda/core/transforms.py +29 -16
  42. numba_cuda/numba/cuda/core/typed_passes.py +10 -10
  43. numba_cuda/numba/cuda/core/typeinfer.py +42 -27
  44. numba_cuda/numba/cuda/core/untyped_passes.py +82 -65
  45. numba_cuda/numba/cuda/cpython/unicode.py +2 -2
  46. numba_cuda/numba/cuda/cpython/unicode_support.py +1 -3
  47. numba_cuda/numba/cuda/cudadecl.py +0 -13
  48. numba_cuda/numba/cuda/cudadrv/devicearray.py +10 -9
  49. numba_cuda/numba/cuda/cudadrv/driver.py +142 -519
  50. numba_cuda/numba/cuda/cudadrv/dummyarray.py +4 -0
  51. numba_cuda/numba/cuda/cudadrv/nvrtc.py +87 -32
  52. numba_cuda/numba/cuda/cudaimpl.py +0 -12
  53. numba_cuda/numba/cuda/debuginfo.py +25 -0
  54. numba_cuda/numba/cuda/descriptor.py +1 -1
  55. numba_cuda/numba/cuda/device_init.py +4 -7
  56. numba_cuda/numba/cuda/deviceufunc.py +3 -6
  57. numba_cuda/numba/cuda/dispatcher.py +39 -49
  58. numba_cuda/numba/cuda/intrinsics.py +150 -1
  59. numba_cuda/numba/cuda/libdeviceimpl.py +1 -2
  60. numba_cuda/numba/cuda/lowering.py +36 -29
  61. numba_cuda/numba/cuda/memory_management/nrt.py +10 -14
  62. numba_cuda/numba/cuda/np/arrayobj.py +61 -9
  63. numba_cuda/numba/cuda/np/numpy_support.py +32 -9
  64. numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +4 -3
  65. numba_cuda/numba/cuda/printimpl.py +20 -0
  66. numba_cuda/numba/cuda/serialize.py +10 -0
  67. numba_cuda/numba/cuda/stubs.py +0 -11
  68. numba_cuda/numba/cuda/testing.py +4 -8
  69. numba_cuda/numba/cuda/tests/benchmarks/test_kernel_launch.py +21 -4
  70. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +1 -2
  71. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +195 -51
  72. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +6 -2
  73. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +3 -1
  74. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +1 -1
  75. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +6 -7
  76. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +11 -12
  77. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +53 -23
  78. numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +61 -9
  79. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +6 -0
  80. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +47 -0
  81. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +22 -1
  82. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +13 -0
  83. numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +1 -1
  84. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +1 -1
  85. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +94 -0
  86. numba_cuda/numba/cuda/tests/cudapy/test_device_array_capture.py +243 -0
  87. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +3 -3
  88. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1 -1
  89. numba_cuda/numba/cuda/tests/cudapy/test_numba_interop.py +35 -0
  90. numba_cuda/numba/cuda/tests/cudapy/test_print.py +51 -0
  91. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +37 -35
  92. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +117 -1
  93. numba_cuda/numba/cuda/tests/doc_examples/test_globals.py +111 -0
  94. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +61 -0
  95. numba_cuda/numba/cuda/tests/nrt/test_nrt.py +31 -0
  96. numba_cuda/numba/cuda/tests/support.py +11 -0
  97. numba_cuda/numba/cuda/types/cuda_functions.py +1 -1
  98. numba_cuda/numba/cuda/typing/asnumbatype.py +37 -2
  99. numba_cuda/numba/cuda/typing/context.py +3 -1
  100. numba_cuda/numba/cuda/typing/typeof.py +51 -2
  101. {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/METADATA +4 -13
  102. {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/RECORD +106 -105
  103. numba_cuda/numba/cuda/cext/_devicearray.cp313-win_amd64.pyd +0 -0
  104. numba_cuda/numba/cuda/cext/_devicearray.cpp +0 -159
  105. numba_cuda/numba/cuda/cext/_devicearray.h +0 -29
  106. numba_cuda/numba/cuda/intrinsic_wrapper.py +0 -41
  107. {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/WHEEL +0 -0
  108. {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/licenses/LICENSE +0 -0
  109. {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/licenses/LICENSE.numba +0 -0
  110. {numba_cuda-0.21.1.dist-info → numba_cuda-0.24.0.dist-info}/top_level.txt +0 -0
@@ -38,13 +38,16 @@ def compute_use_defs(blocks):
38
38
  func = ir_extension_usedefs[type(stmt)]
39
39
  func(stmt, use_set, def_set)
40
40
  continue
41
- if isinstance(stmt, ir.Assign):
42
- if isinstance(stmt.value, ir.Inst):
41
+ if isinstance(stmt, ir.assign_types):
42
+ if isinstance(stmt.value, ir.inst_types):
43
43
  rhs_set = set(var.name for var in stmt.value.list_vars())
44
- elif isinstance(stmt.value, ir.Var):
44
+ elif isinstance(stmt.value, ir.var_types):
45
45
  rhs_set = set([stmt.value.name])
46
- elif isinstance(
47
- stmt.value, (ir.Arg, ir.Const, ir.Global, ir.FreeVar)
46
+ elif (
47
+ isinstance(stmt.value, ir.arg_types)
48
+ or isinstance(stmt.value, ir.const_types)
49
+ or isinstance(stmt.value, ir.global_types)
50
+ or isinstance(stmt.value, ir.freevar_types)
48
51
  ):
49
52
  rhs_set = ()
50
53
  else:
@@ -326,7 +329,7 @@ def rewrite_semantic_constants(func_ir, called_args):
326
329
  if getattr(val, "op", None) == "getattr":
327
330
  if val.attr == "ndim":
328
331
  arg_def = guard(get_definition, func_ir, val.value)
329
- if isinstance(arg_def, ir.Arg):
332
+ if isinstance(arg_def, ir.arg_types):
330
333
  argty = called_args[arg_def.index]
331
334
  if isinstance(argty, types.Array):
332
335
  rewrite_statement(func_ir, stmt, argty.ndim)
@@ -337,17 +340,17 @@ def rewrite_semantic_constants(func_ir, called_args):
337
340
  func = guard(get_definition, func_ir, val.func)
338
341
  if (
339
342
  func is not None
340
- and isinstance(func, ir.Global)
343
+ and isinstance(func, ir.global_types)
341
344
  and getattr(func, "value", None) is len
342
345
  ):
343
346
  (arg,) = val.args
344
347
  arg_def = guard(get_definition, func_ir, arg)
345
- if isinstance(arg_def, ir.Arg):
348
+ if isinstance(arg_def, ir.arg_types):
346
349
  argty = called_args[arg_def.index]
347
350
  if isinstance(argty, types.BaseTuple):
348
351
  rewrite_statement(func_ir, stmt, argty.count)
349
352
  elif (
350
- isinstance(arg_def, ir.Expr)
353
+ isinstance(arg_def, ir.expr_types)
351
354
  and arg_def.op == "typed_getitem"
352
355
  ):
353
356
  argty = arg_def.dtype
@@ -358,9 +361,9 @@ def rewrite_semantic_constants(func_ir, called_args):
358
361
 
359
362
  for blk in func_ir.blocks.values():
360
363
  for stmt in blk.body:
361
- if isinstance(stmt, ir.Assign):
364
+ if isinstance(stmt, ir.assign_types):
362
365
  val = stmt.value
363
- if isinstance(val, ir.Expr):
366
+ if isinstance(val, ir.expr_types):
364
367
  rewrite_array_ndim(val, func_ir, called_args)
365
368
  rewrite_tuple_len(val, func_ir, called_args)
366
369
 
@@ -391,7 +394,7 @@ def find_literally_calls(func_ir, argtypes):
391
394
  for blk in func_ir.blocks.values():
392
395
  for assign in blk.find_exprs(op="call"):
393
396
  var = ir_utils.guard(ir_utils.get_definition, func_ir, assign.func)
394
- if isinstance(var, (ir.Global, ir.FreeVar)):
397
+ if isinstance(var, ir.global_types + ir.freevar_types):
395
398
  fnobj = var.value
396
399
  else:
397
400
  fnobj = ir_utils.guard(
@@ -401,7 +404,7 @@ def find_literally_calls(func_ir, argtypes):
401
404
  # Found
402
405
  [arg] = assign.args
403
406
  defarg = func_ir.get_definition(arg)
404
- if isinstance(defarg, ir.Arg):
407
+ if isinstance(defarg, ir.arg_types):
405
408
  argindex = defarg.index
406
409
  marked_args.add(argindex)
407
410
  first_loc.setdefault(argindex, assign.loc)
@@ -473,14 +476,14 @@ def dead_branch_prune(func_ir, called_args):
473
476
  branches = []
474
477
  for blk in func_ir.blocks.values():
475
478
  branch_or_jump = blk.body[-1]
476
- if isinstance(branch_or_jump, ir.Branch):
479
+ if isinstance(branch_or_jump, ir.branch_types):
477
480
  branch = branch_or_jump
478
481
  pred = guard(get_definition, func_ir, branch.cond.name)
479
482
  if pred is not None and getattr(pred, "op", None) == "call":
480
483
  function = guard(get_definition, func_ir, pred.func)
481
484
  if (
482
485
  function is not None
483
- and isinstance(function, ir.Global)
486
+ and isinstance(function, ir.global_types)
484
487
  and function.value is bool
485
488
  ):
486
489
  condition = guard(get_definition, func_ir, pred.args[0])
@@ -539,7 +542,9 @@ def dead_branch_prune(func_ir, called_args):
539
542
  try:
540
543
  # Just to prevent accidents, whilst already guarded, ensure this
541
544
  # is an ir.Const
542
- if not isinstance(pred, (ir.Const, ir.FreeVar, ir.Global)):
545
+ if not isinstance(
546
+ pred, ir.const_types + ir.freevar_types + ir.global_types
547
+ ):
543
548
  raise TypeError("Expected constant Numba IR node")
544
549
  take_truebr = bool(pred.value)
545
550
  except TypeError:
@@ -584,8 +589,11 @@ def dead_branch_prune(func_ir, called_args):
584
589
  phi2asgn = dict()
585
590
  for lbl, blk in func_ir.blocks.items():
586
591
  for stmt in blk.body:
587
- if isinstance(stmt, ir.Assign):
588
- if isinstance(stmt.value, ir.Expr) and stmt.value.op == "phi":
592
+ if isinstance(stmt, ir.assign_types):
593
+ if (
594
+ isinstance(stmt.value, ir.expr_types)
595
+ and stmt.value.op == "phi"
596
+ ):
589
597
  phi2lbl[stmt.value] = lbl
590
598
  phi2asgn[stmt.value] = stmt
591
599
 
@@ -599,12 +607,12 @@ def dead_branch_prune(func_ir, called_args):
599
607
 
600
608
  for branch, condition, blk in branch_info:
601
609
  const_conds = []
602
- if isinstance(condition, ir.Expr) and condition.op == "binop":
610
+ if isinstance(condition, ir.expr_types) and condition.op == "binop":
603
611
  prune = prune_by_value
604
612
  for arg in [condition.lhs, condition.rhs]:
605
613
  resolved_const = Unknown()
606
614
  arg_def = guard(get_definition, func_ir, arg)
607
- if isinstance(arg_def, ir.Arg):
615
+ if isinstance(arg_def, ir.arg_types):
608
616
  # it's an e.g. literal argument to the function
609
617
  resolved_const = resolve_input_arg_const(arg_def.index)
610
618
  prune = prune_by_type
@@ -668,7 +676,7 @@ def dead_branch_prune(func_ir, called_args):
668
676
  for _, cond, blk in branch_info:
669
677
  if cond in deadcond:
670
678
  for x in blk.body:
671
- if isinstance(x, ir.Assign) and x.value is cond:
679
+ if isinstance(x, ir.assign_types) and x.value is cond:
672
680
  # rewrite the condition as a true/false bit
673
681
  nullified_info = nullified_conditions[deadcond.index(cond)]
674
682
  # only do a rewrite of conditions, predicates need to retain
@@ -273,7 +273,7 @@ class Annotate:
273
273
  ann = function.get_annotation_info(signature=signature)
274
274
  self.ann = ann
275
275
 
276
- for k, v in ann.items():
276
+ for v in ann.values():
277
277
  res = hllines(reform_code(v), style)
278
278
  rest = htlines(reform_code(v), style)
279
279
  v["pygments_lines"] = [
@@ -94,16 +94,16 @@ class TypeAnnotation(object):
94
94
  for inst in blk.body:
95
95
  lineno = inst.loc.line
96
96
 
97
- if isinstance(inst, ir.Assign):
97
+ if isinstance(inst, ir.assign_types):
98
98
  if found_lifted_loop:
99
99
  atype = "XXX Lifted Loop XXX"
100
100
  found_lifted_loop = False
101
101
  elif (
102
- isinstance(inst.value, ir.Expr)
102
+ isinstance(inst.value, ir.expr_types)
103
103
  and inst.value.op == "call"
104
104
  ):
105
105
  atype = self.calltypes[inst.value]
106
- elif isinstance(inst.value, ir.Const) and isinstance(
106
+ elif isinstance(inst.value, ir.const_types) and isinstance(
107
107
  inst.value.value, LiftedLoop
108
108
  ):
109
109
  atype = "XXX Lifted Loop XXX"
@@ -113,7 +113,7 @@ class TypeAnnotation(object):
113
113
  atype = self.typemap.get(inst.target.name, "<missing>")
114
114
 
115
115
  aline = "%s = %s :: %s" % (inst.target, inst.value, atype)
116
- elif isinstance(inst, ir.SetItem):
116
+ elif isinstance(inst, ir.setitem_types):
117
117
  atype = self.calltypes[inst]
118
118
  aline = "%s :: %s" % (inst, atype)
119
119
  else:
@@ -63,11 +63,11 @@ class OverloadSelector(object):
63
63
  """
64
64
  Select all compatible signatures and their implementation.
65
65
  """
66
- out = {}
67
- for ver_sig, impl in self.versions:
68
- if self._match_arglist(ver_sig, sig):
69
- out[ver_sig] = impl
70
- return out
66
+ return {
67
+ ver_sig: impl
68
+ for ver_sig, impl in self.versions
69
+ if self._match_arglist(ver_sig, sig)
70
+ }
71
71
 
72
72
  def _best_signature(self, candidates):
73
73
  """
@@ -933,7 +933,12 @@ class BaseContext(object):
933
933
  If *caching* evaluates True, the function keeps the compiled function
934
934
  for reuse in *.cached_internal_func*.
935
935
  """
936
- cache_key = (impl.__code__, sig, type(self.error_model))
936
+ cache_key = (
937
+ impl.__code__,
938
+ sig,
939
+ type(self.error_model),
940
+ self.enable_nrt,
941
+ )
937
942
  if not caching:
938
943
  cached = None
939
944
  else:
@@ -1317,11 +1322,7 @@ class _wrap_missing_loc(object):
1317
1322
  # ignore attributes if not available (i.e fix py2.7)
1318
1323
  attrs = "__name__", "libs"
1319
1324
  for attr in attrs:
1320
- try:
1321
- val = getattr(fn, attr)
1322
- except AttributeError:
1323
- pass
1324
- else:
1325
+ if (val := getattr(fn, attr, None)) is not None:
1325
1326
  setattr(wrapper, attr, val)
1326
1327
 
1327
1328
  return wrapper
@@ -14,7 +14,7 @@ from numba.cuda import utils
14
14
  from numba.cuda.utils import PYVERSION
15
15
 
16
16
 
17
- if PYVERSION in ((3, 12), (3, 13)):
17
+ if PYVERSION in ((3, 12), (3, 13), (3, 14)):
18
18
  from opcode import _inline_cache_entries
19
19
 
20
20
  # Instruction/opcode length in bytes
@@ -112,7 +112,7 @@ class ByteCodeInst(object):
112
112
  # https://bugs.python.org/issue27129
113
113
  # https://github.com/python/cpython/pull/25069
114
114
  assert self.is_jump
115
- if PYVERSION in ((3, 13),):
115
+ if PYVERSION in ((3, 13), (3, 14)):
116
116
  if self.opcode in (
117
117
  dis.opmap[k]
118
118
  for k in ["JUMP_BACKWARD", "JUMP_BACKWARD_NO_INTERRUPT"]
@@ -141,7 +141,7 @@ class ByteCodeInst(object):
141
141
  else:
142
142
  raise NotImplementedError(PYVERSION)
143
143
 
144
- if PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
144
+ if PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13), (3, 14)):
145
145
  if self.opcode in JREL_OPS:
146
146
  return self.next + self.arg * 2
147
147
  else:
@@ -179,7 +179,7 @@ NO_ARG_LEN = 1
179
179
  OPCODE_NOP = dis.opname.index("NOP")
180
180
 
181
181
 
182
- if PYVERSION in ((3, 13),):
182
+ if PYVERSION in ((3, 13), (3, 14)):
183
183
 
184
184
  def _unpack_opargs(code):
185
185
  buf = []
@@ -418,7 +418,7 @@ class _ByteCode(object):
418
418
 
419
419
 
420
420
  def _fix_LOAD_GLOBAL_arg(arg):
421
- if PYVERSION in ((3, 11), (3, 12), (3, 13)):
421
+ if PYVERSION in ((3, 11), (3, 12), (3, 13), (3, 14)):
422
422
  return arg >> 1
423
423
  elif PYVERSION in (
424
424
  (3, 9),
@@ -452,12 +452,13 @@ class ByteCodePy311(_ByteCode):
452
452
  """
453
453
  Returns the exception entry for the given instruction offset
454
454
  """
455
- candidates = []
456
- for ent in self.exception_entries:
457
- if ent.start <= offset < ent.end:
458
- candidates.append((ent.depth, ent))
455
+ candidates = [
456
+ (ent.depth, ent)
457
+ for ent in self.exception_entries
458
+ if ent.start <= offset < ent.end
459
+ ]
459
460
  if candidates:
460
- ent = max(candidates)[1]
461
+ _, ent = max(candidates)
461
462
  return ent
462
463
 
463
464
 
@@ -592,7 +593,7 @@ class ByteCodePy312(ByteCodePy311):
592
593
  if not next_inst.opname == "FOR_ITER":
593
594
  continue
594
595
 
595
- if PYVERSION in ((3, 13),):
596
+ if PYVERSION in ((3, 13), (3, 14)):
596
597
  # Check end of pattern, two instructions.
597
598
  # Check for the corresponding END_FOR, exception table end
598
599
  # is non-inclusive, so subtract one.
@@ -601,8 +602,14 @@ class ByteCodePy312(ByteCodePy311):
601
602
  if not curr_inst.opname == "END_FOR":
602
603
  continue
603
604
  next_inst = self.table[self.ordered_offsets[index - 1]]
604
- if not next_inst.opname == "POP_TOP":
605
- continue
605
+ if PYVERSION in ((3, 13),):
606
+ if not next_inst.opname == "POP_TOP":
607
+ continue
608
+ elif PYVERSION in ((3, 14),):
609
+ if not next_inst.opname == "POP_ITER":
610
+ continue
611
+ else:
612
+ raise NotImplementedError(PYVERSION)
606
613
  # END_FOR must be followed by SWAP(2)
607
614
  next_inst = self.table[self.ordered_offsets[index]]
608
615
  if not next_inst.opname == "SWAP" and next_inst.arg == 2:
@@ -646,6 +653,7 @@ if PYVERSION == (3, 11):
646
653
  elif PYVERSION in (
647
654
  (3, 12),
648
655
  (3, 13),
656
+ (3, 14),
649
657
  ):
650
658
  ByteCode = ByteCodePy312
651
659
  elif PYVERSION < (3, 11):