Skip to content

Fix/Improve Test Driver #721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Oct 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ install:
- pip install -r test-requirements.txt
- python setup.py install

script: bash travis.sh
script:
- python runtests.py -v

notifications:
irc:
Expand Down
40 changes: 28 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,28 +117,44 @@ Running tests and linting

First install any additional dependencies needed for testing:

$ pip install -r test-requirements.txt
$ pip3 install -r test-requirements.txt

To run tests, run the script `tests.py` in the mypy repository:
To run all tests, run the script `runtests.py` in the mypy repository:

$ python3 tests.py
$ ./runtests.py

You can also run tests without having to run `setup.py` first by
setting up the Python module search path suitably:
Note that some tests will be disabled for older python versions.

$ export PYTHONPATH=PREFIX/mypy:PREFIX/mypy/lib-typing/3.2
$ python3 tests.py
You can run a subset of test suites by passing postive or negative filters:

Replace `PREFIX` with the path where you have the repository cloned.
$ ./runtests.py lex parse -x lint -x stub

You can also run the type checker for manual testing now without
installing anything by running `scripts/mypy`:
If you want to run individual unit tests, you can run myunit directly, or
pass inferior arguments via -a:

$ python3 PREFIX/mypy/scripts/mypy PROGRAM
$ scripts/myunit -m mypy.test.testlex -v '*backslash*'
$ ./runtests.py mypy.test.testlex -a -v -a '*backslash*'

You can also run the type checker for manual testing without
installing anything by setting up the Python module search path suitably:

$ export PYTHONPATH=$PWD:$PWD/lib-typing/3.2
$ python<version> -m mypy PROGRAM.py

You can add the entry scripts to PATH for a single python3 version:

$ export PATH=$PWD/scripts
$ mypy PROGRAM.py

You can check a module or string instead of a file:

$ mypy PROGRAM.py
$ mypy -m MODULE
$ mypy -c 'import MODULE'

To run the linter:

$ ./lint.sh
$ ./runtests.py lint


Development status
Expand Down
11 changes: 0 additions & 11 deletions lint.sh

This file was deleted.

5 changes: 5 additions & 0 deletions mypy/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Mypy type checker command line tool."""

from mypy.main import main

main()
39 changes: 29 additions & 10 deletions mypy/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
from mypy import stats


# We need to know the location of this file to load data, but
# until Python 3.4, __file__ is relative.
__file__ = os.path.realpath(__file__)

debug = False


Expand All @@ -39,6 +43,7 @@
# Build flags
VERBOSE = 'verbose' # More verbose messages (for troubleshooting)
MODULE = 'module' # Build module as a script
PROGRAM_TEXT = 'program-text' # Build command-line argument as a script
TEST_BUILTINS = 'test-builtins' # Use stub builtins to speed up tests

# State ids. These describe the states a source file / module can be in a
Expand Down Expand Up @@ -83,6 +88,7 @@ def __init__(self, files: Dict[str, MypyFile],
def build(program_path: str,
target: int,
module: str = None,
argument: str = None,
program_text: Union[str, bytes] = None,
alt_lib_path: str = None,
bin_dir: str = None,
Expand Down Expand Up @@ -123,7 +129,7 @@ def build(program_path: str,
if TEST_BUILTINS in flags:
# Use stub builtins (to speed up test cases and to make them easier to
# debug).
lib_path.insert(0, os.path.join('mypy', 'test', 'data', 'lib-stub'))
lib_path.insert(0, os.path.join(os.path.dirname(__file__), 'test', 'data', 'lib-stub'))
elif program_path:
# Include directory of the program file in the module search path.
lib_path.insert(
Expand All @@ -147,9 +153,11 @@ def build(program_path: str,
custom_typing_module=custom_typing_module,
html_report_dir=html_report_dir)

program_path = program_path or lookup_program(module, lib_path)
if program_text is None:
program_path = program_path or lookup_program(module, lib_path)
program_text = read_program(program_path)
else:
program_path = program_path or '<string>'

# Construct information that describes the initial file. __main__ is the
# implicit module id and the import context is empty initially ([]).
Expand All @@ -164,16 +172,17 @@ def build(program_path: str,


def default_data_dir(bin_dir: str) -> str:
# TODO fix this logic
if not bin_dir:
# Default to current directory.
return ''
# Default to directory containing this file's parent.
return os.path.dirname(os.path.dirname(__file__))
base = os.path.basename(bin_dir)
dir = os.path.dirname(bin_dir)
if (sys.platform == 'win32' and base.lower() == 'scripts'
if (sys.platform == 'win32' and base.lower() == 'mypy'
and not os.path.isdir(os.path.join(dir, 'stubs'))):
# Installed, on Windows.
return os.path.join(dir, 'Lib', 'mypy')
elif base == 'scripts':
elif base == 'mypy':
# Assume that we have a repo check out or unpacked source tarball.
return os.path.dirname(bin_dir)
elif base == 'bin':
Expand All @@ -199,7 +208,14 @@ def default_lib_path(data_dir: str, target: int, pyversion: int,
path[:0] = path_env.split(os.pathsep)

# Add library stubs directory. By convention, they are stored in the
# stubs/x.y directory of the mypy installation.
# stubs/x.y directory of the mypy installation. Additionally, stubs
# for earlier versions in the same major version will be added, and
# as a last resort, third-party stubs will be added.
if pyversion == 2:
major, minor = 2, 7
else:
# See bug #886
major, minor = sys.version_info[0], sys.version_info[1]
version_dir = '3.2'
third_party_dir = 'third-party-3.2'
if pyversion < 3:
Expand All @@ -208,9 +224,12 @@ def default_lib_path(data_dir: str, target: int, pyversion: int,
path.append(os.path.join(data_dir, 'stubs', version_dir))
path.append(os.path.join(data_dir, 'stubs', third_party_dir))
path.append(os.path.join(data_dir, 'stubs-auto', version_dir))
if sys.version_info.major == 3:
if major == 3:
# Add additional stub directories.
versions = ['3.3', '3.4', '3.5', '3.6']
if False:
# Ick, we really should figure out how to use this again.
versions = ['3.%d' % i for i in range(minor, -1, -1)]
for v in versions:
stubdir = os.path.join(data_dir, 'stubs', v)
if os.path.isdir(stubdir):
Expand Down Expand Up @@ -444,7 +463,7 @@ def lookup_state(self, module: str) -> 'State':
for state in self.states:
if state.id == module:
return state
raise RuntimeError('%s not found' % str)
raise RuntimeError('%s not found' % module)

def all_imported_modules_in_file(self,
file: MypyFile) -> List[Tuple[str, int]]:
Expand All @@ -459,7 +478,7 @@ def correct_rel_imp(imp: Union[ImportFrom, ImportAll]) -> str:
rel = imp.relative
if rel == 0:
return imp.id
if os.path.basename(file.path) == '__init__.py':
if os.path.basename(file.path).startswith('__init__.'):
rel -= 1
if rel != 0:
file_id = ".".join(file_id.split(".")[:-rel])
Expand Down
4 changes: 3 additions & 1 deletion mypy/checkstrformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
from mypy.nodes import (
Node, StrExpr, TupleExpr, DictExpr, Context
)
import mypy.checker
if False:
# break import cycle only needed for mypy
import mypy.checker
from mypy import messages
from mypy.messages import MessageBuilder

Expand Down
10 changes: 7 additions & 3 deletions mypy/codec/pytokenize.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
from token import *

import token
x = None
x = None # type: str
__all__ = [x for x in dir(token) if not x.startswith("_")]
__all__ += ["COMMENT", "tokenize", "generate_tokens", "NL", "untokenize"]
del x
Expand Down Expand Up @@ -187,7 +187,7 @@ def maybe(*choices): return group(*choices) + '?'
'r': None, 'R': None, 'u': None, 'U': None,
'b': None, 'B': None}

triple_quoted = {}
triple_quoted = {} # type: Dict[str, str]
for t in ("'''", '"""',
"r'''", 'r"""', "R'''", 'R"""',
"u'''", 'u"""', "U'''", 'U"""',
Expand All @@ -197,7 +197,7 @@ def maybe(*choices): return group(*choices) + '?'
"br'''", 'br"""', "Br'''", 'Br"""',
"bR'''", 'bR"""', "BR'''", 'BR"""'):
triple_quoted[t] = t
single_quoted = {}
single_quoted = {} # type: Dict[str, str]
for t in ("'", '"',
"r'", 'r"', "R'", 'R"',
"u'", 'u"', "U'", 'U"',
Expand Down Expand Up @@ -333,6 +333,10 @@ def generate_tokens(readline):
contline = None
indents = [0]

if 0:
# type hints for mypy
strstart = (0, 0)
endprog = re.compile('')
while 1: # loop over lines in stream
try:
line = readline()
Expand Down
37 changes: 21 additions & 16 deletions mypy/codec/test/test_function_translation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import codecs
import sys

from unittest import TestCase

Expand All @@ -8,68 +9,68 @@
# even indices are input functions, odd indices are expected output
test_function_examples = [
# test a function without annotations
'''\
b'''\
def f(x):
x = {'a': x}
return x['a']
''',
'''\
b'''\
def f(x):
x = {'a': x}
return x['a']
''',

# test parameter type annotations
'''\
b'''\
def f(x: int, y: str = 'abc'):
return x
''',
'''\
b'''\
def f(x , y = 'abc'):
return x
''',

# test return type annotations
'''\
b'''\
def f(x, y) -> str:
return x
''',
'''\
b'''\
def f(x, y) :
return x
''',

# test newlines in param list
'''\
b'''\
def f(x: int,
y: str) -> str:
return x
''',
'''\
b'''\
def f(x ,
y ) :
return x
''',

# test newlines in return type annotation
'''\
b'''\
def f(x: int, y: str='abc') -> Tuple[int,
str]:
return x, y
''',
'''\
b'''\
def f(x , y ='abc')\\
:
return x, y
''',


# test unrelated continuations
'''\
b'''\
x = 1 + \
2
''',
'''\
b'''\
x = 1 + \
2
''',
Expand All @@ -81,7 +82,11 @@ class TestFunctionTranslation(TestCase):

def test_all_functions(self):
for i in range(0, len(test_function_examples), 2):
func_translated = codecs.decode(test_function_examples[i], 'mypy')
#print repr(func_translated)
#print repr(test_function_examples[i + 1])
self.assertEqual(func_translated, test_function_examples[i + 1])
func_orig = test_function_examples[i]
func_py2 = test_function_examples[i + 1].decode('utf-8')
func_py3 = func_orig.decode('utf-8')
func_translated = codecs.decode(func_orig, 'mypy')
if sys.version_info[0] == 2:
self.assertEqual(func_translated, func_py2)
else:
self.assertEqual(func_translated, func_py3)
Loading