def _end_try_blocks(self):
        """Closes all try blocks by inserting the required marker at the
        exception handler

        This is only needed for py3.11 because of the changes in exception
        handling. This merely maps the new py3.11 semantics back to the old way.

        What the code does:

        - For each block, compute the difference of blockstack to its incoming
          blocks' blockstack.
        - If the incoming blockstack has an extra TRY, the current block must
          be the EXCEPT block and we need to insert a marker.

        See also: _insert_try_block_end
        """
        assert PYVERSION in ((3, 11), (3, 12), (3, 13))
        graph = self.cfa.graph
        for offset, block in self.blocks.items():
            # Get current blockstack
            cur_bs = self.dfa.infos[offset].blockstack
            # Check blockstack of the incoming blocks
            for inc, _ in graph.predecessors(offset):
                inc_bs = self.dfa.infos[inc].blockstack

                # find first diff in the blockstack
                for i, (x, y) in enumerate(zip(cur_bs, inc_bs)):
                    if x != y:
                        break
                else:
                    i = min(len(cur_bs), len(inc_bs))

                def do_change(remain):
                    while remain:
                        ent = remain.pop()
                        if ent['kind'] == BlockKind('TRY'):
                            # Extend block with marker for end of try
                            self.current_block = block
                            oldbody = list(block.body)
                            block.body.clear()
                            self._insert_try_block_end()
                            block.body.extend(oldbody)
                            return True

                if do_change(list(inc_bs[i:])):
                    break
Closes all try blocks by inserting the required marker at the
        exception handler

        This is only needed for py3.11 because of the changes in exception
        handling. This merely maps the new py3.11 semantics back to the old way.

        What the code does:

        - For each block, compute the difference of blockstack to its incoming
          blocks' blockstack.
        - If the incoming blockstack has an extra TRY, the current block must
          be the EXCEPT block and we need to insert a marker.

        See also: _insert_try_block_end
        
numba/core/interpreter.py