prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Module import fails when auto_reload is active
  I have two piece of code (the structure has been simplified for clarity sake)
  First in base.py
  ```
  #! /usr/bin/env python
  # -*- coding: utf-8 -*-
  # module: init0
  
  from abc   import ABCMeta
  from sanic import Sanic
  
  class BaseService( metaclass = ABCMeta ):
      def create_app( self ) -> Sanic:
          app = Sanic( __name__ )
          return app
  
  # app = BaseService().create_app()
  
  # app.run( host  = '0.0.0.0',
  #      port  = 5000,
  #      debug = True,
  #     )
  
  print('[DONE]')
  
  ```
  Second in run_test.py
  ```
  #! /usr/bin/env python
  # -*- coding: utf-8 -*-
  # module: init0
  
  from init0.base import BaseService
  
  def main():
      app = BaseService().create_app()
      app.run( host  = '0.0.0.0',
           port  = 5000,
           debug = True,
          )
      return
  
  if __name__ == '__main__':
      main()
  
  ```
  
  If I were to run `python -m init0.run_test` with `debug = False` then everything works perfectly, however if it's `debug = True`, then it'd throw me `ModuleNotFoundError: No module named 'init0'`
  
  Is it some sort of loading error somewhere that I need to configure beforehand?
  
  Thanks a lot in advance
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `sanic/reloader_helpers.py`
  Content:
  ```
  1 import os
  2 import signal
  3 import subprocess
  4 import sys
  5 
  6 from multiprocessing import Process
  7 from time import sleep
  8 
  9 
  10 def _iter_module_files():
  11     """This iterates over all relevant Python files.
  12 
  13     It goes through all
  14     loaded files from modules, all files in folders of already loaded modules
  15     as well as all files reachable through a package.
  16     """
  17     # The list call is necessary on Python 3 in case the module
  18     # dictionary modifies during iteration.
  19     for module in list(sys.modules.values()):
  20         if module is None:
  21             continue
  22         filename = getattr(module, "__file__", None)
  23         if filename:
  24             old = None
  25             while not os.path.isfile(filename):
  26                 old = filename
  27                 filename = os.path.dirname(filename)
  28                 if filename == old:
  29                     break
  30             else:
  31                 if filename[-4:] in (".pyc", ".pyo"):
  32                     filename = filename[:-1]
  33                 yield filename
  34 
  35 
  36 def _get_args_for_reloading():
  37     """Returns the executable."""
  38     rv = [sys.executable]
  39     rv.extend(sys.argv)
  40     return rv
  41 
  42 
  43 def restart_with_reloader():
  44     """Create a new process and a subprocess in it with the same arguments as
  45     this one.
  46     """
  47     args = _get_args_for_reloading()
  48     new_environ = os.environ.copy()
  49     new_environ["SANIC_SERVER_RUNNING"] = "true"
  50     cmd = " ".join(args)
  51     worker_process = Process(
  52         target=subprocess.call,
  53         args=(cmd,),
  54         kwargs=dict(shell=True, env=new_environ),
  55     )
  56     worker_process.start()
  57     return worker_process
  58 
  59 
  60 def kill_process_children_unix(pid):
  61     """Find and kill child processes of a process (maximum two level).
  62 
  63     :param pid: PID of parent process (process ID)
  64     :return: Nothing
  65     """
  66     root_process_path = "/proc/{pid}/task/{pid}/children".format(pid=pid)
  67     if not os.path.isfile(root_process_path):
  68         return
  69     with open(root_process_path) as children_list_file:
  70         children_list_pid = children_list_file.read().split()
  71 
  72     for child_pid in children_list_pid:
  73         children_proc_path = "/proc/%s/task/%s/children" % (
  74             child_pid,
  75             child_pid,
  76         )
  77         if not os.path.isfile(children_proc_path):
  78             continue
  79         with open(children_proc_path) as children_list_file_2:
  80             children_list_pid_2 = children_list_file_2.read().split()
  81         for _pid in children_list_pid_2:
  82             try:
  83                 os.kill(int(_pid), signal.SIGTERM)
  84             except ProcessLookupError:
  85                 continue
  86         try:
  87             os.kill(int(child_pid), signal.SIGTERM)
  88         except ProcessLookupError:
  89             continue
  90 
  91 
  92 def kill_process_children_osx(pid):
  93     """Find and kill child processes of a process.
  94 
  95     :param pid: PID of parent process (process ID)
  96     :return: Nothing
  97     """
  98     subprocess.run(["pkill", "-P", str(pid)])
  99 
  100 
  101 def kill_process_children(pid):
  102     """Find and kill child processes of a process.
  103 
  104     :param pid: PID of parent process (process ID)
  105     :return: Nothing
  106     """
  107     if sys.platform == "darwin":
  108         kill_process_children_osx(pid)
  109     elif sys.platform == "linux":
  110         kill_process_children_unix(pid)
  111     else:
  112         pass  # should signal error here
  113 
  114 
  115 def kill_program_completly(proc):
  116     """Kill worker and it's child processes and exit.
  117 
  118     :param proc: worker process (process ID)
  119     :return: Nothing
  120     """
  121     kill_process_children(proc.pid)
  122     proc.terminate()
  123     os._exit(0)
  124 
  125 
  126 def watchdog(sleep_interval):
  127     """Watch project files, restart worker process if a change happened.
  128 
  129     :param sleep_interval: interval in second.
  130     :return: Nothing
  131     """
  132     mtimes = {}
  133     worker_process = restart_with_reloader()
  134     signal.signal(
  135         signal.SIGTERM, lambda *args: kill_program_completly(worker_process)
  136     )
  137     signal.signal(
  138         signal.SIGINT, lambda *args: kill_program_completly(worker_process)
  139     )
  140     while True:
  141         for filename in _iter_module_files():
  142             try:
  143                 mtime = os.stat(filename).st_mtime
  144             except OSError:
  145                 continue
  146 
  147             old_time = mtimes.get(filename)
  148             if old_time is None:
  149                 mtimes[filename] = mtime
  150                 continue
  151             elif mtime > old_time:
  152                 kill_process_children(worker_process.pid)
  153                 worker_process.terminate()
  154                 worker_process = restart_with_reloader()
  155                 mtimes[filename] = mtime
  156                 break
  157 
  158         sleep(sleep_interval)
  159
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/sanic/reloader_helpers.py b/sanic/reloader_helpers.py
  --- a/sanic/reloader_helpers.py
  +++ b/sanic/reloader_helpers.py
  @@ -36,7 +36,15 @@
   def _get_args_for_reloading():
       """Returns the executable."""
       rv = [sys.executable]
  -    rv.extend(sys.argv)
  +    main_module = sys.modules["__main__"]
  +    mod_spec = getattr(main_module, "__spec__", None)
  +    if mod_spec:
  +        # Parent exe was launched as a module rather than a script
  +        rv.extend(["-m", mod_spec.name])
  +        if len(sys.argv) > 1:
  +            rv.extend(sys.argv[1:])
  +    else:
  +        rv.extend(sys.argv)
       return rv
   
   
  @@ -44,6 +52,7 @@
       """Create a new process and a subprocess in it with the same arguments as
       this one.
       """
  +    cwd = os.getcwd()
       args = _get_args_for_reloading()
       new_environ = os.environ.copy()
       new_environ["SANIC_SERVER_RUNNING"] = "true"
  @@ -51,7 +60,7 @@
       worker_process = Process(
           target=subprocess.call,
           args=(cmd,),
  -        kwargs=dict(shell=True, env=new_environ),
  +        kwargs={"cwd": cwd, "shell": True, "env": new_environ},
       )
       worker_process.start()
       return worker_process
  
verification_info: {"golden_diff": "diff --git a/sanic/reloader_helpers.py b/sanic/reloader_helpers.py\n--- a/sanic/reloader_helpers.py\n+++ b/sanic/reloader_helpers.py\n@@ -36,7 +36,15 @@\n def _get_args_for_reloading():\n     \"\"\"Returns the executable.\"\"\"\n     rv = [sys.executable]\n-    rv.extend(sys.argv)\n+    main_module = sys.modules[\"__main__\"]\n+    mod_spec = getattr(main_module, \"__spec__\", None)\n+    if mod_spec:\n+        # Parent exe was launched as a module rather than a script\n+        rv.extend([\"-m\", mod_spec.name])\n+        if len(sys.argv) > 1:\n+            rv.extend(sys.argv[1:])\n+    else:\n+        rv.extend(sys.argv)\n     return rv\n \n \n@@ -44,6 +52,7 @@\n     \"\"\"Create a new process and a subprocess in it with the same arguments as\n     this one.\n     \"\"\"\n+    cwd = os.getcwd()\n     args = _get_args_for_reloading()\n     new_environ = os.environ.copy()\n     new_environ[\"SANIC_SERVER_RUNNING\"] = \"true\"\n@@ -51,7 +60,7 @@\n     worker_process = Process(\n         target=subprocess.call,\n         args=(cmd,),\n-        kwargs=dict(shell=True, env=new_environ),\n+        kwargs={\"cwd\": cwd, \"shell\": True, \"env\": new_environ},\n     )\n     worker_process.start()\n     return worker_process\n", "issue": "Module import fails when auto_reload is active\nI have two piece of code (the structure has been simplified for clarity sake)\r\nFirst in base.py\r\n```\r\n#! /usr/bin/env python\r\n# -*- coding: utf-8 -*-\r\n# module: init0\r\n\r\nfrom abc   import ABCMeta\r\nfrom sanic import Sanic\r\n\r\nclass BaseService( metaclass = ABCMeta ):\r\n    def create_app( self ) -> Sanic:\r\n        app = Sanic( __name__ )\r\n        return app\r\n\r\n# app = BaseService().create_app()\r\n\r\n# app.run( host  = '0.0.0.0',\r\n#      port  = 5000,\r\n#      debug = True,\r\n#     )\r\n\r\nprint('[DONE]')\r\n\r\n```\r\nSecond in run_test.py\r\n```\r\n#! /usr/bin/env python\r\n# -*- coding: utf-8 -*-\r\n# module: init0\r\n\r\nfrom init0.base import BaseService\r\n\r\ndef main():\r\n    app = BaseService().create_app()\r\n    app.run( host  = '0.0.0.0',\r\n         port  = 5000,\r\n         debug = True,\r\n        )\r\n    return\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n\r\n```\r\n\r\nIf I were to run `python -m init0.run_test` with `debug = False` then everything works perfectly, however if it's `debug = True`, then it'd throw me `ModuleNotFoundError: No module named 'init0'`\r\n\r\nIs it some sort of loading error somewhere that I need to configure beforehand?\r\n\r\nThanks a lot in advance\n", "before_files": [{"content": "import os\nimport signal\nimport subprocess\nimport sys\n\nfrom multiprocessing import Process\nfrom time import sleep\n\n\ndef _iter_module_files():\n    \"\"\"This iterates over all relevant Python files.\n\n    It goes through all\n    loaded files from modules, all files in folders of already loaded modules\n    as well as all files reachable through a package.\n    \"\"\"\n    # The list call is necessary on Python 3 in case the module\n    # dictionary modifies during iteration.\n    for module in list(sys.modules.values()):\n        if module is None:\n            continue\n        filename = getattr(module, \"__file__\", None)\n        if filename:\n            old = None\n            while not os.path.isfile(filename):\n                old = filename\n                filename = os.path.dirname(filename)\n                if filename == old:\n                    break\n            else:\n                if filename[-4:] in (\".pyc\", \".pyo\"):\n                    filename = filename[:-1]\n                yield filename\n\n\ndef _get_args_for_reloading():\n    \"\"\"Returns the executable.\"\"\"\n    rv = [sys.executable]\n    rv.extend(sys.argv)\n    return rv\n\n\ndef restart_with_reloader():\n    \"\"\"Create a new process and a subprocess in it with the same arguments as\n    this one.\n    \"\"\"\n    args = _get_args_for_reloading()\n    new_environ = os.environ.copy()\n    new_environ[\"SANIC_SERVER_RUNNING\"] = \"true\"\n    cmd = \" \".join(args)\n    worker_process = Process(\n        target=subprocess.call,\n        args=(cmd,),\n        kwargs=dict(shell=True, env=new_environ),\n    )\n    worker_process.start()\n    return worker_process\n\n\ndef kill_process_children_unix(pid):\n    \"\"\"Find and kill child processes of a process (maximum two level).\n\n    :param pid: PID of parent process (process ID)\n    :return: Nothing\n    \"\"\"\n    root_process_path = \"/proc/{pid}/task/{pid}/children\".format(pid=pid)\n    if not os.path.isfile(root_process_path):\n        return\n    with open(root_process_path) as children_list_file:\n        children_list_pid = children_list_file.read().split()\n\n    for child_pid in children_list_pid:\n        children_proc_path = \"/proc/%s/task/%s/children\" % (\n            child_pid,\n            child_pid,\n        )\n        if not os.path.isfile(children_proc_path):\n            continue\n        with open(children_proc_path) as children_list_file_2:\n            children_list_pid_2 = children_list_file_2.read().split()\n        for _pid in children_list_pid_2:\n            try:\n                os.kill(int(_pid), signal.SIGTERM)\n            except ProcessLookupError:\n                continue\n        try:\n            os.kill(int(child_pid), signal.SIGTERM)\n        except ProcessLookupError:\n            continue\n\n\ndef kill_process_children_osx(pid):\n    \"\"\"Find and kill child processes of a process.\n\n    :param pid: PID of parent process (process ID)\n    :return: Nothing\n    \"\"\"\n    subprocess.run([\"pkill\", \"-P\", str(pid)])\n\n\ndef kill_process_children(pid):\n    \"\"\"Find and kill child processes of a process.\n\n    :param pid: PID of parent process (process ID)\n    :return: Nothing\n    \"\"\"\n    if sys.platform == \"darwin\":\n        kill_process_children_osx(pid)\n    elif sys.platform == \"linux\":\n        kill_process_children_unix(pid)\n    else:\n        pass  # should signal error here\n\n\ndef kill_program_completly(proc):\n    \"\"\"Kill worker and it's child processes and exit.\n\n    :param proc: worker process (process ID)\n    :return: Nothing\n    \"\"\"\n    kill_process_children(proc.pid)\n    proc.terminate()\n    os._exit(0)\n\n\ndef watchdog(sleep_interval):\n    \"\"\"Watch project files, restart worker process if a change happened.\n\n    :param sleep_interval: interval in second.\n    :return: Nothing\n    \"\"\"\n    mtimes = {}\n    worker_process = restart_with_reloader()\n    signal.signal(\n        signal.SIGTERM, lambda *args: kill_program_completly(worker_process)\n    )\n    signal.signal(\n        signal.SIGINT, lambda *args: kill_program_completly(worker_process)\n    )\n    while True:\n        for filename in _iter_module_files():\n            try:\n                mtime = os.stat(filename).st_mtime\n            except OSError:\n                continue\n\n            old_time = mtimes.get(filename)\n            if old_time is None:\n                mtimes[filename] = mtime\n                continue\n            elif mtime > old_time:\n                kill_process_children(worker_process.pid)\n                worker_process.terminate()\n                worker_process = restart_with_reloader()\n                mtimes[filename] = mtime\n                break\n\n        sleep(sleep_interval)\n", "path": "sanic/reloader_helpers.py"}], "after_files": [{"content": "import os\nimport signal\nimport subprocess\nimport sys\n\nfrom multiprocessing import Process\nfrom time import sleep\n\n\ndef _iter_module_files():\n    \"\"\"This iterates over all relevant Python files.\n\n    It goes through all\n    loaded files from modules, all files in folders of already loaded modules\n    as well as all files reachable through a package.\n    \"\"\"\n    # The list call is necessary on Python 3 in case the module\n    # dictionary modifies during iteration.\n    for module in list(sys.modules.values()):\n        if module is None:\n            continue\n        filename = getattr(module, \"__file__\", None)\n        if filename:\n            old = None\n            while not os.path.isfile(filename):\n                old = filename\n                filename = os.path.dirname(filename)\n                if filename == old:\n                    break\n            else:\n                if filename[-4:] in (\".pyc\", \".pyo\"):\n                    filename = filename[:-1]\n                yield filename\n\n\ndef _get_args_for_reloading():\n    \"\"\"Returns the executable.\"\"\"\n    rv = [sys.executable]\n    main_module = sys.modules[\"__main__\"]\n    mod_spec = getattr(main_module, \"__spec__\", None)\n    if mod_spec:\n        # Parent exe was launched as a module rather than a script\n        rv.extend([\"-m\", mod_spec.name])\n        if len(sys.argv) > 1:\n            rv.extend(sys.argv[1:])\n    else:\n        rv.extend(sys.argv)\n    return rv\n\n\ndef restart_with_reloader():\n    \"\"\"Create a new process and a subprocess in it with the same arguments as\n    this one.\n    \"\"\"\n    cwd = os.getcwd()\n    args = _get_args_for_reloading()\n    new_environ = os.environ.copy()\n    new_environ[\"SANIC_SERVER_RUNNING\"] = \"true\"\n    cmd = \" \".join(args)\n    worker_process = Process(\n        target=subprocess.call,\n        args=(cmd,),\n        kwargs={\"cwd\": cwd, \"shell\": True, \"env\": new_environ},\n    )\n    worker_process.start()\n    return worker_process\n\n\ndef kill_process_children_unix(pid):\n    \"\"\"Find and kill child processes of a process (maximum two level).\n\n    :param pid: PID of parent process (process ID)\n    :return: Nothing\n    \"\"\"\n    root_process_path = \"/proc/{pid}/task/{pid}/children\".format(pid=pid)\n    if not os.path.isfile(root_process_path):\n        return\n    with open(root_process_path) as children_list_file:\n        children_list_pid = children_list_file.read().split()\n\n    for child_pid in children_list_pid:\n        children_proc_path = \"/proc/%s/task/%s/children\" % (\n            child_pid,\n            child_pid,\n        )\n        if not os.path.isfile(children_proc_path):\n            continue\n        with open(children_proc_path) as children_list_file_2:\n            children_list_pid_2 = children_list_file_2.read().split()\n        for _pid in children_list_pid_2:\n            try:\n                os.kill(int(_pid), signal.SIGTERM)\n            except ProcessLookupError:\n                continue\n        try:\n            os.kill(int(child_pid), signal.SIGTERM)\n        except ProcessLookupError:\n            continue\n\n\ndef kill_process_children_osx(pid):\n    \"\"\"Find and kill child processes of a process.\n\n    :param pid: PID of parent process (process ID)\n    :return: Nothing\n    \"\"\"\n    subprocess.run([\"pkill\", \"-P\", str(pid)])\n\n\ndef kill_process_children(pid):\n    \"\"\"Find and kill child processes of a process.\n\n    :param pid: PID of parent process (process ID)\n    :return: Nothing\n    \"\"\"\n    if sys.platform == \"darwin\":\n        kill_process_children_osx(pid)\n    elif sys.platform == \"linux\":\n        kill_process_children_unix(pid)\n    else:\n        pass  # should signal error here\n\n\ndef kill_program_completly(proc):\n    \"\"\"Kill worker and it's child processes and exit.\n\n    :param proc: worker process (process ID)\n    :return: Nothing\n    \"\"\"\n    kill_process_children(proc.pid)\n    proc.terminate()\n    os._exit(0)\n\n\ndef watchdog(sleep_interval):\n    \"\"\"Watch project files, restart worker process if a change happened.\n\n    :param sleep_interval: interval in second.\n    :return: Nothing\n    \"\"\"\n    mtimes = {}\n    worker_process = restart_with_reloader()\n    signal.signal(\n        signal.SIGTERM, lambda *args: kill_program_completly(worker_process)\n    )\n    signal.signal(\n        signal.SIGINT, lambda *args: kill_program_completly(worker_process)\n    )\n    while True:\n        for filename in _iter_module_files():\n            try:\n                mtime = os.stat(filename).st_mtime\n            except OSError:\n                continue\n\n            old_time = mtimes.get(filename)\n            if old_time is None:\n                mtimes[filename] = mtime\n                continue\n            elif mtime > old_time:\n                kill_process_children(worker_process.pid)\n                worker_process.terminate()\n                worker_process = restart_with_reloader()\n                mtimes[filename] = mtime\n                break\n\n        sleep(sleep_interval)\n", "path": "sanic/reloader_helpers.py"}]}