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
numba_cuda/VERSION CHANGED
@@ -1 +1 @@
1
- 0.23.0
1
+ 0.24.0
@@ -1,6 +1,8 @@
1
1
  # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
2
  # SPDX-License-Identifier: BSD-2-Clause
3
3
 
4
+ # delvewheel: patch
5
+
4
6
  import importlib
5
7
  from numba.cuda.core import config
6
8
  from .utils import _readenv
@@ -23,7 +25,8 @@ if not (
23
25
  ):
24
26
  raise ImportError(
25
27
  "NVIDIA CUDA Python bindings not found. Install the 'cuda' package "
26
- "(e.g. pip install nvidia-cuda-python or numba-cuda[cuXY])."
28
+ '(e.g. pip install "cuda-bindings==XY.*" or "numba-cuda[cuXY]", '
29
+ "with XY=12 or XY=13)."
27
30
  )
28
31
 
29
32
  if config.ENABLE_CUDASIM:
@@ -0,0 +1,47 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+ from packaging import version
4
+ from cuda import core
5
+
6
+
7
+ CUDA_CORE_VERSION = version.parse(core.__version__)
8
+ if CUDA_CORE_VERSION < version.parse("0.5.0"):
9
+ from cuda.core.experimental import (
10
+ Program,
11
+ ProgramOptions,
12
+ Linker,
13
+ LinkerOptions,
14
+ Stream,
15
+ Device,
16
+ launch,
17
+ ObjectCode,
18
+ LaunchConfig,
19
+ )
20
+ from cuda.core.experimental._utils.cuda_utils import CUDAError, NVRTCError
21
+ else:
22
+ from cuda.core import (
23
+ Program,
24
+ ProgramOptions,
25
+ Linker,
26
+ LinkerOptions,
27
+ Stream,
28
+ Device,
29
+ launch,
30
+ ObjectCode,
31
+ LaunchConfig,
32
+ )
33
+ from cuda.core._utils.cuda_utils import CUDAError, NVRTCError
34
+
35
+ __all__ = [
36
+ "Program",
37
+ "ProgramOptions",
38
+ "Linker",
39
+ "LinkerOptions",
40
+ "Stream",
41
+ "Device",
42
+ "launch",
43
+ "CUDAError",
44
+ "NVRTCError",
45
+ "ObjectCode",
46
+ "LaunchConfig",
47
+ ]
@@ -29,7 +29,7 @@
29
29
  *
30
30
  */
31
31
 
32
- #if (PY_MAJOR_VERSION >= 3) && ((PY_MINOR_VERSION == 12) || (PY_MINOR_VERSION == 13))
32
+ #if (PY_MAJOR_VERSION >= 3) && ((PY_MINOR_VERSION == 12) || (PY_MINOR_VERSION == 13) || (PY_MINOR_VERSION == 14))
33
33
 
34
34
  #ifndef Py_BUILD_CORE
35
35
  #define Py_BUILD_CORE 1
@@ -1004,12 +1004,18 @@ static PyTypeObject DispatcherType = {
1004
1004
  0, /* tp_version_tag */
1005
1005
  0, /* tp_finalize */
1006
1006
  0, /* tp_vectorcall */
1007
- #if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 12)
1007
+ #if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION >= 12)
1008
1008
  /* This was introduced first in 3.12
1009
1009
  * https://github.com/python/cpython/issues/91051
1010
1010
  */
1011
1011
  0, /* tp_watched */
1012
1012
  #endif
1013
+ #if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION >= 13)
1014
+ /* This was introduced in 3.13
1015
+ * https://github.com/python/cpython/pull/114900
1016
+ */
1017
+ 0, /* tp_versions_used */
1018
+ #endif
1013
1019
 
1014
1020
  /* WARNING: Do not remove this, only modify it! It is a version guard to
1015
1021
  * act as a reminder to update this struct on Python version update! */
@@ -110,7 +110,12 @@ _Numba_hashtable_hash_int(const void *key)
110
110
  extern "C" Py_uhash_t
111
111
  _Numba_hashtable_hash_ptr(const void *key)
112
112
  {
113
+ /* Use public API on Python 3.13+; _Py_HashPointer is deprecated on 3.14+ */
114
+ #if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION >= 13)
115
+ return (Py_uhash_t)Py_HashPointer((void *)key);
116
+ #else
113
117
  return (Py_uhash_t)_Py_HashPointer((void *)key);
118
+ #endif
114
119
  }
115
120
 
116
121
  extern "C" int
@@ -33,6 +33,6 @@
33
33
  Py_DECREF(tmp); } while (0)
34
34
 
35
35
 
36
- #define NB_SUPPORTED_PYTHON_MINOR ((PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12) || (PY_MINOR_VERSION == 13))
36
+ #define NB_SUPPORTED_PYTHON_MINOR ((PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12) || (PY_MINOR_VERSION == 13) || (PY_MINOR_VERSION == 14))
37
37
 
38
38
  #endif /* NUMBA_PY_MODULE_H_ */
@@ -17,11 +17,24 @@
17
17
  #include <numpy/npy_2_compat.h>
18
18
  #endif
19
19
 
20
- #if (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION == 13)
21
- #ifndef Py_BUILD_CORE
22
- #define Py_BUILD_CORE 1
23
- #endif
24
- #include "internal/pycore_setobject.h" // _PySet_NextEntry()
20
+ #ifndef Py_BUILD_CORE
21
+ #define Py_BUILD_CORE 1
22
+ #endif
23
+
24
+ #if (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION >= 13)
25
+ // required include from Python 3.13+
26
+ #include "internal/pycore_setobject.h"
27
+ #ifndef PySet_NextEntry
28
+ #define PySet_NextEntry _PySet_NextEntryRef
29
+ #endif
30
+ #else
31
+ #ifndef PySet_NextEntry
32
+ #define PySet_NextEntry _PySet_NextEntry
33
+ #endif
34
+ #endif
35
+
36
+ #ifdef Py_BUILD_CORE
37
+ #undef Py_BUILD_CORE
25
38
  #endif
26
39
 
27
40
 
@@ -410,17 +423,52 @@ compute_fingerprint(string_writer_t *w, PyObject *val)
410
423
  Py_hash_t h;
411
424
  PyObject *item;
412
425
  Py_ssize_t pos = 0;
426
+ int rc;
427
+
428
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 13
429
+ // needed when using _PySet_NextEntryRef
430
+ Py_BEGIN_CRITICAL_SECTION(val);
431
+ #endif
413
432
  /* Only one item is considered, as in typeof.py */
414
- if (!_PySet_NextEntry(val, &pos, &item, &h)) {
433
+ rc = PySet_NextEntry(val, &pos, &item, &h);
434
+
435
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 13
436
+ // needed when using _PySet_NextEntryRef
437
+ Py_END_CRITICAL_SECTION();
438
+ #endif
439
+
440
+ if (!rc) {
415
441
  /* Empty set */
416
442
  PyErr_SetString(PyExc_ValueError,
417
443
  "cannot compute fingerprint of empty set");
418
444
  return -1;
419
445
  }
420
- TRY(string_writer_put_char, w, OP_SET);
421
- TRY(compute_fingerprint, w, item);
446
+
447
+ if (string_writer_put_char(w, OP_SET)) {
448
+ goto fingerprint_error;
449
+ }
450
+
451
+ if (compute_fingerprint(w, item)) {
452
+ goto fingerprint_error;
453
+ }
454
+
455
+ goto fingerprint_success;
456
+
457
+ fingerprint_error:
458
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 13
459
+ // extra ref if using python >= 3.13
460
+ Py_XDECREF(item);
461
+ #endif
462
+ return -1;
463
+
464
+ fingerprint_success:
465
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 13
466
+ // extra ref if using python >= 3.13
467
+ Py_XDECREF(item);
468
+ #endif
422
469
  return 0;
423
470
  }
471
+
424
472
  if (PyObject_CheckBuffer(val)) {
425
473
  Py_buffer buf;
426
474
  int flags = PyBUF_ND | PyBUF_STRIDES | PyBUF_FORMAT;
@@ -337,12 +337,18 @@ static PyTypeObject MemAllocType = {
337
337
  0, /* tp_version_tag */
338
338
  0, /* tp_finalize */
339
339
  0, /* tp_vectorcall */
340
- #if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 12)
340
+ #if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION >= 12)
341
341
  /* This was introduced first in 3.12
342
342
  * https://github.com/python/cpython/issues/91051
343
343
  */
344
344
  0, /* tp_watched */
345
345
  #endif
346
+ #if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION >= 13)
347
+ /* This was introduced in 3.13
348
+ * https://github.com/python/cpython/pull/114900
349
+ */
350
+ 0, /* tp_versions_used */
351
+ #endif
346
352
 
347
353
  /* WARNING: Do not remove this, only modify it! It is a version guard to
348
354
  * act as a reminder to update this struct on Python version update! */
@@ -422,10 +422,9 @@ HAVE_ARGUMENT = dis.HAVE_ARGUMENT
422
422
  EXTENDED_ARG = dis.EXTENDED_ARG
423
423
 
424
424
 
425
- _BUILTIN_TYPE_NAMES = {}
426
- for k, v in types.__dict__.items():
427
- if type(v) is type:
428
- _BUILTIN_TYPE_NAMES[v] = k
425
+ _BUILTIN_TYPE_NAMES = {
426
+ v: k for k, v in types.__dict__.items() if type(v) is type
427
+ }
429
428
 
430
429
 
431
430
  def _builtin_type(name):
@@ -463,7 +462,7 @@ def _extract_class_dict(cls):
463
462
  base_value = inherited_dict[name]
464
463
  if value is base_value:
465
464
  to_remove.append(name)
466
- except KeyError:
465
+ except KeyError: # noqa: PERF203
467
466
  pass
468
467
  for name in to_remove:
469
468
  clsdict.pop(name)
@@ -209,7 +209,9 @@ class CUDACodeLibrary(serialize.ReduceMixin, CodeLibrary):
209
209
  return cc
210
210
 
211
211
  device = devices.get_context().device
212
- return device.compute_capability
212
+ cc = device.compute_capability
213
+ cc = (cc[0], cc[1], "a" if cc >= (9, 0) else "")
214
+ return cc
213
215
 
214
216
  def get_asm_str(self, cc=None):
215
217
  return "\n".join(self.get_asm_strs(cc=cc))
@@ -347,7 +349,7 @@ class CUDACodeLibrary(serialize.ReduceMixin, CodeLibrary):
347
349
  cufunc = self._cufunc_cache.get(device.id, None)
348
350
  if cufunc:
349
351
  return cufunc
350
- cubin = self.get_cubin(cc=device.compute_capability)
352
+ cubin = self.get_cubin()
351
353
  module = ctx.create_module_image(
352
354
  cubin, self._setup_functions, self._teardown_functions
353
355
  )
@@ -852,15 +852,15 @@ def kernel_fixup(kernel, debug):
852
852
  return_value = kernel.args[0]
853
853
 
854
854
  for block in kernel.blocks:
855
- remove_list = []
856
-
857
855
  # Find all stores first
858
- for inst in block.instructions:
856
+ remove_list = [
857
+ inst
858
+ for inst in block.instructions
859
859
  if (
860
860
  isinstance(inst, ir.StoreInstr)
861
861
  and inst.operands[1] == return_value
862
- ):
863
- remove_list.append(inst)
862
+ )
863
+ ]
864
864
 
865
865
  # Remove all stores
866
866
  for to_remove in remove_list:
@@ -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"] = [
@@ -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
  """
@@ -1322,11 +1322,7 @@ class _wrap_missing_loc(object):
1322
1322
  # ignore attributes if not available (i.e fix py2.7)
1323
1323
  attrs = "__name__", "libs"
1324
1324
  for attr in attrs:
1325
- try:
1326
- val = getattr(fn, attr)
1327
- except AttributeError:
1328
- pass
1329
- else:
1325
+ if (val := getattr(fn, attr, None)) is not None:
1330
1326
  setattr(wrapper, attr, val)
1331
1327
 
1332
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):