old_contents: import importlib
  import os
  import re
  import subprocess
  
  import sourcer
  
  
  project_home = os.path.dirname(__file__)
  
  
  def generate_meta_module(description):
      grammar = sourcer.Grammar(description, include_source=True)
  
      # Make sure that the grammar describes itself.
      assert grammar.parse(description)
  
      # Save our current code for meta.py.
      with open('sourcer/meta.py', 'r') as f:
          was = f.read()
  
      # Replace it with our new code.
      with open('sourcer/meta.py', 'w') as f:
          f.write(f'# Generated by ../{os.path.basename(__file__)}\n')
          f.write(grammar._source_code)
  
      # Reload sourcer to load the new code.
      importlib.reload(sourcer)
  
      # Try parsing the description again, this time using the new code. Then try
      # running the tests.
      try:
          new_grammar = sourcer.Grammar(description, include_source=True)
          assert new_grammar.parse(description)
          subprocess.run('python -m pytest tests', shell=True, check=True)
      except Exception:
          # If we failed, restore the old code and re-raise the exception.
          with open('sourcer/meta.py', 'w') as f:
              f.write(was)
          raise
  
  
  def update_metasyntax_example(description):
      print('Updating metasyntax example.')
      path = os.path.join(project_home, 'docs', 'examples', 'metasyntax.md')
  
      with open(path) as f:
          contents = f.read()
  
      section = '~~~\n' + description.strip().replace('\\', '\\\\') + '\n~~~'
      contents = re.sub('~~~(.|\n)*?~~~', section, contents)
  
      with open(path, 'w') as f:
          f.write(contents)
  
  
  def read_metasyntax():
      with open(os.path.join(project_home, 'metasyntax.txt')) as f:
          return f.read()
  
  
  def run(description):
      generate_meta_module(description)
      update_metasyntax_example(description)
  
  
  if __name__ == '__main__':
      run(read_metasyntax())
  
new_contents: import importlib
  import os
  import re
  import subprocess
  import sys
  
  import sourcer
  
  
  project_home = os.path.dirname(__file__)
  
  
  def generate_meta_module(description):
      grammar = sourcer.Grammar(description, include_source=True)
  
      # Make sure that the grammar describes itself.
      assert grammar.parse(description)
  
      # Save our current code for meta.py.
      with open('sourcer/meta.py', 'r') as f:
          was = f.read()
  
      # Replace it with our new code.
      with open('sourcer/meta.py', 'w') as f:
          f.write(f'# Generated by ../{os.path.basename(__file__)}\n')
          f.write(grammar._source_code)
  
      # Reload sourcer to load the new code.
      importlib.reload(sourcer)
  
      # Try parsing the description again, this time using the new code. Then try
      # running the tests.
      try:
          new_grammar = sourcer.Grammar(description, include_source=True)
          assert new_grammar.parse(description)
          subprocess.run(f'{sys.executable} -m pytest tests', shell=True, check=True)
      except Exception:
          # If we failed, restore the old code and re-raise the exception.
          with open('sourcer/meta.py', 'w') as f:
              f.write(was)
          raise
  
  
  def update_metasyntax_example(description):
      print('Updating metasyntax example.')
      path = os.path.join(project_home, 'docs', 'examples', 'metasyntax.md')
  
      with open(path) as f:
          contents = f.read()
  
      section = '~~~\n' + description.strip().replace('\\', '\\\\') + '\n~~~'
      contents = re.sub('~~~(.|\n)*?~~~', section, contents)
  
      with open(path, 'w') as f:
          f.write(contents)
  
  
  def read_metasyntax():
      with open(os.path.join(project_home, 'metasyntax.txt')) as f:
          return f.read()
  
  
  def run(description):
      generate_meta_module(description)
      update_metasyntax_example(description)
  
  
  if __name__ == '__main__':
      run(read_metasyntax())
  
subject: Use current executable.