def test_pep561(testcase: DataDrivenTestCase) -> None: """Test running mypy on files that depend on PEP 561 packages.""" if (sys.platform == 'darwin' and hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix): pytest.skip() assert testcase.old_cwd is not None, "test was not properly set up" if 'python2' in testcase.name.lower(): python = try_find_python2_interpreter() if python is None: pytest.skip() else: python = sys.executable assert python is not None, "Should be impossible" pkgs, args = parse_pkgs(testcase.input[0]) use_pip = True editable = False for arg in args: if arg == 'no-pip': use_pip = False elif arg == 'editable': editable = True assert pkgs != [], "No packages to install for PEP 561 test?" with virtualenv(python) as venv: venv_dir, python_executable = venv for pkg in pkgs: install_package(pkg, python_executable, use_pip, editable) if venv_dir is not None: old_dir = os.getcwd() os.chdir(venv_dir) try: program = testcase.name + '.py' with open(program, 'w', encoding='utf-8') as f: for s in testcase.input: f.write('{}\n'.format(s)) cmd_line = [program, '--no-incremental', '--no-error-summary'] if python_executable != sys.executable: cmd_line.append( '--python-executable={}'.format(python_executable)) output = [] # Type check the module out, err, returncode = mypy.api.run(cmd_line) os.remove(program) # split lines, remove newlines, and remove directory of test case for line in (out + err).splitlines(): if line.startswith(test_temp_dir + os.sep): output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n")) else: # Normalize paths so that the output is the same on Windows and Linux/macOS. line = line.replace(test_temp_dir + os.sep, test_temp_dir + '/') output.append(line.rstrip("\r\n")) assert_string_arrays_equal([line for line in testcase.output], output, 'Invalid output ({}, line {})'.format( testcase.file, testcase.line)) finally: if venv_dir is not None: os.chdir(old_dir)
def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None: """Runs Mypy in a subprocess. If this passes without errors, executes the script again with a given Python version. """ assert testcase.old_cwd is not None, "test was not properly set up" # TODO: Enable strict optional for these tests mypy_cmdline = [ '--show-traceback', '--no-site-packages', '--no-strict-optional', '--no-silence-site-packages', ] if testcase.name.lower().endswith('_newsemanal'): mypy_cmdline.append('--new-semantic-analyzer') py2 = testcase.name.lower().endswith('python2') if py2: mypy_cmdline.append('--py2') interpreter = try_find_python2_interpreter() if interpreter is None: # Skip, can't find a Python 2 interpreter. pytest.skip() # placate the type checker return else: interpreter = python3_path mypy_cmdline.append('--python-version={}'.format('.'.join( map(str, PYTHON3_VERSION)))) # Write the program to a file. program = '_' + testcase.name + '.py' program_path = os.path.join(test_temp_dir, program) mypy_cmdline.append(program_path) with open(program_path, 'w', encoding='utf8') as file: for s in testcase.input: file.write('{}\n'.format(s)) mypy_cmdline.append('--cache-dir={}'.format(cache_dir)) output = [] # Type check the program. out, err, returncode = api.run(mypy_cmdline) # split lines, remove newlines, and remove directory of test case for line in (out + err).splitlines(): if line.startswith(test_temp_dir + os.sep): output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n")) else: output.append(line.rstrip("\r\n")) if returncode == 0: # Execute the program. returncode, interp_out = run_command([interpreter, program]) output.extend(interp_out) # Remove temp file. os.remove(program_path) for i, line in enumerate(output): if os.path.sep + 'typeshed' + os.path.sep in line: output[i] = line.split(os.path.sep)[-1] assert_string_arrays_equal( adapt_output(testcase), output, 'Invalid output ({}, line {})'.format(testcase.file, testcase.line))
def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None: """Runs Mypy in a subprocess. If this passes without errors, executes the script again with a given Python version. """ assert testcase.old_cwd is not None, "test was not properly set up" # TODO: Enable strict optional for these tests mypy_cmdline = [ '--show-traceback', '--no-site-packages', '--no-strict-optional', '--no-silence-site-packages', ] if testcase.name.lower().endswith('_newsemanal'): mypy_cmdline.append('--new-semantic-analyzer') py2 = testcase.name.lower().endswith('python2') if py2: mypy_cmdline.append('--py2') interpreter = try_find_python2_interpreter() if interpreter is None: # Skip, can't find a Python 2 interpreter. pytest.skip() # placate the type checker return else: interpreter = python3_path mypy_cmdline.append('--python-version={}'.format('.'.join(map(str, PYTHON3_VERSION)))) # Write the program to a file. program = '_' + testcase.name + '.py' program_path = os.path.join(test_temp_dir, program) mypy_cmdline.append(program_path) with open(program_path, 'w', encoding='utf8') as file: for s in testcase.input: file.write('{}\n'.format(s)) mypy_cmdline.append('--cache-dir={}'.format(cache_dir)) output = [] # Type check the program. out, err, returncode = api.run(mypy_cmdline) # split lines, remove newlines, and remove directory of test case for line in (out + err).splitlines(): if line.startswith(test_temp_dir + os.sep): output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n")) else: output.append(line.rstrip("\r\n")) if returncode == 0: # Execute the program. returncode, interp_out = run_command([interpreter, program]) output.extend(interp_out) # Remove temp file. os.remove(program_path) for i, line in enumerate(output): if os.path.sep + 'typeshed' + os.path.sep in line: output[i] = line.split(os.path.sep)[-1] assert_string_arrays_equal(adapt_output(testcase), output, 'Invalid output ({}, line {})'.format( testcase.file, testcase.line))
def test_typed_pkg(self) -> None: """Tests type checking based on installed packages. This test CANNOT be split up, concurrency means that simultaneously installing/uninstalling will break tests. """ test_file = 'simple.py' if not os.path.isdir('test-packages-data'): os.mkdir('test-packages-data') old_cwd = os.getcwd() os.chdir('test-packages-data') with open(test_file, 'w') as f: f.write(SIMPLE_PROGRAM) try: with self.install_package('typedpkg-stubs'): check_mypy_run([ test_file ], "simple.py:4: error: Revealed type is 'builtins.list[builtins.str]'\n" ) # The Python 2 tests are intentionally placed after a Python 3 test to check # the package_dir_cache is behaving correctly. python2 = try_find_python2_interpreter() if python2: with self.install_package('typedpkg-stubs', python2): check_mypy_run([ '--python-executable={}'.format(python2), test_file ], "simple.py:4: error: Revealed type is 'builtins.list[builtins.str]'\n" ) with self.install_package('typedpkg', python2): check_mypy_run([ '--python-executable={}'.format(python2), 'simple.py' ], "simple.py:4: error: Revealed type is 'builtins.tuple[builtins.str]'\n" ) with self.install_package('typedpkg', python2): with self.install_package('typedpkg-stubs', python2): check_mypy_run([ '--python-executable={}'.format(python2), test_file ], "simple.py:4: error: Revealed type is 'builtins.list[builtins.str]'\n" ) with self.install_package('typedpkg'): check_mypy_run([ test_file ], "simple.py:4: error: Revealed type is 'builtins.tuple[builtins.str]'\n" ) with self.install_package('typedpkg'): with self.install_package('typedpkg-stubs'): check_mypy_run([ test_file ], "simple.py:4: error: Revealed type is 'builtins.list[builtins.str]'\n" ) finally: os.chdir(old_cwd) shutil.rmtree('test-packages-data')
def test_typedpkg_python2(self) -> None: python2 = try_find_python2_interpreter() if python2: with self.virtualenv(python2) as py2: self.install_package('typedpkg', py2) check_mypy_run( [self.tempfile], py2, self.msg_tuple, )
def add_python2(self, name: str, *args: str, cwd: Optional[str] = None) -> None: name = 'run2 %s' % name if not self.allow(name): return largs = list(args) python2 = util.try_find_python2_interpreter() assert python2, "Couldn't find a Python 2.7 interpreter" largs[0:0] = [python2] env = self.env self.waiter.add(LazySubprocess(name, largs, cwd=cwd, env=env))
def test_python_evaluation(testcase): python2_interpreter = try_find_python2_interpreter() # Use Python 2 interpreter if running a Python 2 test case. if testcase.name.lower().endswith('python2'): if not python2_interpreter: # Skip, can't find a Python 2 interpreter. raise SkipTestCaseException() interpreter = python2_interpreter args = ['--py2'] py2 = True else: interpreter = python3_path args = [] py2 = False args.append('--show-traceback') # Write the program to a file. program = '_program.py' program_path = os.path.join(test_temp_dir, program) with open(program_path, 'w') as file: for s in testcase.input: file.write('{}\n'.format(s)) # Type check the program. # This uses the same PYTHONPATH as the current process. process = subprocess.Popen([python3_path, os.path.join(testcase.old_cwd, 'scripts', 'mypy')] + args + [program], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=test_temp_dir) outb = process.stdout.read() # Split output into lines. out = [s.rstrip('\n\r') for s in str(outb, 'utf8').splitlines()] if not process.wait(): # Set up module path for the execution. # This needs the typing module but *not* the mypy module. vers_dir = '2.7' if py2 else '3.2' typing_path = os.path.join(testcase.old_cwd, 'lib-typing', vers_dir) assert os.path.isdir(typing_path) env = os.environ.copy() env['PYTHONPATH'] = typing_path process = subprocess.Popen([interpreter, program], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=test_temp_dir, env=env) outb = process.stdout.read() # Split output into lines. out += [s.rstrip('\n\r') for s in str(outb, 'utf8').splitlines()] # Remove temp file. os.remove(program_path) assert_string_arrays_equal(testcase.output, out, 'Invalid output ({}, line {})'.format( testcase.file, testcase.line))
def test_typedpkg_python2(self) -> None: self.simple_prog.create() python2 = try_find_python2_interpreter() if python2: with self.virtualenv(python2) as venv: venv_dir, py2 = venv self.install_package('typedpkg', py2) self.simple_prog.check_mypy_run( py2, [SimpleMsg.msg_tuple], venv_dir=venv_dir, )
def test_python_evaluation(testcase): python2_interpreter = try_find_python2_interpreter() # Use Python 2 interpreter if running a Python 2 test case. if testcase.name.lower().endswith('python2'): if not python2_interpreter: # Skip, can't find a Python 2 interpreter. raise SkipTestCaseException() interpreter = python2_interpreter args = ['--py2'] py2 = True else: interpreter = python3_path args = [] py2 = False args.append('--show-traceback') # Write the program to a file. program = '_program.py' program_path = os.path.join(test_temp_dir, program) with open(program_path, 'w') as file: for s in testcase.input: file.write('{}\n'.format(s)) # Type check the program. # This uses the same PYTHONPATH as the current process. process = subprocess.Popen( [python3_path, os.path.join(testcase.old_cwd, 'scripts', 'mypy')] + args + [program], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=test_temp_dir) outb = process.stdout.read() # Split output into lines. out = [s.rstrip('\n\r') for s in str(outb, 'utf8').splitlines()] if not process.wait(): # Set up module path for the execution. # This needs the typing module but *not* the mypy module. vers_dir = '2.7' if py2 else '3.2' typing_path = os.path.join(testcase.old_cwd, 'lib-typing', vers_dir) assert os.path.isdir(typing_path) env = os.environ.copy() env['PYTHONPATH'] = typing_path process = subprocess.Popen([interpreter, program], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=test_temp_dir, env=env) outb = process.stdout.read() # Split output into lines. out += [s.rstrip('\n\r') for s in str(outb, 'utf8').splitlines()] # Remove temp file. os.remove(program_path) assert_string_arrays_equal( testcase.output, out, 'Invalid output ({}, line {})'.format(testcase.file, testcase.line))
def test_typedpkg_python2(self) -> None: python2 = try_find_python2_interpreter() if python2: with self.virtualenv(python2) as venv: venv_dir, py2 = venv self.install_package('typedpkg', py2) check_mypy_run( [self.tempfile], py2, expected_out=self.msg_tuple, venv_dir=venv_dir, )
def run_case(self, testcase: DataDrivenTestCase) -> None: assert testcase.old_cwd is not None, "test was not properly set up" mypy_cmdline = [ '--show-traceback', '--no-silence-site-packages', '--no-error-summary', '--config-file={}/sqlalchemy.ini'.format(inipath), ] py2 = testcase.name.lower().endswith('python2') if py2: if try_find_python2_interpreter() is None: pytest.skip() return mypy_cmdline.append('--py2') else: if sys.version_info[:2] == (3, 5): version = (3, 6) # Always accept variable annotations. else: version = sys.version_info[:2] mypy_cmdline.append('--python-version={}'.format('.'.join( map(str, version)))) program_text = '\n'.join(testcase.input) flags = re.search('# flags: (.*)$', program_text, flags=re.MULTILINE) if flags: flag_list = flags.group(1).split() mypy_cmdline.extend(flag_list) # Write the program to a file. program_path = os.path.join(test_temp_dir, 'main.py') mypy_cmdline.append(program_path) with open(program_path, 'w') as file: for s in testcase.input: file.write('{}\n'.format(s)) output = [] # Type check the program. out, err, returncode = api.run(mypy_cmdline) # split lines, remove newlines, and remove directory of test case for line in (out + err).splitlines(): if line.startswith(test_temp_dir + os.sep): output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n").replace( '.py', '')) else: output.append(line.rstrip("\r\n")) # Remove temp file. os.remove(program_path) assert_string_arrays_equal( testcase.output, output, 'Invalid output ({}, line {})'.format(testcase.file, testcase.line))
def test_python_evaluation(testcase: DataDrivenTestCase) -> None: """Runs Mypy in a subprocess. If this passes without errors, executes the script again with a given Python version. """ mypy_cmdline = [ python3_path, os.path.join(testcase.old_cwd, 'scripts', 'mypy'), '--show-traceback', ] py2 = testcase.name.lower().endswith('python2') if py2: mypy_cmdline.append('--py2') interpreter = try_find_python2_interpreter() if not interpreter: # Skip, can't find a Python 2 interpreter. raise SkipTestCaseException() else: interpreter = python3_path # Write the program to a file. program = '_' + testcase.name + '.py' mypy_cmdline.append(program) program_path = os.path.join(test_temp_dir, program) with open(program_path, 'w') as file: for s in testcase.input: file.write('{}\n'.format(s)) # Type check the program. # This uses the same PYTHONPATH as the current process. returncode, out = run(mypy_cmdline) if returncode == 0: # Set up module path for the execution. # This needs the typing module but *not* the mypy module. vers_dir = '2.7' if py2 else '3.2' typing_path = os.path.join(testcase.old_cwd, 'lib-typing', vers_dir) assert os.path.isdir(typing_path) env = os.environ.copy() env['PYTHONPATH'] = typing_path returncode, interp_out = run([interpreter, program], env=env) out += interp_out # Remove temp file. os.remove(program_path) assert_string_arrays_equal(adapt_output(testcase), out, 'Invalid output ({}, line {})'.format( testcase.file, testcase.line))
def test_python_evaluation(testcase: DataDrivenTestCase) -> None: """Runs Mypy in a subprocess. If this passes without errors, executes the script again with a given Python version. """ assert testcase.old_cwd is not None, "test was not properly set up" mypy_cmdline = ['--show-traceback'] py2 = testcase.name.lower().endswith('python2') if py2: mypy_cmdline.append('--py2') interpreter = try_find_python2_interpreter() if interpreter is None: # Skip, can't find a Python 2 interpreter. pytest.skip() # placate the type checker return else: interpreter = python3_path # Write the program to a file. program = '_' + testcase.name + '.py' program_path = os.path.join(test_temp_dir, program) mypy_cmdline.append(program_path) with open(program_path, 'w') as file: for s in testcase.input: file.write('{}\n'.format(s)) output = [] # Type check the program. out, err, returncode = api.run(mypy_cmdline) # split lines, remove newlines, and remove directory of test case for line in (out + err).splitlines(): if line.startswith(test_temp_dir + os.sep): output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n")) else: output.append(line.rstrip("\r\n")) if returncode == 0: # Execute the program. returncode, interp_out = run([interpreter, program]) output.extend(interp_out) # Remove temp file. os.remove(program_path) assert_string_arrays_equal(adapt_output(testcase), output, 'Invalid output ({}, line {})'.format( testcase.file, testcase.line))
def test_python_evaluation(testcase: DataDrivenTestCase) -> None: """Runs Mypy in a subprocess. If this passes without errors, executes the script again with a given Python version. """ assert testcase.old_cwd is not None, "test was not properly set up" mypy_cmdline = [ python3_path, os.path.join(testcase.old_cwd, 'scripts', 'mypy'), '--show-traceback', ] py2 = testcase.name.lower().endswith('python2') if py2: mypy_cmdline.append('--py2') interpreter = try_find_python2_interpreter() if interpreter is None: # Skip, can't find a Python 2 interpreter. pytest.skip() # placate the type checker return else: interpreter = python3_path # Write the program to a file. program = '_' + testcase.name + '.py' mypy_cmdline.append(program) program_path = os.path.join(test_temp_dir, program) with open(program_path, 'w') as file: for s in testcase.input: file.write('{}\n'.format(s)) # Type check the program. # This uses the same PYTHONPATH as the current process. returncode, out = run(mypy_cmdline) if returncode == 0: # Execute the program. returncode, interp_out = run([interpreter, program]) out += interp_out # Remove temp file. os.remove(program_path) assert_string_arrays_equal(adapt_output(testcase), out, 'Invalid output ({}, line {})'.format( testcase.file, testcase.line))
def run_case(self, testcase: DataDrivenTestCase) -> None: assert testcase.old_cwd is not None, "test was not properly set up" mypy_cmdline = [ '--show-traceback', '--no-silence-site-packages', ] py2 = testcase.name.lower().endswith('python2') if py2: if try_find_python2_interpreter() is None: pytest.skip() return mypy_cmdline.append('--py2') else: mypy_cmdline.append('--python-version={}'.format('.'.join( map(str, sys.version_info[:2])))) # Write the program to a file. program_path = os.path.join(test_temp_dir, 'main.py') mypy_cmdline.append(program_path) with open(program_path, 'w') as file: for s in testcase.input: file.write('{}\n'.format(s)) output = [] # Type check the program. out, err, returncode = api.run(mypy_cmdline) # split lines, remove newlines, and remove directory of test case for line in (out + err).splitlines(): if line.startswith(test_temp_dir + os.sep): output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n").replace( '.py', '')) else: output.append(line.rstrip("\r\n")) # Remove temp file. os.remove(program_path) assert_string_arrays_equal( testcase.output, output, 'Invalid output ({}, line {})'.format(testcase.file, testcase.line))
def test_pep561(testcase: DataDrivenTestCase) -> None: """Test running mypy on files that depend on PEP 561 packages.""" assert testcase.old_cwd is not None, "test was not properly set up" if 'python2' in testcase.name.lower(): python = try_find_python2_interpreter() if python is None: pytest.skip() else: python = sys.executable assert python is not None, "Should be impossible" pkgs, pip_args = parse_pkgs(testcase.input[0]) mypy_args = parse_mypy_args(testcase.input[1]) use_pip = True editable = False for arg in pip_args: if arg == 'no-pip': use_pip = False elif arg == 'editable': editable = True assert pkgs != [], "No packages to install for PEP 561 test?" with virtualenv(python) as venv: venv_dir, python_executable = venv for pkg in pkgs: install_package(pkg, python_executable, use_pip, editable) cmd_line = list(mypy_args) has_program = not ('-p' in cmd_line or '--package' in cmd_line) if has_program: program = testcase.name + '.py' with open(program, 'w', encoding='utf-8') as f: for s in testcase.input: f.write(f'{s}\n') cmd_line.append(program) cmd_line.extend(['--no-error-summary']) if python_executable != sys.executable: cmd_line.append(f'--python-executable={python_executable}') steps = testcase.find_steps() if steps != [[]]: steps = [[]] + steps # type: ignore[operator,assignment] for i, operations in enumerate(steps): perform_file_operations(operations) output = [] # Type check the module out, err, returncode = mypy.api.run(cmd_line) # split lines, remove newlines, and remove directory of test case for line in (out + err).splitlines(): if line.startswith(test_temp_dir + os.sep): output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n")) else: # Normalize paths so that the output is the same on Windows and Linux/macOS. line = line.replace(test_temp_dir + os.sep, test_temp_dir + '/') output.append(line.rstrip("\r\n")) iter_count = '' if i == 0 else f' on iteration {i + 1}' expected = testcase.output if i == 0 else testcase.output2.get( i + 1, []) assert_string_arrays_equal( expected, output, 'Invalid output ({}, line {}){}'.format( testcase.file, testcase.line, iter_count)) if has_program: os.remove(program)
def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None: """Runs Mypy in a subprocess. If this passes without errors, executes the script again with a given Python version. """ assert testcase.old_cwd is not None, "test was not properly set up" # We must enable site packages to get access to installed stubs. # TODO: Enable strict optional for these tests mypy_cmdline = [ '--show-traceback', '--no-strict-optional', '--no-silence-site-packages', '--no-error-summary', ] py2 = testcase.name.lower().endswith('python2') if py2: mypy_cmdline.append('--py2') interpreter = try_find_python2_interpreter() if interpreter is None: # Skip, can't find a Python 2 interpreter. pytest.skip() # placate the type checker return else: interpreter = python3_path mypy_cmdline.append(f"--python-version={'.'.join(map(str, PYTHON3_VERSION))}") m = re.search('# flags: (.*)$', '\n'.join(testcase.input), re.MULTILINE) if m: mypy_cmdline.extend(m.group(1).split()) # Write the program to a file. program = '_' + testcase.name + '.py' program_path = os.path.join(test_temp_dir, program) mypy_cmdline.append(program_path) with open(program_path, 'w', encoding='utf8') as file: for s in testcase.input: file.write(f'{s}\n') mypy_cmdline.append(f'--cache-dir={cache_dir}') output = [] # Type check the program. out, err, returncode = api.run(mypy_cmdline) # split lines, remove newlines, and remove directory of test case for line in (out + err).splitlines(): if line.startswith(test_temp_dir + os.sep): output.append(line[len(test_temp_dir + os.sep):].rstrip("\r\n")) else: # Normalize paths so that the output is the same on Windows and Linux/macOS. line = line.replace(test_temp_dir + os.sep, test_temp_dir + '/') output.append(line.rstrip("\r\n")) if returncode == 0: # Execute the program. proc = subprocess.run([interpreter, '-Wignore', program], cwd=test_temp_dir, stdout=PIPE, stderr=PIPE) output.extend(split_lines(proc.stdout, proc.stderr)) # Remove temp file. os.remove(program_path) for i, line in enumerate(output): if os.path.sep + 'typeshed' + os.path.sep in line: output[i] = line.split(os.path.sep)[-1] assert_string_arrays_equal(adapt_output(testcase), output, 'Invalid output ({}, line {})'.format( testcase.file, testcase.line))