@@ -372,6 +372,110 @@ def test_subinterps(self):
372372 self .assertNotEqual (pickle .load (f ), id (builtins ))
373373
374374
375+ class EmbeddingTests (unittest .TestCase ):
376+ def setUp (self ):
377+ here = os .path .abspath (__file__ )
378+ basepath = os .path .dirname (os .path .dirname (os .path .dirname (here )))
379+ exename = "_testembed"
380+ if sys .platform .startswith ("win" ):
381+ ext = ("_d" if "_d" in sys .executable else "" ) + ".exe"
382+ exename += ext
383+ exepath = os .path .dirname (sys .executable )
384+ else :
385+ exepath = os .path .join (basepath , "Programs" )
386+ self .test_exe = exe = os .path .join (exepath , exename )
387+ if not os .path .exists (exe ):
388+ self .skipTest ("%r doesn't exist" % exe )
389+ # This is needed otherwise we get a fatal error:
390+ # "Py_Initialize: Unable to get the locale encoding
391+ # LookupError: no codec search functions registered: can't find encoding"
392+ self .oldcwd = os .getcwd ()
393+ os .chdir (basepath )
394+
395+ def tearDown (self ):
396+ os .chdir (self .oldcwd )
397+
398+ def run_embedded_interpreter (self , * args , env = None ):
399+ """Runs a test in the embedded interpreter"""
400+ cmd = [self .test_exe ]
401+ cmd .extend (args )
402+ if env is not None and sys .platform == 'win32' :
403+ # Windows requires at least the SYSTEMROOT environment variable to
404+ # start Python.
405+ env = env .copy ()
406+ env ['SYSTEMROOT' ] = os .environ ['SYSTEMROOT' ]
407+
408+ p = subprocess .Popen (cmd ,
409+ stdout = subprocess .PIPE ,
410+ stderr = subprocess .PIPE ,
411+ universal_newlines = True ,
412+ env = env )
413+ (out , err ) = p .communicate ()
414+ self .assertEqual (p .returncode , 0 ,
415+ "bad returncode %d, stderr is %r" %
416+ (p .returncode , err ))
417+ return out , err
418+
419+ def test_repeated_init_and_subinterpreters (self ):
420+ # This is just a "don't crash" test
421+ out , err = self .run_embedded_interpreter ('repeated_init_and_subinterpreters' )
422+ if support .verbose :
423+ print ()
424+ print (out )
425+ print (err )
426+
427+ def test_forced_io_encoding (self ):
428+ # Checks forced configuration of embedded interpreter IO streams
429+ env = dict (os .environ , PYTHONIOENCODING = "utf-8:surrogateescape" )
430+ out , err = self .run_embedded_interpreter ("forced_io_encoding" , env = env )
431+ if support .verbose :
432+ print ()
433+ print (out )
434+ print (err )
435+ expected_stream_encoding = "utf-8"
436+ expected_errors = "surrogateescape"
437+ expected_output = '\n ' .join ([
438+ "--- Use defaults ---" ,
439+ "Expected encoding: default" ,
440+ "Expected errors: default" ,
441+ "stdin: {in_encoding}:{errors}" ,
442+ "stdout: {out_encoding}:{errors}" ,
443+ "stderr: {out_encoding}:backslashreplace" ,
444+ "--- Set errors only ---" ,
445+ "Expected encoding: default" ,
446+ "Expected errors: ignore" ,
447+ "stdin: {in_encoding}:ignore" ,
448+ "stdout: {out_encoding}:ignore" ,
449+ "stderr: {out_encoding}:backslashreplace" ,
450+ "--- Set encoding only ---" ,
451+ "Expected encoding: latin-1" ,
452+ "Expected errors: default" ,
453+ "stdin: latin-1:{errors}" ,
454+ "stdout: latin-1:{errors}" ,
455+ "stderr: latin-1:backslashreplace" ,
456+ "--- Set encoding and errors ---" ,
457+ "Expected encoding: latin-1" ,
458+ "Expected errors: replace" ,
459+ "stdin: latin-1:replace" ,
460+ "stdout: latin-1:replace" ,
461+ "stderr: latin-1:backslashreplace" ])
462+ expected_output = expected_output .format (
463+ in_encoding = expected_stream_encoding ,
464+ out_encoding = expected_stream_encoding ,
465+ errors = expected_errors )
466+ # This is useful if we ever trip over odd platform behaviour
467+ self .maxDiff = None
468+ self .assertEqual (out .strip (), expected_output )
469+
470+ def test_pre_initialization_api (self ):
471+ """
472+ Checks the few parts of the C-API that work before the runtine
473+ is initialized (via Py_Initialize()).
474+ """
475+ env = dict (os .environ , PYTHONPATH = os .pathsep .join (sys .path ))
476+ out , err = self .run_embedded_interpreter ("pre_initialization_api" , env = env )
477+ self .assertEqual (out , '' )
478+ self .assertEqual (err , '' )
375479
376480
377481@unittest .skipUnless (threading , 'Threading required for this test.' )
0 commit comments