@@ -372,6 +372,110 @@ def test_subinterps(self):
372
372
self .assertNotEqual (pickle .load (f ), id (builtins ))
373
373
374
374
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 , '' )
375
479
376
480
377
481
@unittest .skipUnless (threading , 'Threading required for this test.' )
0 commit comments