old_contents: import re
  from collections import deque
  
  from dmoj.executors.mixins import ScriptDirectoryMixin
  from dmoj.executors.script_executor import ScriptExecutor
  from dmoj.result import Result
  from dmoj.utils.unicode import utf8bytes, utf8text
  
  retraceback = re.compile(r'Traceback \(most recent call last\):\n.*?\n([a-zA-Z_]\w*)(?::[^\n]*?)?$', re.S | re.M)
  
  
  class PythonExecutor(ScriptDirectoryMixin, ScriptExecutor):
      loader_script = '''\
  import runpy, sys, os
  del sys.argv[0]
  sys.stdin = os.fdopen(0, 'r', 65536)
  sys.stdout = os.fdopen(1, 'w', 65536)
  runpy.run_path(sys.argv[0], run_name='__main__')
  '''
  
      unbuffered_loader_script = '''\
  import runpy, sys
  del sys.argv[0]
  runpy.run_path(sys.argv[0], run_name='__main__')
  '''
      address_grace = 131072
      ext = 'py'
  
      def get_cmdline(self):
          # -B: Don't write .pyc/.pyo, since sandbox will kill those writes
          # -S: Disable site module for speed (no loading dist-packages nor site-packages)
          return [self.get_command(), '-BS' + ('u' if self.unbuffered else ''), self._loader, self._code]
  
      def create_files(self, problem_id, source_code):
          self._loader = self._file('-loader.py')
          with open(self._code, 'wb') as fo, open(self._loader, 'w') as loader:
              # We want source code to be UTF-8, but the normal (Python 2) way of having
              # "# -*- coding: utf-8 -*-" in header changes line numbers, so we write
              # UTF-8 BOM instead.
              fo.write(b'\xef\xbb\xbf')
              fo.write(utf8bytes(source_code))
              loader.write(self.unbuffered_loader_script if self.unbuffered else self.loader_script)
  
      def get_feedback(self, stderr, result, process):
          if not result.result_flag & Result.IR or not stderr or len(stderr) > 2048:
              return ''
          match = deque(retraceback.finditer(utf8text(stderr, 'replace')), maxlen=1)
          if not match:
              return ''
          exception = match[0].group(1)
          return '' if len(exception) > 20 else exception
  
      @classmethod
      def get_version_flags(cls, command):
          return ['-V']
  
new_contents: import re
  from collections import deque
  
  from dmoj.executors.compiled_executor import CompiledExecutor
  from dmoj.executors.mixins import ScriptDirectoryMixin
  from dmoj.result import Result
  from dmoj.utils.unicode import utf8bytes, utf8text
  
  retraceback = re.compile(r'Traceback \(most recent call last\):\n.*?\n([a-zA-Z_]\w*)(?::[^\n]*?)?$', re.S | re.M)
  
  
  class PythonExecutor(ScriptDirectoryMixin, CompiledExecutor):
      loader_script = '''\
  import runpy, sys, os
  del sys.argv[0]
  sys.stdin = os.fdopen(0, 'r', 65536)
  sys.stdout = os.fdopen(1, 'w', 65536)
  runpy.run_path(sys.argv[0], run_name='__main__')
  '''
  
      unbuffered_loader_script = '''\
  import runpy, sys
  del sys.argv[0]
  runpy.run_path(sys.argv[0], run_name='__main__')
  '''
      address_grace = 131072
      ext = 'py'
  
      def get_compile_args(self):
          return [self.get_command(), '-m', 'compileall', '-q', self._dir]
  
      def get_cmdline(self):
          # -B: Don't write .pyc/.pyo, since sandbox will kill those writes
          # -S: Disable site module for speed (no loading dist-packages nor site-packages)
          return [self.get_command(), '-BS' + ('u' if self.unbuffered else ''), self._loader, self._code]
  
      def get_executable(self):
          return self.get_command()
  
      def create_files(self, problem_id, source_code, **kwargs):
          super().create_files(problem_id, source_code, **kwargs)
          self._loader = self._file('-loader.py')
          with open(self._code, 'wb') as fo, open(self._loader, 'w') as loader:
              # We want source code to be UTF-8, but the normal (Python 2) way of having
              # "# -*- coding: utf-8 -*-" in header changes line numbers, so we write
              # UTF-8 BOM instead.
              fo.write(b'\xef\xbb\xbf')
              fo.write(utf8bytes(source_code))
              loader.write(self.unbuffered_loader_script if self.unbuffered else self.loader_script)
  
      def get_feedback(self, stderr, result, process):
          if not result.result_flag & Result.IR or not stderr or len(stderr) > 2048:
              return ''
          match = deque(retraceback.finditer(utf8text(stderr, 'replace')), maxlen=1)
          if not match:
              return ''
          exception = match[0].group(1)
          return '' if len(exception) > 20 else exception
  
      @classmethod
      def get_version_flags(cls, command):
          return ['-V']
  
subject: Use py_compile in Python executor