def test_socket(self): # use a subprocess to have only one thread code = """if 1: import signal import socket import struct import _testcapi signum = signal.SIGINT signals = (signum,) def handler(signum, frame): pass signal.signal(signum, handler) read, write = socket.socketpair() write.setblocking(False) signal.set_wakeup_fd(write.fileno()) signal.raise_signal(signum) data = read.recv(1) if not data: raise Exception("no signum written") raised = struct.unpack('B', data) if raised != signals: raise Exception("%r != %r" % (raised, signals)) read.close() write.close() """ assert_python_ok('-c', code)
def test_hash_randomization(self): # Verify that -R enables hash randomization: self.verify_valid_flag('-R') hashes = [] if os.environ.get('PYTHONHASHSEED', 'random') != 'random': env = dict(os.environ) # copy # We need to test that it is enabled by default without # the environment variable enabling it for us. del env['PYTHONHASHSEED'] env['__cleanenv'] = '1' # consumed by assert_python_ok() else: env = {} for i in range(3): code = 'print(hash("spam"))' rc, out, err = assert_python_ok('-c', code, **env) self.assertEqual(rc, 0) hashes.append(out) hashes = sorted(set(hashes)) # uniq # Rare chance of failure due to 3 random seeds honestly being equal. self.assertGreater(len(hashes), 1, msg='3 runs produced an identical random hash ' ' for "spam": {}'.format(hashes)) # Verify that sys.flags contains hash_randomization code = 'import sys; print("random is", sys.flags.hash_randomization)' rc, out, err = assert_python_ok('-c', code) self.assertEqual(rc, 0) self.assertIn(b'random is 1', out)
def test_temp_dir__forked_child(self): """Test that a forked child process does not remove the directory.""" # See bpo-30028 for details. # Run the test as an external script, because it uses fork. script_helper.assert_python_ok("-c", textwrap.dedent(""" import os from test import support with support.temp_cwd() as temp_path: pid = os.fork() if pid != 0: # parent process (child has pid == 0) # wait for the child to terminate (pid, status) = os.waitpid(pid, 0) if status != 0: raise AssertionError(f"Child process failed with exit " f"status indication 0x{status:x}.") # Make sure that temp_path is still present. When the child # process leaves the 'temp_cwd'-context, the __exit__()- # method of the context must not remove the temporary # directory. if not os.path.isdir(temp_path): raise AssertionError("Child removed temp_path.") """))
def test_pthread_kill(self): code = """if 1: import signal import threading import sys signum = signal.SIGUSR1 def handler(signum, frame): 1/0 signal.signal(signum, handler) if sys.platform == 'freebsd6': # Issue #12392 and #12469: send a signal to the main thread # doesn't work before the creation of the first thread on # FreeBSD 6 def noop(): pass thread = threading.Thread(target=noop) thread.start() thread.join() tid = threading.get_ident() try: signal.pthread_kill(tid, signum) except ZeroDivisionError: pass else: raise Exception("ZeroDivisionError not raised") """ assert_python_ok('-c', code)
def test_sigwait_thread(self): # Check that calling sigwait() from a thread doesn't suspend the whole # process. A new interpreter is spawned to avoid problems when mixing # threads and fork(): only async-safe functions are allowed between # fork() and exec(). assert_python_ok("-c", """if True: import os, threading, sys, time, signal # the default handler terminates the process signum = signal.SIGUSR1 def kill_later(): # wait until the main thread is waiting in sigwait() time.sleep(1) os.kill(os.getpid(), signum) # the signal must be blocked by all the threads signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) killer = threading.Thread(target=kill_later) killer.start() received = signal.sigwait([signum]) if received != signum: print("sigwait() received %s, not %s" % (received, signum), file=sys.stderr) sys.exit(1) killer.join() # unblock the signal, which should have been cleared by sigwait() signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) """)
def test_sigpending(self): code = """if 1: import os import signal def handler(signum, frame): 1/0 signum = signal.SIGUSR1 signal.signal(signum, handler) signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) os.kill(os.getpid(), signum) pending = signal.sigpending() for sig in pending: assert isinstance(sig, signal.Signals), repr(pending) if pending != {signum}: raise Exception('%s != {%s}' % (pending, signum)) try: signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) except ZeroDivisionError: pass else: raise Exception("ZeroDivisionError not raised") """ assert_python_ok('-c', code)
def test_set_pycache_prefix(self): # sys.pycache_prefix can be set from either -X pycache_prefix or # PYTHONPYCACHEPREFIX env var, with the former taking precedence. NO_VALUE = object() # `-X pycache_prefix` with no `=PATH` cases = [ # (PYTHONPYCACHEPREFIX, -X pycache_prefix, sys.pycache_prefix) (None, None, None), ('foo', None, 'foo'), (None, 'bar', 'bar'), ('foo', 'bar', 'bar'), ('foo', '', None), ('foo', NO_VALUE, None), ] for envval, opt, expected in cases: exp_clause = "is None" if expected is None else f'== "{expected}"' code = f"import sys; sys.exit(not sys.pycache_prefix {exp_clause})" args = ['-c', code] env = {} if envval is None else {'PYTHONPYCACHEPREFIX': envval} if opt is NO_VALUE: args[:0] = ['-X', 'pycache_prefix'] elif opt is not None: args[:0] = ['-X', f'pycache_prefix={opt}'] with self.subTest(envval=envval, opt=opt): with support.temp_cwd(): assert_python_ok(*args, **env)
def test_doctest_main_issue4197(self): test_src = textwrap.dedent("""\ class Test: ">>> 'line 2'" pass import doctest doctest.testmod() """) pattern = 'File "%s", line 2, in %s' with test.support.temp_dir() as d: script_name = make_script(d, 'script', test_src) rc, out, err = assert_python_ok(script_name) expected = pattern % (script_name, "__main__.Test") if verbose: print ("Expected line", expected) print ("Got stdout:") print (ascii(out)) self.assertIn(expected.encode('utf-8'), out) zip_name, run_name = make_zip_script(d, "test_zip", script_name, '__main__.py') rc, out, err = assert_python_ok(zip_name) expected = pattern % (run_name, "__main__.Test") if verbose: print ("Expected line", expected) print ("Got stdout:") print (ascii(out)) self.assertIn(expected.encode('utf-8'), out)
def test_unencodable_filename(self): # Issue #11619: The Python parser and the import machinery must not # encode filenames, especially on Windows pyname = script_helper.make_script("", TESTFN_UNENCODABLE, "pass") self.addCleanup(unlink, pyname) name = pyname[:-3] script_helper.assert_python_ok("-c", "mod = __import__(%a)" % name, __isolated=False)
def test_assert_python_ok_raises(self): # I didn't import the sys module so this child will fail. with self.assertRaises(AssertionError) as error_context: script_helper.assert_python_ok('-c', 'sys.exit(0)') error_msg = str(error_context.exception) self.assertIn('command line:', error_msg) self.assertIn('sys.exit(0)', error_msg, msg='unexpected command line')
def test_run_code(self): # Test expected operation of the '-c' switch # Switch needs an argument assert_python_failure('-c') # Check we get an error for an uncaught exception assert_python_failure('-c', 'raise Exception') # All good if execution is successful assert_python_ok('-c', 'pass')
def test_verbose(self): # -v causes imports to write to stderr. If the write to # stderr itself causes an import to happen (for the output # codec), a recursion loop can occur. rc, out, err = assert_python_ok('-v') self.assertNotIn(b'stack overflow', err) rc, out, err = assert_python_ok('-vv') self.assertNotIn(b'stack overflow', err)
def test_sys_argv_list(self): with open(TESTFN, 'w') as fd: self.addCleanup(unlink, TESTFN) fd.write("import sys\n") fd.write("print(type(sys.argv))\n") status, direct_stdout, stderr = assert_python_ok(TESTFN) status, trace_stdout, stderr = assert_python_ok('-m', 'trace', '-l', TESTFN) self.assertIn(direct_stdout.strip(), trace_stdout)
def test_del___main__(self): # Issue #15001: PyRun_SimpleFileExFlags() did crash because it kept a # borrowed reference to the dict of __main__ module and later modify # the dict whereas the module was destroyed filename = test.support.TESTFN self.addCleanup(test.support.unlink, filename) with open(filename, "w") as script: print("import sys", file=script) print("del sys.modules['__main__']", file=script) assert_python_ok(filename)
def test_issue_8766(self): # "import encodings" emits a warning whereas the warnings is not loaded # or not completely loaded (warnings imports indirectly encodings by # importing linecache) yet with support.temp_cwd() as cwd, support.temp_cwd('encodings'): # encodings loaded by initfsencoding() assert_python_ok('-c', 'pass', PYTHONPATH=cwd) # Use -W to load warnings module at startup assert_python_ok('-c', 'pass', '-W', 'always', PYTHONPATH=cwd)
def extract_docstrings_from_str(self, module_content): """ utility: return all msgids extracted from module_content """ filename = 'test_docstrings.py' with temp_cwd(None) as cwd: with open(filename, 'w') as fp: fp.write(module_content) assert_python_ok(self.script, '-D', filename) with open('messages.pot') as fp: data = fp.read() return self.get_msgids(data)
def f(self, ext=ext, switch=switch): script_helper.assert_python_ok(*(switch + ["-m", "compileall", "-q", self.pkgdir])) # Verify the __pycache__ directory contents. self.assertTrue(os.path.exists(self.pkgdir_cachedir)) expected = sorted( base.format(sys.implementation.cache_tag, ext) for base in ("__init__.{}.{}", "bar.{}.{}") ) self.assertEqual(sorted(os.listdir(self.pkgdir_cachedir)), expected) # Make sure there are no .pyc files in the source directory. self.assertFalse([fn for fn in os.listdir(self.pkgdir) if fn.endswith(ext)])
def test_import_in_del_does_not_crash(self): # Issue 4236 testfn = script_helper.make_script('', TESTFN, textwrap.dedent("""\ import sys class C: def __del__(self): import importlib sys.argv.insert(0, C()) """)) script_helper.assert_python_ok(testfn)
def test_run_profile_as_module(self): # Test that -m switch needs an argument assert_python_failure('-m', self.profilermodule.__name__, '-m') # Test failure for not-existent module assert_python_failure('-m', self.profilermodule.__name__, '-m', 'random_module_xyz') # Test successful run assert_python_ok('-m', self.profilermodule.__name__, '-m', 'timeit', '-n', '1')
def test_module_path_option(self): # Test -m switch with modules # Test that -m switch needs an argument assert_python_failure('-m', 'cProfile', '-m') # Test failure for not-existent module assert_python_failure('-m', 'cProfile', '-m', 'random_module_xyz') # Test successful run assert_python_ok('-m', 'cProfile', '-m', 'timeit', '-n', '1')
def test_run_module(self): # Test expected operation of the '-m' switch # Switch needs an argument assert_python_failure('-m') # Check we get an error for a nonexistent module assert_python_failure('-m', 'fnord43520xyz') # Check the runpy module also gives an error for # a nonexistent module assert_python_failure('-m', 'runpy', 'fnord43520xyz') # All good if module is located and run successfully assert_python_ok('-m', 'timeit', '-n', '1')
def test_all(self): # Run the tester in a sub-process, to make sure there is only one # thread (for reliable signal delivery). tester = support.findfile("eintr_tester.py", subdir="eintrdata") if support.verbose: args = [sys.executable, tester] with subprocess.Popen(args) as proc: exitcode = proc.wait() self.assertEqual(exitcode, 0) else: script_helper.assert_python_ok(tester)
def test_all(self): # Run the tester in a sub-process, to make sure there is only one # thread (for reliable signal delivery). tester = support.findfile("eintr_tester.py", subdir="eintrdata") # FIXME: Issue #25122, always run in verbose mode to debug hang on FreeBSD if True: #support.verbose: args = [sys.executable, tester] with subprocess.Popen(args) as proc: exitcode = proc.wait() self.assertEqual(exitcode, 0) else: script_helper.assert_python_ok(tester)
def test_wakeup_write_error(self): # Issue #16105: write() errors in the C signal handler should not # pass silently. # Use a subprocess to have only one thread. code = """if 1: import _testcapi import errno import os import signal import sys from test.support import captured_stderr def handler(signum, frame): 1/0 signal.signal(signal.SIGALRM, handler) r, w = os.pipe() os.set_blocking(r, False) # Set wakeup_fd a read-only file descriptor to trigger the error signal.set_wakeup_fd(r) try: with captured_stderr() as err: signal.raise_signal(signal.SIGALRM) except ZeroDivisionError: # An ignored exception should have been printed out on stderr err = err.getvalue() if ('Exception ignored when trying to write to the signal wakeup fd' not in err): raise AssertionError(err) if ('OSError: [Errno %d]' % errno.EBADF) not in err: raise AssertionError(err) else: raise AssertionError("ZeroDivisionError not raised") os.close(r) os.close(w) """ r, w = os.pipe() try: os.write(r, b'x') except OSError: pass else: self.skipTest("OS doesn't report write() error on the read end of a pipe") finally: os.close(r) os.close(w) assert_python_ok('-c', code)
def test_unbuffered_output(self): # Test expected operation of the '-u' switch for stream in ('stdout', 'stderr'): # Binary is unbuffered code = ("import os, sys; sys.%s.buffer.write(b'x'); os._exit(0)" % stream) rc, out, err = assert_python_ok('-u', '-c', code) data = err if stream == 'stderr' else out self.assertEqual(data, b'x', "binary %s not unbuffered" % stream) # Text is unbuffered code = ("import os, sys; sys.%s.write('x'); os._exit(0)" % stream) rc, out, err = assert_python_ok('-u', '-c', code) data = err if stream == 'stderr' else out self.assertEqual(data, b'x', "text %s not unbuffered" % stream)
def test_dash_l(self): rc, out, err = assert_python_ok(self.script, '-l', self.fodder) self.assertEqual(rc, 0) self.assertIn(self.fodder_md5, out) parts = self.fodder.split(os.path.sep) self.assertIn(parts[-1].encode(), out) self.assertNotIn(parts[-2].encode(), out)
def test_print_exception_stderr_is_none_1(self): script = r"""if True: import sys import threading import time running = False def run(): global running running = True while running: time.sleep(0.01) 1/0 t = threading.Thread(target=run) t.start() while not running: time.sleep(0.01) sys.stderr = None running = False t.join() """ rc, out, err = assert_python_ok("-c", script) self.assertEqual(out, b'') err = err.decode() self.assertIn("Exception in thread", err) self.assertIn("Traceback (most recent call last):", err) self.assertIn("ZeroDivisionError", err) self.assertNotIn("Unhandled exception", err)
def test_checksum_fodder(self): rc, out, err = assert_python_ok(self.script, self.fodder) self.assertEqual(rc, 0) self.assertTrue(out.startswith(self.fodder_md5)) for part in self.fodder.split(os.path.sep): self.assertIn(part.encode(), out) self.assertFalse(err)
def test_dummy_thread_after_fork(self): # Issue #14308: a dummy thread in the active list doesn't mess up # the after-fork mechanism. code = """if 1: import _thread, threading, os, time def background_thread(evt): # Creates and registers the _DummyThread instance threading.current_thread() evt.set() time.sleep(10) evt = threading.Event() _thread.start_new_thread(background_thread, (evt,)) evt.wait() assert threading.active_count() == 2, threading.active_count() if os.fork() == 0: assert threading.active_count() == 1, threading.active_count() os._exit(0) else: os.wait() """ _, out, err = assert_python_ok("-c", code) self.assertEqual(out, b'') self.assertEqual(err, b'')
def test_main_thread_after_fork_from_nonmain_thread(self): code = """if 1: import os, threading, sys def f(): pid = os.fork() if pid == 0: main = threading.main_thread() print(main.name) print(main.ident == threading.current_thread().ident) print(main.ident == threading.get_ident()) # stdout is fully buffered because not a tty, # we have to flush before exit. sys.stdout.flush() else: os.waitpid(pid, 0) th = threading.Thread(target=f) th.start() th.join() """ _, out, err = assert_python_ok("-c", code) data = out.decode().replace('\r', '') self.assertEqual(err, b"") self.assertEqual(data, "Thread-1\nTrue\nTrue\n")
def test_help_flag(self): rc, out, err = assert_python_ok('-m', 'json.tool', '-h') self.assertEqual(rc, 0) self.assertTrue(out.startswith(b'usage: ')) self.assertEqual(err, b'')
def test_comma_separated_warnings(self): rc, stdout, stderr = assert_python_ok("-c", "import sys; sys.stdout.write(str(sys.warnoptions))", PYTHONWARNINGS="ignore::DeprecationWarning,ignore::UnicodeWarning") self.assertEqual(stdout, b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
def test_usage(self): rc, out, err = assert_python_ok('-h') self.assertIn(b'usage', out)
def get_output(self, *args): return script_helper.assert_python_ok('-m', 'base64', *args).out
def test_warn_on_full_buffer(self): # Use a subprocess to have only one thread. if os.name == 'nt': action = 'send' else: action = 'write' code = """if 1: import errno import signal import socket import sys import time import _testcapi from test.support import captured_stderr signum = signal.SIGINT # This handler will be called, but we intentionally won't read from # the wakeup fd. def handler(signum, frame): pass signal.signal(signum, handler) read, write = socket.socketpair() # Fill the socketpair buffer if sys.platform == 'win32': # bpo-34130: On Windows, sometimes non-blocking send fails to fill # the full socketpair buffer, so use a timeout of 50 ms instead. write.settimeout(0.050) else: write.setblocking(False) # Start with large chunk size to reduce the # number of send needed to fill the buffer. written = 0 for chunk_size in (2 ** 16, 2 ** 8, 1): chunk = b"x" * chunk_size try: while True: write.send(chunk) written += chunk_size except (BlockingIOError, socket.timeout): pass print(f"%s bytes written into the socketpair" % written, flush=True) write.setblocking(False) try: write.send(b"x") except BlockingIOError: # The socketpair buffer seems full pass else: raise AssertionError("%s bytes failed to fill the socketpair " "buffer" % written) # By default, we get a warning when a signal arrives msg = ('Exception ignored when trying to {action} ' 'to the signal wakeup fd') signal.set_wakeup_fd(write.fileno()) with captured_stderr() as err: signal.raise_signal(signum) err = err.getvalue() if msg not in err: raise AssertionError("first set_wakeup_fd() test failed, " "stderr: %r" % err) # And also if warn_on_full_buffer=True signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=True) with captured_stderr() as err: signal.raise_signal(signum) err = err.getvalue() if msg not in err: raise AssertionError("set_wakeup_fd(warn_on_full_buffer=True) " "test failed, stderr: %r" % err) # But not if warn_on_full_buffer=False signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=False) with captured_stderr() as err: signal.raise_signal(signum) err = err.getvalue() if err != "": raise AssertionError("set_wakeup_fd(warn_on_full_buffer=False) " "test failed, stderr: %r" % err) # And then check the default again, to make sure warn_on_full_buffer # settings don't leak across calls. signal.set_wakeup_fd(write.fileno()) with captured_stderr() as err: signal.raise_signal(signum) err = err.getvalue() if msg not in err: raise AssertionError("second set_wakeup_fd() test failed, " "stderr: %r" % err) """.format(action=action) assert_python_ok('-c', code)
def test_dash_c_loader(self): rc, out, err = assert_python_ok("-c", "print(__loader__)") expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8") self.assertIn(expected, out)
def test_version(self): version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii") for switch in '-V', '--version', '-VV': rc, out, err = assert_python_ok(switch) self.assertFalse(err.startswith(version)) self.assertTrue(out.startswith(version))
def test_closed_stdout(self): # Issue #13444: if stdout has been explicitly closed, we should # not attempt to flush it at shutdown. code = "import sys; sys.stdout.close()" rc, out, err = assert_python_ok('-c', code) self.assertEqual(b'', err)
def verify_valid_flag(self, cmd_line): rc, out, err = assert_python_ok(*cmd_line) self.assertTrue(out == b'' or out.endswith(b'\n')) self.assertNotIn(b'Traceback', out) self.assertNotIn(b'Traceback', err)
def test_env_limit(self): # start and set the number of frames code = 'import tracemalloc; print(tracemalloc.get_traceback_limit())' ok, stdout, stderr = assert_python_ok('-c', code, PYTHONTRACEMALLOC='10') stdout = stdout.rstrip() self.assertEqual(stdout, b'10')
def test_non_ascii(self): # Test handling of non-ascii data command = ("assert(ord(%r) == %s)" % (os_helper.FS_NONASCII, ord(os_helper.FS_NONASCII))) assert_python_ok('-c', command)
def test_exit(self): # call with two arguments self.assertRaises(TypeError, sys.exit, 42, 42) # call without argument with self.assertRaises(SystemExit) as cm: sys.exit() self.assertIsNone(cm.exception.code) rc, out, err = assert_python_ok('-c', 'import sys; sys.exit()') self.assertEqual(rc, 0) self.assertEqual(out, b'') self.assertEqual(err, b'') # call with integer argument with self.assertRaises(SystemExit) as cm: sys.exit(42) self.assertEqual(cm.exception.code, 42) # call with tuple argument with one entry # entry will be unpacked with self.assertRaises(SystemExit) as cm: sys.exit((42,)) self.assertEqual(cm.exception.code, 42) # call with string argument with self.assertRaises(SystemExit) as cm: sys.exit("exit") self.assertEqual(cm.exception.code, "exit") # call with tuple argument with two entries with self.assertRaises(SystemExit) as cm: sys.exit((17, 23)) self.assertEqual(cm.exception.code, (17, 23)) # test that the exit machinery handles SystemExits properly rc, out, err = assert_python_failure('-c', 'raise SystemExit(47)') self.assertEqual(rc, 47) self.assertEqual(out, b'') self.assertEqual(err, b'') def check_exit_message(code, expected, **env_vars): rc, out, err = assert_python_failure('-c', code, **env_vars) self.assertEqual(rc, 1) self.assertEqual(out, b'') self.assertTrue(err.startswith(expected), "%s doesn't start with %s" % (ascii(err), ascii(expected))) # test that stderr buffer is flushed before the exit message is written # into stderr check_exit_message( r'import sys; sys.stderr.write("unflushed,"); sys.exit("message")', b"unflushed,message") # test that the exit message is written with backslashreplace error # handler to stderr check_exit_message( r'import sys; sys.exit("surrogates:\uDCFF")', b"surrogates:\\udcff") # test that the unicode message is encoded to the stderr encoding # instead of the default encoding (utf8) check_exit_message( r'import sys; sys.exit("h\xe9")', b"h\xe9", PYTHONIOENCODING='latin-1')
def test_run_as_module(self): assert_python_ok('-m', 'trace', '-l', '--module', 'timeit', '-n', '1') assert_python_failure('-m', 'trace', '-l', '--module', 'not_a_module_zzz')
def test_pthread_sigmask(self): code = """if 1: import signal import os; import threading def handler(signum, frame): 1/0 def kill(signum): os.kill(os.getpid(), signum) def check_mask(mask): for sig in mask: assert isinstance(sig, signal.Signals), repr(sig) def read_sigmask(): sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, []) check_mask(sigmask) return sigmask signum = signal.SIGUSR1 # Install our signal handler old_handler = signal.signal(signum, handler) # Unblock SIGUSR1 (and copy the old mask) to test our signal handler old_mask = signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) check_mask(old_mask) try: kill(signum) except ZeroDivisionError: pass else: raise Exception("ZeroDivisionError not raised") # Block and then raise SIGUSR1. The signal is blocked: the signal # handler is not called, and the signal is now pending mask = signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) check_mask(mask) kill(signum) # Check the new mask blocked = read_sigmask() check_mask(blocked) if signum not in blocked: raise Exception("%s not in %s" % (signum, blocked)) if old_mask ^ blocked != {signum}: raise Exception("%s ^ %s != {%s}" % (old_mask, blocked, signum)) # Unblock SIGUSR1 try: # unblock the pending signal calls immediately the signal handler signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) except ZeroDivisionError: pass else: raise Exception("ZeroDivisionError not raised") try: kill(signum) except ZeroDivisionError: pass else: raise Exception("ZeroDivisionError not raised") # Check the new mask unblocked = read_sigmask() if signum in unblocked: raise Exception("%s in %s" % (signum, unblocked)) if blocked ^ unblocked != {signum}: raise Exception("%s ^ %s != {%s}" % (blocked, unblocked, signum)) if old_mask != unblocked: raise Exception("%s != %s" % (old_mask, unblocked)) """ assert_python_ok('-c', code)
def test_function_tp_clear_leaves_consistent_state(self): # https://github.com/python/cpython/issues/91636 code = """if 1: import gc import weakref class LateFin: __slots__ = ('ref',) def __del__(self): # 8. Now `latefin`'s finalizer is called. Here we # obtain a reference to `func`, which is currently # undergoing `tp_clear`. global func func = self.ref() class Cyclic(tuple): __slots__ = () # 4. The finalizers of all garbage objects are called. In # this case this is only us as `func` doesn't have a # finalizer. def __del__(self): # 5. Create a weakref to `func` now. If we had created # it earlier, it would have been cleared by the # garbage collector before calling the finalizers. self[1].ref = weakref.ref(self[0]) # 6. Drop the global reference to `latefin`. The only # remaining reference is the one we have. global latefin del latefin # 7. Now `func` is `tp_clear`-ed. This drops the last # reference to `Cyclic`, which gets `tp_dealloc`-ed. # This drops the last reference to `latefin`. latefin = LateFin() def func(): pass cyc = tuple.__new__(Cyclic, (func, latefin)) # 1. Create a reference cycle of `cyc` and `func`. func.__module__ = cyc # 2. Make the cycle unreachable, but keep the global reference # to `latefin` so that it isn't detected as garbage. This # way its finalizer will not be called immediately. del func, cyc # 3. Invoke garbage collection, # which will find `cyc` and `func` as garbage. gc.collect() # 9. Previously, this would crash because `func_qualname` # had been NULL-ed out by func_clear(). print(f"{func=}") """ # We're mostly just checking that this doesn't crash. rc, stdout, stderr = assert_python_ok("-c", code) self.assertEqual(rc, 0) self.assertRegex(stdout, rb"""\A\s*func=<function at \S+>\s*\Z""") self.assertFalse(stderr)
def test_env_var_enabled_at_startup(self): # tracing at startup code = 'import tracemalloc; print(tracemalloc.is_tracing())' ok, stdout, stderr = assert_python_ok('-c', code, PYTHONTRACEMALLOC='1') stdout = stdout.rstrip() self.assertEqual(stdout, b'True')
def run_ok(self, *args): return assert_python_ok('-m', 'calendar', *args)[1]
def test_env_var_ignored_with_E(self): """PYTHON* environment variables must be ignored when -E is present.""" code = 'import tracemalloc; print(tracemalloc.is_tracing())' ok, stdout, stderr = assert_python_ok('-E', '-c', code, PYTHONTRACEMALLOC='1') stdout = stdout.rstrip() self.assertEqual(stdout, b'False')
def test_improper_option(self): # Same as above, but check that the message is printed out when # the interpreter is executed. This also checks that options are # actually parsed at all. rc, out, err = assert_python_ok("-Wxxx", "-c", "pass") self.assertIn(b"Invalid -W option ignored: invalid action: 'xxx'", err)
def test_env_var_disabled_by_default(self): # not tracing by default code = 'import tracemalloc; print(tracemalloc.is_tracing())' ok, stdout, stderr = assert_python_ok('-c', code) stdout = stdout.rstrip() self.assertEqual(stdout, b'False')
def test_interprocess_signal(self): dirname = os.path.dirname(__file__) script = os.path.join(dirname, 'signalinterproctester.py') assert_python_ok(script)
def _check_script(self, script_name, *cmd_line_switches): if not __debug__: cmd_line_switches += ('-' + 'O' * sys.flags.optimize, ) run_args = cmd_line_switches + (script_name, self.start_method) rc, out, err = assert_python_ok(*run_args, __isolated=False) self._check_output(script_name, rc, out, err)
def test_envvar_and_command_line(self): rc, stdout, stderr = assert_python_ok("-Wignore::UnicodeWarning", "-c", "import sys; sys.stdout.write(str(sys.warnoptions))", PYTHONWARNINGS="ignore::DeprecationWarning") self.assertEqual(stdout, b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
def test_import(self): assert_python_ok('-S', '-c', 'import ' + self.pathmodule.__name__)
def test_single_warning(self): rc, stdout, stderr = assert_python_ok("-c", "import sys; sys.stdout.write(str(sys.warnoptions))", PYTHONWARNINGS="ignore::DeprecationWarning") self.assertEqual(stdout, b"['ignore::DeprecationWarning']")
def test_deprecation_message(self): code = "def f():\n import parser\n\nf()" rc, out, err = assert_python_ok('-c', code) self.assertIn(b'<string>:2: DeprecationWarning', err)
def test_infile_stdout(self): infile = self._create_infile() rc, out, err = assert_python_ok('-m', 'json.tool', infile) self.assertEqual(rc, 0) self.assertEqual(out.splitlines(), self.expect.encode().splitlines()) self.assertEqual(err, b'')
def test_decompress_infile_outfile_error(self): rc, out, err = assert_python_ok('-m', 'gzip', '-d', 'thisisatest.out') self.assertIn(b"filename doesn't end in .gz:", out) self.assertEqual(rc, 0) self.assertEqual(err, b'')
def test_coding(self): # bpo-32381: the -c command ignores the coding cookie ch = os_helper.FS_NONASCII cmd = f"# coding: latin1\nprint(ascii('{ch}'))" res = assert_python_ok('-c', cmd) self.assertEqual(res.out.rstrip(), ascii(ch).encode('ascii'))
def test_pymem_alloc0(self): # Issue #21639: Check that PyMem_Malloc(0) with tracemalloc enabled # does not crash. code = 'import _testcapi; _testcapi.test_pymem_alloc0(); 1' assert_python_ok('-X', 'tracemalloc', '-c', code)