prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  With no scene specified on CLI, manim gives false choice.
  I was running the command:
  `manim -pl --media_dir ~/renderings ~/dev/manim/example_scenes/basic.py ` 
  and was greeted by this:
  ```
  
  [19:29:42] INFO     Read configuration files:                                                                      config.py:416
                      ['/home/cobordism/.local/lib/python3.8/site-packages/manim/default.cfg']                                    
  1: GraphScene
  2: LinearTransformationScene
  3: MovingCameraScene
  4: OpeningManimExample
  5: ReconfigurableScene
  6: SampleSpaceScene
  7: SpecialThreeDScene
  8: SquareToCircle
  9: ThreeDScene
  10: UpdatersExample
  11: VectorScene
  12: WarpSquare
  13: WriteStuff
  14: ZoomedScene
  
  Choose number corresponding to desired scene/arguments.
  (Use comma separated list for multiple entries)
  Choice(s): 
  
  ```
  
  Clearly something is wonky here The choices should have been only the scenes from basic.py.
  i.e. OpeningManimExample, SquareToCircle, WarpSquare, WriteStuff, UpdatersExample.
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `manim/__main__.py`
  Content:
  ```
  1 import inspect
  2 import os
  3 import platform
  4 import subprocess as sp
  5 import sys
  6 import re
  7 import traceback
  8 import importlib.util
  9 
  10 from .config import file_writer_config
  11 from .scene.scene import Scene
  12 from .utils.sounds import play_error_sound
  13 from .utils.sounds import play_finish_sound
  14 from . import constants
  15 from .logger import logger
  16 
  17 
  18 def open_file_if_needed(file_writer):
  19     if file_writer_config["quiet"]:
  20         curr_stdout = sys.stdout
  21         sys.stdout = open(os.devnull, "w")
  22 
  23     open_file = any([
  24         file_writer_config["preview"],
  25         file_writer_config["show_file_in_finder"]
  26     ])
  27     if open_file:
  28         current_os = platform.system()
  29         file_paths = []
  30 
  31         if file_writer_config["save_last_frame"]:
  32             file_paths.append(file_writer.get_image_file_path())
  33         if file_writer_config["write_to_movie"]:
  34             file_paths.append(file_writer.get_movie_file_path())
  35 
  36         for file_path in file_paths:
  37             if current_os == "Windows":
  38                 os.startfile(file_path)
  39             else:
  40                 commands = []
  41                 if current_os == "Linux":
  42                     commands.append("xdg-open")
  43                 elif current_os.startswith("CYGWIN"):
  44                     commands.append("cygstart")
  45                 else:  # Assume macOS
  46                     commands.append("open")
  47 
  48                 if file_writer_config["show_file_in_finder"]:
  49                     commands.append("-R")
  50 
  51                 commands.append(file_path)
  52 
  53                 # commands.append("-g")
  54                 FNULL = open(os.devnull, 'w')
  55                 sp.call(commands, stdout=FNULL, stderr=sp.STDOUT)
  56                 FNULL.close()
  57 
  58     if file_writer_config["quiet"]:
  59         sys.stdout.close()
  60         sys.stdout = curr_stdout
  61 
  62 
  63 def is_child_scene(obj, module):
  64     return (inspect.isclass(obj)
  65             and issubclass(obj, Scene)
  66             and obj != Scene
  67             and obj.__module__.startswith(module.__name__))
  68 
  69 
  70 def prompt_user_for_choice(scene_classes):
  71     num_to_class = {}
  72     for count, scene_class in enumerate(scene_classes):
  73         count += 1  # start with 1 instead of 0
  74         name = scene_class.__name__
  75         print("%d: %s" % (count, name))
  76         num_to_class[count] = scene_class
  77     try:
  78         user_input = input(constants.CHOOSE_NUMBER_MESSAGE)
  79         return [num_to_class[int(num_str)]
  80                 for num_str in re.split(r"\s*,\s*", user_input.strip())]
  81     except KeyError:
  82         logger.error(constants.INVALID_NUMBER_MESSAGE)
  83         sys.exit(2)
  84     except EOFError:
  85         sys.exit(1)
  86 
  87 
  88 def get_scenes_to_render(scene_classes):
  89     if not scene_classes:
  90         logger.error(constants.NO_SCENE_MESSAGE)
  91         return []
  92     if file_writer_config["write_all"]:
  93         return scene_classes
  94     result = []
  95     for scene_name in file_writer_config["scene_names"]:
  96         found = False
  97         for scene_class in scene_classes:
  98             if scene_class.__name__ == scene_name:
  99                 result.append(scene_class)
  100                 found = True
  101                 break
  102         if not found and (scene_name != ""):
  103             logger.error(
  104                 constants.SCENE_NOT_FOUND_MESSAGE.format(
  105                     scene_name
  106                 )
  107             )
  108     if result:
  109         return result
  110     return [scene_classes[0]] if len(scene_classes) == 1 else prompt_user_for_choice(scene_classes)
  111 
  112 
  113 def get_scene_classes_from_module(module):
  114     if hasattr(module, "SCENES_IN_ORDER"):
  115         return module.SCENES_IN_ORDER
  116     else:
  117         return [
  118             member[1]
  119             for member in inspect.getmembers(
  120                 module,
  121                 lambda x: is_child_scene(x, module)
  122             )
  123         ]
  124 
  125 
  126 def get_module(file_name):
  127     if file_name == "-":
  128         module = types.ModuleType("input_scenes")
  129         code = sys.stdin.read()
  130         try:
  131             exec(code, module.__dict__)
  132             return module
  133         except Exception as e:
  134             logger.error(f"Failed to render scene: {str(e)}")
  135             sys.exit(2)
  136     else:
  137         if os.path.exists(file_name):
  138             module_name = re.sub(r"\..+$", "", file_name.replace(os.sep, "."))
  139             spec = importlib.util.spec_from_file_location(module_name, file_name)
  140             module = importlib.util.module_from_spec(spec)
  141             spec.loader.exec_module(module)
  142             return module
  143         else:
  144             raise FileNotFoundError(f'{file_name} not found')
  145 
  146 
  147 def main():
  148     module = get_module(file_writer_config["input_file"])
  149     all_scene_classes = get_scene_classes_from_module(module)
  150     scene_classes_to_render = get_scenes_to_render(all_scene_classes)
  151     sound_on = file_writer_config["sound"]
  152     for SceneClass in scene_classes_to_render:
  153         try:
  154             # By invoking, this renders the full scene
  155             scene = SceneClass()
  156             open_file_if_needed(scene.file_writer)
  157             if sound_on:
  158                 play_finish_sound()
  159         except Exception:
  160             print("\n\n")
  161             traceback.print_exc()
  162             print("\n\n")
  163             if sound_on:
  164                 play_error_sound()
  165 
  166 
  167 if __name__ == "__main__":
  168     main()
  169
  ```
  --- 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/manim/__main__.py b/manim/__main__.py
  --- a/manim/__main__.py
  +++ b/manim/__main__.py
  @@ -135,7 +135,9 @@
               sys.exit(2)
       else:
           if os.path.exists(file_name):
  -            module_name = re.sub(r"\..+$", "", file_name.replace(os.sep, "."))
  +            if file_name[-3:] != ".py":
  +                raise Exception(f"{file_name} is not a valid Manim python script.")
  +            module_name = file_name[:-3].replace(os.sep, '.').split('.')[-1]
               spec = importlib.util.spec_from_file_location(module_name, file_name)
               module = importlib.util.module_from_spec(spec)
               spec.loader.exec_module(module)
  
verification_info: {"golden_diff": "diff --git a/manim/__main__.py b/manim/__main__.py\n--- a/manim/__main__.py\n+++ b/manim/__main__.py\n@@ -135,7 +135,9 @@\n             sys.exit(2)\n     else:\n         if os.path.exists(file_name):\n-            module_name = re.sub(r\"\\..+$\", \"\", file_name.replace(os.sep, \".\"))\n+            if file_name[-3:] != \".py\":\n+                raise Exception(f\"{file_name} is not a valid Manim python script.\")\n+            module_name = file_name[:-3].replace(os.sep, '.').split('.')[-1]\n             spec = importlib.util.spec_from_file_location(module_name, file_name)\n             module = importlib.util.module_from_spec(spec)\n             spec.loader.exec_module(module)\n", "issue": "With no scene specified on CLI, manim gives false choice.\nI was running the command:\r\n`manim -pl --media_dir ~/renderings ~/dev/manim/example_scenes/basic.py ` \r\nand was greeted by this:\r\n```\r\n\r\n[19:29:42] INFO     Read configuration files:                                                                      config.py:416\r\n                    ['/home/cobordism/.local/lib/python3.8/site-packages/manim/default.cfg']                                    \r\n1: GraphScene\r\n2: LinearTransformationScene\r\n3: MovingCameraScene\r\n4: OpeningManimExample\r\n5: ReconfigurableScene\r\n6: SampleSpaceScene\r\n7: SpecialThreeDScene\r\n8: SquareToCircle\r\n9: ThreeDScene\r\n10: UpdatersExample\r\n11: VectorScene\r\n12: WarpSquare\r\n13: WriteStuff\r\n14: ZoomedScene\r\n\r\nChoose number corresponding to desired scene/arguments.\r\n(Use comma separated list for multiple entries)\r\nChoice(s): \r\n\r\n```\r\n\r\nClearly something is wonky here The choices should have been only the scenes from basic.py.\r\ni.e. OpeningManimExample, SquareToCircle, WarpSquare, WriteStuff, UpdatersExample.\r\n\r\n\n", "before_files": [{"content": "import inspect\nimport os\nimport platform\nimport subprocess as sp\nimport sys\nimport re\nimport traceback\nimport importlib.util\n\nfrom .config import file_writer_config\nfrom .scene.scene import Scene\nfrom .utils.sounds import play_error_sound\nfrom .utils.sounds import play_finish_sound\nfrom . import constants\nfrom .logger import logger\n\n\ndef open_file_if_needed(file_writer):\n    if file_writer_config[\"quiet\"]:\n        curr_stdout = sys.stdout\n        sys.stdout = open(os.devnull, \"w\")\n\n    open_file = any([\n        file_writer_config[\"preview\"],\n        file_writer_config[\"show_file_in_finder\"]\n    ])\n    if open_file:\n        current_os = platform.system()\n        file_paths = []\n\n        if file_writer_config[\"save_last_frame\"]:\n            file_paths.append(file_writer.get_image_file_path())\n        if file_writer_config[\"write_to_movie\"]:\n            file_paths.append(file_writer.get_movie_file_path())\n\n        for file_path in file_paths:\n            if current_os == \"Windows\":\n                os.startfile(file_path)\n            else:\n                commands = []\n                if current_os == \"Linux\":\n                    commands.append(\"xdg-open\")\n                elif current_os.startswith(\"CYGWIN\"):\n                    commands.append(\"cygstart\")\n                else:  # Assume macOS\n                    commands.append(\"open\")\n\n                if file_writer_config[\"show_file_in_finder\"]:\n                    commands.append(\"-R\")\n\n                commands.append(file_path)\n\n                # commands.append(\"-g\")\n                FNULL = open(os.devnull, 'w')\n                sp.call(commands, stdout=FNULL, stderr=sp.STDOUT)\n                FNULL.close()\n\n    if file_writer_config[\"quiet\"]:\n        sys.stdout.close()\n        sys.stdout = curr_stdout\n\n\ndef is_child_scene(obj, module):\n    return (inspect.isclass(obj)\n            and issubclass(obj, Scene)\n            and obj != Scene\n            and obj.__module__.startswith(module.__name__))\n\n\ndef prompt_user_for_choice(scene_classes):\n    num_to_class = {}\n    for count, scene_class in enumerate(scene_classes):\n        count += 1  # start with 1 instead of 0\n        name = scene_class.__name__\n        print(\"%d: %s\" % (count, name))\n        num_to_class[count] = scene_class\n    try:\n        user_input = input(constants.CHOOSE_NUMBER_MESSAGE)\n        return [num_to_class[int(num_str)]\n                for num_str in re.split(r\"\\s*,\\s*\", user_input.strip())]\n    except KeyError:\n        logger.error(constants.INVALID_NUMBER_MESSAGE)\n        sys.exit(2)\n    except EOFError:\n        sys.exit(1)\n\n\ndef get_scenes_to_render(scene_classes):\n    if not scene_classes:\n        logger.error(constants.NO_SCENE_MESSAGE)\n        return []\n    if file_writer_config[\"write_all\"]:\n        return scene_classes\n    result = []\n    for scene_name in file_writer_config[\"scene_names\"]:\n        found = False\n        for scene_class in scene_classes:\n            if scene_class.__name__ == scene_name:\n                result.append(scene_class)\n                found = True\n                break\n        if not found and (scene_name != \"\"):\n            logger.error(\n                constants.SCENE_NOT_FOUND_MESSAGE.format(\n                    scene_name\n                )\n            )\n    if result:\n        return result\n    return [scene_classes[0]] if len(scene_classes) == 1 else prompt_user_for_choice(scene_classes)\n\n\ndef get_scene_classes_from_module(module):\n    if hasattr(module, \"SCENES_IN_ORDER\"):\n        return module.SCENES_IN_ORDER\n    else:\n        return [\n            member[1]\n            for member in inspect.getmembers(\n                module,\n                lambda x: is_child_scene(x, module)\n            )\n        ]\n\n\ndef get_module(file_name):\n    if file_name == \"-\":\n        module = types.ModuleType(\"input_scenes\")\n        code = sys.stdin.read()\n        try:\n            exec(code, module.__dict__)\n            return module\n        except Exception as e:\n            logger.error(f\"Failed to render scene: {str(e)}\")\n            sys.exit(2)\n    else:\n        if os.path.exists(file_name):\n            module_name = re.sub(r\"\\..+$\", \"\", file_name.replace(os.sep, \".\"))\n            spec = importlib.util.spec_from_file_location(module_name, file_name)\n            module = importlib.util.module_from_spec(spec)\n            spec.loader.exec_module(module)\n            return module\n        else:\n            raise FileNotFoundError(f'{file_name} not found')\n\n\ndef main():\n    module = get_module(file_writer_config[\"input_file\"])\n    all_scene_classes = get_scene_classes_from_module(module)\n    scene_classes_to_render = get_scenes_to_render(all_scene_classes)\n    sound_on = file_writer_config[\"sound\"]\n    for SceneClass in scene_classes_to_render:\n        try:\n            # By invoking, this renders the full scene\n            scene = SceneClass()\n            open_file_if_needed(scene.file_writer)\n            if sound_on:\n                play_finish_sound()\n        except Exception:\n            print(\"\\n\\n\")\n            traceback.print_exc()\n            print(\"\\n\\n\")\n            if sound_on:\n                play_error_sound()\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "manim/__main__.py"}], "after_files": [{"content": "import inspect\nimport os\nimport platform\nimport subprocess as sp\nimport sys\nimport re\nimport traceback\nimport importlib.util\n\nfrom .config import file_writer_config\nfrom .scene.scene import Scene\nfrom .utils.sounds import play_error_sound\nfrom .utils.sounds import play_finish_sound\nfrom . import constants\nfrom .logger import logger\n\n\ndef open_file_if_needed(file_writer):\n    if file_writer_config[\"quiet\"]:\n        curr_stdout = sys.stdout\n        sys.stdout = open(os.devnull, \"w\")\n\n    open_file = any([\n        file_writer_config[\"preview\"],\n        file_writer_config[\"show_file_in_finder\"]\n    ])\n    if open_file:\n        current_os = platform.system()\n        file_paths = []\n\n        if file_writer_config[\"save_last_frame\"]:\n            file_paths.append(file_writer.get_image_file_path())\n        if file_writer_config[\"write_to_movie\"]:\n            file_paths.append(file_writer.get_movie_file_path())\n\n        for file_path in file_paths:\n            if current_os == \"Windows\":\n                os.startfile(file_path)\n            else:\n                commands = []\n                if current_os == \"Linux\":\n                    commands.append(\"xdg-open\")\n                elif current_os.startswith(\"CYGWIN\"):\n                    commands.append(\"cygstart\")\n                else:  # Assume macOS\n                    commands.append(\"open\")\n\n                if file_writer_config[\"show_file_in_finder\"]:\n                    commands.append(\"-R\")\n\n                commands.append(file_path)\n\n                # commands.append(\"-g\")\n                FNULL = open(os.devnull, 'w')\n                sp.call(commands, stdout=FNULL, stderr=sp.STDOUT)\n                FNULL.close()\n\n    if file_writer_config[\"quiet\"]:\n        sys.stdout.close()\n        sys.stdout = curr_stdout\n\n\ndef is_child_scene(obj, module):\n    return (inspect.isclass(obj)\n            and issubclass(obj, Scene)\n            and obj != Scene\n            and obj.__module__.startswith(module.__name__))\n\n\ndef prompt_user_for_choice(scene_classes):\n    num_to_class = {}\n    for count, scene_class in enumerate(scene_classes):\n        count += 1  # start with 1 instead of 0\n        name = scene_class.__name__\n        print(\"%d: %s\" % (count, name))\n        num_to_class[count] = scene_class\n    try:\n        user_input = input(constants.CHOOSE_NUMBER_MESSAGE)\n        return [num_to_class[int(num_str)]\n                for num_str in re.split(r\"\\s*,\\s*\", user_input.strip())]\n    except KeyError:\n        logger.error(constants.INVALID_NUMBER_MESSAGE)\n        sys.exit(2)\n    except EOFError:\n        sys.exit(1)\n\n\ndef get_scenes_to_render(scene_classes):\n    if not scene_classes:\n        logger.error(constants.NO_SCENE_MESSAGE)\n        return []\n    if file_writer_config[\"write_all\"]:\n        return scene_classes\n    result = []\n    for scene_name in file_writer_config[\"scene_names\"]:\n        found = False\n        for scene_class in scene_classes:\n            if scene_class.__name__ == scene_name:\n                result.append(scene_class)\n                found = True\n                break\n        if not found and (scene_name != \"\"):\n            logger.error(\n                constants.SCENE_NOT_FOUND_MESSAGE.format(\n                    scene_name\n                )\n            )\n    if result:\n        return result\n    return [scene_classes[0]] if len(scene_classes) == 1 else prompt_user_for_choice(scene_classes)\n\n\ndef get_scene_classes_from_module(module):\n    if hasattr(module, \"SCENES_IN_ORDER\"):\n        return module.SCENES_IN_ORDER\n    else:\n        return [\n            member[1]\n            for member in inspect.getmembers(\n                module,\n                lambda x: is_child_scene(x, module)\n            )\n        ]\n\n\ndef get_module(file_name):\n    if file_name == \"-\":\n        module = types.ModuleType(\"input_scenes\")\n        code = sys.stdin.read()\n        try:\n            exec(code, module.__dict__)\n            return module\n        except Exception as e:\n            logger.error(f\"Failed to render scene: {str(e)}\")\n            sys.exit(2)\n    else:\n        if os.path.exists(file_name):\n            if file_name[-3:] != \".py\":\n                raise Exception(f\"{file_name} is not a valid Manim python script.\")\n            module_name = file_name[:-3].replace(os.sep, '.').split('.')[-1]\n            spec = importlib.util.spec_from_file_location(module_name, file_name)\n            module = importlib.util.module_from_spec(spec)\n            spec.loader.exec_module(module)\n            return module\n        else:\n            raise FileNotFoundError(f'{file_name} not found')\n\n\ndef main():\n    module = get_module(file_writer_config[\"input_file\"])\n    all_scene_classes = get_scene_classes_from_module(module)\n    scene_classes_to_render = get_scenes_to_render(all_scene_classes)\n    sound_on = file_writer_config[\"sound\"]\n    for SceneClass in scene_classes_to_render:\n        try:\n            # By invoking, this renders the full scene\n            scene = SceneClass()\n            open_file_if_needed(scene.file_writer)\n            if sound_on:\n                play_finish_sound()\n        except Exception:\n            print(\"\\n\\n\")\n            traceback.print_exc()\n            print(\"\\n\\n\")\n            if sound_on:\n                play_error_sound()\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "manim/__main__.py"}]}