mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	Patch #1739468: Directories and zipfiles containing __main__.py are now executable
This commit is contained in:
		
							parent
							
								
									5cf449cfb2
								
							
						
					
					
						commit
						327a39b047
					
				
					 6 changed files with 254 additions and 47 deletions
				
			
		|  | @ -24,6 +24,7 @@ PyAPI_FUNC(PyObject *) PyImport_ImportModuleEx( | ||||||
| #define PyImport_ImportModuleEx(n, g, l, f) \ | #define PyImport_ImportModuleEx(n, g, l, f) \ | ||||||
| 	PyImport_ImportModuleLevel(n, g, l, f, -1) | 	PyImport_ImportModuleLevel(n, g, l, f, -1) | ||||||
| 
 | 
 | ||||||
|  | PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path); | ||||||
| PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); | PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); | ||||||
| PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m); | PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m); | ||||||
| PyAPI_FUNC(void) PyImport_Cleanup(void); | PyAPI_FUNC(void) PyImport_Cleanup(void); | ||||||
|  | @ -42,6 +43,7 @@ struct _inittab { | ||||||
|     void (*initfunc)(void); |     void (*initfunc)(void); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | PyAPI_DATA(PyTypeObject) PyNullImporter_Type; | ||||||
| PyAPI_DATA(struct _inittab *) PyImport_Inittab; | PyAPI_DATA(struct _inittab *) PyImport_Inittab; | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void)); | PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void)); | ||||||
|  |  | ||||||
|  | @ -1,3 +1,6 @@ | ||||||
|  | # Tests invocation of the interpreter with various command line arguments | ||||||
|  | # All tests are executed with environment variables ignored | ||||||
|  | # See test_cmd_line_script.py for testing of script execution | ||||||
| 
 | 
 | ||||||
| import test.test_support, unittest | import test.test_support, unittest | ||||||
| import sys | import sys | ||||||
|  |  | ||||||
							
								
								
									
										145
									
								
								Lib/test/test_cmd_line_script.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								Lib/test/test_cmd_line_script.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,145 @@ | ||||||
|  | # Tests command line execution of scripts | ||||||
|  | from __future__ import with_statement | ||||||
|  | 
 | ||||||
|  | import unittest | ||||||
|  | import os | ||||||
|  | import os.path | ||||||
|  | import sys | ||||||
|  | import test | ||||||
|  | import tempfile | ||||||
|  | import subprocess | ||||||
|  | import py_compile | ||||||
|  | import contextlib | ||||||
|  | import shutil | ||||||
|  | import zipfile | ||||||
|  | 
 | ||||||
|  | verbose = test.test_support.verbose | ||||||
|  | 
 | ||||||
|  | # XXX ncoghlan: Should we consider moving these to test_support? | ||||||
|  | from test_cmd_line import _spawn_python, _kill_python | ||||||
|  | 
 | ||||||
|  | def _run_python(*args): | ||||||
|  |     if __debug__: | ||||||
|  |         p = _spawn_python(*args) | ||||||
|  |     else: | ||||||
|  |         p = _spawn_python('-O', *args) | ||||||
|  |     stdout_data = _kill_python(p) | ||||||
|  |     return p.wait(), stdout_data | ||||||
|  | 
 | ||||||
|  | @contextlib.contextmanager | ||||||
|  | def temp_dir(): | ||||||
|  |     dirname = tempfile.mkdtemp() | ||||||
|  |     try: | ||||||
|  |         yield dirname | ||||||
|  |     finally: | ||||||
|  |         shutil.rmtree(dirname) | ||||||
|  | 
 | ||||||
|  | test_source = ("""\ | ||||||
|  | # Script may be run with optimisation enabled, so don't rely on assert | ||||||
|  | # statements being executed | ||||||
|  | def assertEqual(lhs, rhs): | ||||||
|  |     if lhs != rhs: | ||||||
|  |         raise AssertionError("%r != %r" % (lhs, rhs)) | ||||||
|  | def assertIdentical(lhs, rhs): | ||||||
|  |     if lhs is not rhs: | ||||||
|  |         raise AssertionError("%r is not %r" % (lhs, rhs)) | ||||||
|  | # Check basic code execution | ||||||
|  | result = ['Top level assignment'] | ||||||
|  | def f(): | ||||||
|  |     result.append('Lower level reference') | ||||||
|  | f() | ||||||
|  | assertEqual(result, ['Top level assignment', 'Lower level reference']) | ||||||
|  | # Check population of magic variables | ||||||
|  | assertEqual(__name__, '__main__') | ||||||
|  | print '__file__==%r' % __file__ | ||||||
|  | # Check the sys module | ||||||
|  | import sys | ||||||
|  | assertIdentical(globals(), sys.modules[__name__].__dict__) | ||||||
|  | print 'sys.argv[0]==%r' % sys.argv[0] | ||||||
|  | """) | ||||||
|  | 
 | ||||||
|  | def _make_test_script(script_dir, script_basename): | ||||||
|  |     script_filename = script_basename+os.extsep+"py" | ||||||
|  |     script_name = os.path.join(script_dir, script_filename) | ||||||
|  |     script_file = open(script_name, "w") | ||||||
|  |     script_file.write(test_source) | ||||||
|  |     script_file.close() | ||||||
|  |     return script_name | ||||||
|  | 
 | ||||||
|  | def _compile_test_script(script_name): | ||||||
|  |     py_compile.compile(script_name, doraise=True) | ||||||
|  |     if __debug__: | ||||||
|  |         compiled_name = script_name + 'c' | ||||||
|  |     else: | ||||||
|  |         compiled_name = script_name + 'o' | ||||||
|  |     return compiled_name | ||||||
|  | 
 | ||||||
|  | def _make_test_zip(zip_dir, zip_basename, script_name): | ||||||
|  |     zip_filename = zip_basename+os.extsep+"zip" | ||||||
|  |     zip_name = os.path.join(zip_dir, zip_filename) | ||||||
|  |     zip_file = zipfile.ZipFile(zip_name, 'w') | ||||||
|  |     zip_file.write(script_name, os.path.basename(script_name)) | ||||||
|  |     zip_file.close() | ||||||
|  |     # if verbose: | ||||||
|  |     #    zip_file = zipfile.ZipFile(zip_name, 'r') | ||||||
|  |     #    print "Contents of %r:" % zip_name | ||||||
|  |     #    zip_file.printdir() | ||||||
|  |     #    zip_file.close() | ||||||
|  |     return zip_name | ||||||
|  | 
 | ||||||
|  | class CmdLineTest(unittest.TestCase): | ||||||
|  |     def _check_script(self, script_name, expected_file, expected_argv0): | ||||||
|  |         exit_code, data = _run_python(script_name) | ||||||
|  |         # if verbose: | ||||||
|  |         #    print "Output from test script %r:" % script_name | ||||||
|  |         #    print data | ||||||
|  |         self.assertEqual(exit_code, 0) | ||||||
|  |         printed_file = '__file__==%r' % expected_file | ||||||
|  |         printed_argv0 = 'sys.argv[0]==%r' % expected_argv0 | ||||||
|  |         self.assert_(printed_file in data) | ||||||
|  |         self.assert_(printed_argv0 in data) | ||||||
|  | 
 | ||||||
|  |     def test_basic_script(self): | ||||||
|  |         with temp_dir() as script_dir: | ||||||
|  |             script_name = _make_test_script(script_dir, "script") | ||||||
|  |             self._check_script(script_name, script_name, script_name) | ||||||
|  | 
 | ||||||
|  |     def test_script_compiled(self): | ||||||
|  |         with temp_dir() as script_dir: | ||||||
|  |             script_name = _make_test_script(script_dir, "script") | ||||||
|  |             compiled_name = _compile_test_script(script_name) | ||||||
|  |             os.remove(script_name) | ||||||
|  |             self._check_script(compiled_name, compiled_name, compiled_name) | ||||||
|  | 
 | ||||||
|  |     def test_directory(self): | ||||||
|  |         with temp_dir() as script_dir: | ||||||
|  |             script_name = _make_test_script(script_dir, "__main__") | ||||||
|  |             self._check_script(script_dir, script_name, script_dir) | ||||||
|  | 
 | ||||||
|  |     def test_directory_compiled(self): | ||||||
|  |         with temp_dir() as script_dir: | ||||||
|  |             script_name = _make_test_script(script_dir, "__main__") | ||||||
|  |             compiled_name = _compile_test_script(script_name) | ||||||
|  |             os.remove(script_name) | ||||||
|  |             self._check_script(script_dir, compiled_name, script_dir) | ||||||
|  | 
 | ||||||
|  |     def test_zipfile(self): | ||||||
|  |         with temp_dir() as script_dir: | ||||||
|  |             script_name = _make_test_script(script_dir, "__main__") | ||||||
|  |             zip_name = _make_test_zip(script_dir, "test_zip", script_name) | ||||||
|  |             self._check_script(zip_name, None, zip_name) | ||||||
|  | 
 | ||||||
|  |     def test_zipfile_compiled(self): | ||||||
|  |         with temp_dir() as script_dir: | ||||||
|  |             script_name = _make_test_script(script_dir, "__main__") | ||||||
|  |             compiled_name = _compile_test_script(script_name) | ||||||
|  |             zip_name = _make_test_zip(script_dir, "test_zip", compiled_name) | ||||||
|  |             self._check_script(zip_name, None, zip_name) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_main(): | ||||||
|  |     test.test_support.run_unittest(CmdLineTest) | ||||||
|  |     test.test_support.reap_children() | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     test_main() | ||||||
|  | @ -12,6 +12,10 @@ What's New in Python 2.6 alpha 1? | ||||||
| Core and builtins | Core and builtins | ||||||
| ----------------- | ----------------- | ||||||
| 
 | 
 | ||||||
|  | - Patch #1739468: Directories and zipfiles containing a __main__.py file can | ||||||
|  |   now be directly executed by passing their name to the interpreter. The | ||||||
|  |   directory/zipfile is automatically inserted as the first entry in sys.path. | ||||||
|  | 
 | ||||||
| - Issue #1265: Fix a problem with sys.settrace, if the tracing function uses a | - Issue #1265: Fix a problem with sys.settrace, if the tracing function uses a | ||||||
|   generator expression when at the same time the executed code is closing a |   generator expression when at the same time the executed code is closing a | ||||||
|   paused generator. |   paused generator. | ||||||
|  |  | ||||||
							
								
								
									
										120
									
								
								Modules/main.c
									
										
									
									
									
								
							
							
						
						
									
										120
									
								
								Modules/main.c
									
										
									
									
									
								
							|  | @ -141,7 +141,7 @@ static void RunStartupFile(PyCompilerFlags *cf) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static int RunModule(char *module) | static int RunModule(char *module, int set_argv0) | ||||||
| { | { | ||||||
| 	PyObject *runpy, *runmodule, *runargs, *result; | 	PyObject *runpy, *runmodule, *runargs, *result; | ||||||
| 	runpy = PyImport_ImportModule("runpy"); | 	runpy = PyImport_ImportModule("runpy"); | ||||||
|  | @ -155,7 +155,7 @@ static int RunModule(char *module) | ||||||
| 		Py_DECREF(runpy); | 		Py_DECREF(runpy); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 	runargs = Py_BuildValue("(s)", module); | 	runargs = Py_BuildValue("(si)", module, set_argv0); | ||||||
| 	if (runargs == NULL) { | 	if (runargs == NULL) { | ||||||
| 		fprintf(stderr, | 		fprintf(stderr, | ||||||
| 			"Could not create arguments for runpy._run_module_as_main\n"); | 			"Could not create arguments for runpy._run_module_as_main\n"); | ||||||
|  | @ -177,6 +177,35 @@ static int RunModule(char *module) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int RunMainFromImporter(char *filename) | ||||||
|  | { | ||||||
|  | 	PyObject *argv0 = NULL, *importer = NULL; | ||||||
|  | 
 | ||||||
|  | 	if ( | ||||||
|  | 		(argv0 = PyString_FromString(filename)) &&  | ||||||
|  | 		(importer = PyImport_GetImporter(argv0)) && | ||||||
|  | 		(importer->ob_type != &PyNullImporter_Type)) | ||||||
|  | 	{ | ||||||
|  | 		 /* argv0 is usable as an import source, so
 | ||||||
|  | 			put it in sys.path[0] and import __main__ */ | ||||||
|  | 		PyObject *sys_path = NULL; | ||||||
|  | 		if ( | ||||||
|  | 			(sys_path = PySys_GetObject("path")) && | ||||||
|  | 			!PyList_SetItem(sys_path, 0, argv0) | ||||||
|  | 		) { | ||||||
|  | 			Py_INCREF(argv0); | ||||||
|  | 			Py_CLEAR(importer); | ||||||
|  | 			sys_path = NULL; | ||||||
|  | 			return RunModule("__main__", 0) != 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	PyErr_Clear(); | ||||||
|  | 	Py_CLEAR(argv0); | ||||||
|  | 	Py_CLEAR(importer); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /* Wait until threading._shutdown completes, provided
 | /* Wait until threading._shutdown completes, provided
 | ||||||
|    the threading module was imported in the first place. |    the threading module was imported in the first place. | ||||||
|    The shutdown routine will wait until all non-daemon |    The shutdown routine will wait until all non-daemon | ||||||
|  | @ -388,39 +417,6 @@ Py_Main(int argc, char **argv) | ||||||
| #else | #else | ||||||
| 		filename = argv[_PyOS_optind]; | 		filename = argv[_PyOS_optind]; | ||||||
| #endif | #endif | ||||||
| 		if (filename != NULL) { |  | ||||||
| 			if ((fp = fopen(filename, "r")) == NULL) { |  | ||||||
| #ifdef HAVE_STRERROR |  | ||||||
| 				fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n", |  | ||||||
| 					argv[0], filename, errno, strerror(errno)); |  | ||||||
| #else |  | ||||||
| 				fprintf(stderr, "%s: can't open file '%s': Errno %d\n", |  | ||||||
| 					argv[0], filename, errno); |  | ||||||
| #endif |  | ||||||
| 				return 2; |  | ||||||
| 			} |  | ||||||
| 			else if (skipfirstline) { |  | ||||||
| 				int ch; |  | ||||||
| 				/* Push back first newline so line numbers
 |  | ||||||
| 				   remain the same */ |  | ||||||
| 				while ((ch = getc(fp)) != EOF) { |  | ||||||
| 					if (ch == '\n') { |  | ||||||
| 						(void)ungetc(ch, fp); |  | ||||||
| 						break; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			{ |  | ||||||
| 				/* XXX: does this work on Win/Win64? (see posix_fstat) */ |  | ||||||
| 				struct stat sb; |  | ||||||
| 				if (fstat(fileno(fp), &sb) == 0 && |  | ||||||
| 				    S_ISDIR(sb.st_mode)) { |  | ||||||
| 					fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename); |  | ||||||
| 					fclose(fp); |  | ||||||
| 					return 1; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0); | 	stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0); | ||||||
|  | @ -515,19 +511,63 @@ Py_Main(int argc, char **argv) | ||||||
| 		sts = PyRun_SimpleStringFlags(command, &cf) != 0; | 		sts = PyRun_SimpleStringFlags(command, &cf) != 0; | ||||||
| 		free(command); | 		free(command); | ||||||
| 	} else if (module) { | 	} else if (module) { | ||||||
| 		sts = RunModule(module); | 		sts = RunModule(module, 1); | ||||||
| 		free(module); | 		free(module); | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
|  | 
 | ||||||
| 		if (filename == NULL && stdin_is_interactive) { | 		if (filename == NULL && stdin_is_interactive) { | ||||||
| 			Py_InspectFlag = 0; /* do exit on SystemExit */ | 			Py_InspectFlag = 0; /* do exit on SystemExit */ | ||||||
| 			RunStartupFile(&cf); | 			RunStartupFile(&cf); | ||||||
| 		} | 		} | ||||||
| 		/* XXX */ | 		/* XXX */ | ||||||
| 		sts = PyRun_AnyFileExFlags( | 
 | ||||||
| 			fp, | 		sts = -1;	/* keep track of whether we've already run __main__ */ | ||||||
| 			filename == NULL ? "<stdin>" : filename, | 
 | ||||||
| 			filename != NULL, &cf) != 0; | 		if (filename != NULL) { | ||||||
|  | 			sts = RunMainFromImporter(filename); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (sts==-1 && filename!=NULL) { | ||||||
|  | 			if ((fp = fopen(filename, "r")) == NULL) { | ||||||
|  | #ifdef HAVE_STRERROR | ||||||
|  | 				fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n", | ||||||
|  | 					argv[0], filename, errno, strerror(errno)); | ||||||
|  | #else | ||||||
|  | 				fprintf(stderr, "%s: can't open file '%s': Errno %d\n", | ||||||
|  | 					argv[0], filename, errno); | ||||||
|  | #endif | ||||||
|  | 				return 2; | ||||||
|  | 			} | ||||||
|  | 			else if (skipfirstline) { | ||||||
|  | 				int ch; | ||||||
|  | 				/* Push back first newline so line numbers
 | ||||||
|  | 				   remain the same */ | ||||||
|  | 				while ((ch = getc(fp)) != EOF) { | ||||||
|  | 					if (ch == '\n') { | ||||||
|  | 						(void)ungetc(ch, fp); | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			{ | ||||||
|  | 				/* XXX: does this work on Win/Win64? (see posix_fstat) */ | ||||||
|  | 				struct stat sb; | ||||||
|  | 				if (fstat(fileno(fp), &sb) == 0 && | ||||||
|  | 				    S_ISDIR(sb.st_mode)) { | ||||||
|  | 					fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename); | ||||||
|  | 					return 1; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (sts==-1) { | ||||||
|  | 			sts = PyRun_AnyFileExFlags( | ||||||
|  | 				fp, | ||||||
|  | 				filename == NULL ? "<stdin>" : filename, | ||||||
|  | 				filename != NULL, &cf) != 0; | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Check this environment variable at the end, to give programs the
 | 	/* Check this environment variable at the end, to give programs the
 | ||||||
|  |  | ||||||
|  | @ -104,7 +104,6 @@ static const struct filedescr _PyImport_StandardFiletab[] = { | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| static PyTypeObject NullImporterType;	/* Forward reference */ |  | ||||||
| 
 | 
 | ||||||
| /* Initialize things */ | /* Initialize things */ | ||||||
| 
 | 
 | ||||||
|  | @ -167,7 +166,7 @@ _PyImportHooks_Init(void) | ||||||
| 
 | 
 | ||||||
| 	/* adding sys.path_hooks and sys.path_importer_cache, setting up
 | 	/* adding sys.path_hooks and sys.path_importer_cache, setting up
 | ||||||
| 	   zipimport */ | 	   zipimport */ | ||||||
| 	if (PyType_Ready(&NullImporterType) < 0) | 	if (PyType_Ready(&PyNullImporter_Type) < 0) | ||||||
| 		goto error; | 		goto error; | ||||||
| 
 | 
 | ||||||
| 	if (Py_VerboseFlag) | 	if (Py_VerboseFlag) | ||||||
|  | @ -1088,7 +1087,7 @@ get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, | ||||||
| 	} | 	} | ||||||
| 	if (importer == NULL) { | 	if (importer == NULL) { | ||||||
| 		importer = PyObject_CallFunctionObjArgs( | 		importer = PyObject_CallFunctionObjArgs( | ||||||
| 			(PyObject *)&NullImporterType, p, NULL | 			(PyObject *)&PyNullImporter_Type, p, NULL | ||||||
| 		); | 		); | ||||||
| 		if (importer == NULL) { | 		if (importer == NULL) { | ||||||
| 			if (PyErr_ExceptionMatches(PyExc_ImportError)) { | 			if (PyErr_ExceptionMatches(PyExc_ImportError)) { | ||||||
|  | @ -1106,6 +1105,20 @@ get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, | ||||||
| 	return importer; | 	return importer; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | PyAPI_FUNC(PyObject *) | ||||||
|  | PyImport_GetImporter(PyObject *path) { | ||||||
|  |         PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL; | ||||||
|  | 
 | ||||||
|  | 	if ((path_importer_cache = PySys_GetObject("path_importer_cache"))) { | ||||||
|  | 		if ((path_hooks = PySys_GetObject("path_hooks"))) { | ||||||
|  | 			importer = get_path_importer(path_importer_cache, | ||||||
|  | 			                             path_hooks, path); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */ | ||||||
|  | 	return importer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Search the path (default sys.path) for a module.  Return the
 | /* Search the path (default sys.path) for a module.  Return the
 | ||||||
|    corresponding filedescr struct, and (via return arguments) the |    corresponding filedescr struct, and (via return arguments) the | ||||||
|    pathname and an open file.  Return NULL if the module is not found. */ |    pathname and an open file.  Return NULL if the module is not found. */ | ||||||
|  | @ -3049,7 +3062,7 @@ static PyMethodDef NullImporter_methods[] = { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static PyTypeObject NullImporterType = { | PyTypeObject PyNullImporter_Type = { | ||||||
| 	PyVarObject_HEAD_INIT(NULL, 0) | 	PyVarObject_HEAD_INIT(NULL, 0) | ||||||
| 	"imp.NullImporter",        /*tp_name*/ | 	"imp.NullImporter",        /*tp_name*/ | ||||||
| 	sizeof(NullImporter),      /*tp_basicsize*/ | 	sizeof(NullImporter),      /*tp_basicsize*/ | ||||||
|  | @ -3096,7 +3109,7 @@ initimp(void) | ||||||
| { | { | ||||||
| 	PyObject *m, *d; | 	PyObject *m, *d; | ||||||
| 
 | 
 | ||||||
| 	if (PyType_Ready(&NullImporterType) < 0) | 	if (PyType_Ready(&PyNullImporter_Type) < 0) | ||||||
| 		goto failure; | 		goto failure; | ||||||
| 
 | 
 | ||||||
| 	m = Py_InitModule4("imp", imp_methods, doc_imp, | 	m = Py_InitModule4("imp", imp_methods, doc_imp, | ||||||
|  | @ -3118,8 +3131,8 @@ initimp(void) | ||||||
| 	if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure; | 	if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure; | ||||||
| 	if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure; | 	if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure; | ||||||
| 
 | 
 | ||||||
| 	Py_INCREF(&NullImporterType); | 	Py_INCREF(&PyNullImporter_Type); | ||||||
| 	PyModule_AddObject(m, "NullImporter", (PyObject *)&NullImporterType); | 	PyModule_AddObject(m, "NullImporter", (PyObject *)&PyNullImporter_Type); | ||||||
|   failure: |   failure: | ||||||
| 	; | 	; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nick Coghlan
						Nick Coghlan