@@ -69,30 +69,75 @@ def main():
6969 help = "Print periodic FPS measurements on the terminal."
7070 )
7171 parser .add_argument (
72- 'program ' ,
73- help = "The Pygame Zero program to run."
72+ 'game ' ,
73+ help = "The Pygame Zero game to run (a Python file or directory) ."
7474 )
7575 args = parser .parse_args ()
7676
7777 if __debug__ :
7878 warnings .simplefilter ('default' , DeprecationWarning )
7979
80- load_and_run (args .program , fps = args .fps )
80+ try :
81+ load_and_run (args .game , fps = args .fps )
82+ except NoMainModule as e :
83+ sys .exit (e )
84+
85+
86+ class NoMainModule (Exception ):
87+ """Indicate that we couldn't find a main module to run."""
8188
8289
8390def load_and_run (path , * , fps : bool = False ):
84- """Load and run the given Python file as the main PGZero game module.
91+ """Load and run the given Python file or directory.
92+
93+ If a file, run this as the main PGZero game module.
94+
95+ If a directory, run the first file inside the directory containing:
96+
97+ * `__main__.py`
98+ * `main.py`
99+ * `run_game.py`
100+ * `<name>.py` where `<name>` is the basename of the directory
85101
86102 Note that the 'import pgzrun' IDE mode doesn't pass through this entry
87103 point, as the module is already loaded.
88104
89105 """
90- with open (path , 'rb' ) as f :
91- src = f .read ()
106+ path = path .rstrip (os .sep )
107+ try :
108+ with open (path , 'rb' ) as f :
109+ src = f .read ()
110+ except FileNotFoundError :
111+ raise NoMainModule (f"Error: { path } does not exist." )
112+ except IsADirectoryError :
113+ name = os .path .basename (path )
114+ for candidate in (
115+ '__main__.py' ,
116+ 'main.py' ,
117+ 'run_game.py' ,
118+ f'{ name } .py'
119+ ):
120+ try :
121+ with open (os .path .join (path , candidate ), 'rb' ) as f :
122+ src = f .read ()
123+ break
124+ except FileNotFoundError :
125+ pass
126+ else :
127+ raise NoMainModule (f"""\
128+ Error: { path } is a directory.
129+
130+ To run a directory with pgzrun, it must contain a file named __main__.py,
131+ main.py, run_game.py, or a .py file with the same name as the directory.
132+
133+ You can also run a specific file with:
134+
135+ pgzrun path/to/your/file.py
136+ """ )
137+ else :
138+ name , _ = os .path .splitext (os .path .basename (path ))
92139
93140 code = compile (src , os .path .basename (path ), 'exec' , dont_inherit = True )
94-
95- name , _ = os .path .splitext (os .path .basename (path ))
96141 mod = ModuleType (name )
97142 mod .__file__ = path
98143 mod .__name__ = name
0 commit comments