diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index c34f23d9e169..e98137158bb2 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -195,6 +195,24 @@ section of the command line docs. This option may only be set in the global section (``[mypy]``). +.. confval:: modules + + :type: comma-separated list of strings + + A comma-separated list of modules to be type checked. See the + corresponding flag :option:`--module ` for more information. + + This option may only be set in the global section (``[mypy]``). + +.. confval:: packages + + :type: comma-separated list of strings + + A comma-separated list of packages to be type checked. See the + corresponding flag :option:`--package ` for more information. + + This option may only be set in the global section (``[mypy]``). + .. confval:: exclude :type: newline separated list of regular expressions diff --git a/mypy/config_parser.py b/mypy/config_parser.py index 5dd8fef2523d..4498b34db34f 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -110,6 +110,8 @@ def check_follow_imports(choice: str) -> str: 'custom_typeshed_dir': expand_path, 'mypy_path': lambda s: [expand_path(p.strip()) for p in re.split('[,:]', s)], 'files': split_and_match_files, + 'packages': lambda s: [p.strip() for p in s.split(',')], + 'modules': lambda s: [p.strip() for p in s.split(',')], 'quickstart_file': expand_path, 'junit_xml': expand_path, # These two are for backwards compatibility @@ -426,6 +428,12 @@ def parse_section(prefix: str, template: Options, if 'follow_imports' not in results: results['follow_imports'] = 'error' results[options_key] = v + if key in ('files', 'packages', 'modules'): + if (('packages' in results or 'modules' in results) and results.get('files')): + print("May only specify one of: module/package or files. Ignoring key:", key, + file=stderr) + del results[options_key] + continue return results, report_dirs diff --git a/mypy/main.py b/mypy/main.py index d7a0e7c52619..862c9737a1d8 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -943,8 +943,13 @@ def set_strict_flags() -> None: # Paths listed in the config file will be ignored if any paths, modules or packages # are passed on the command line. - if options.files and not (special_opts.files or special_opts.packages or special_opts.modules): - special_opts.files = options.files + if not (special_opts.files or special_opts.packages or special_opts.modules): + if options.files: + special_opts.files = options.files + if options.modules: + special_opts.modules = options.modules + if options.packages: + special_opts.packages = options.packages # Check for invalid argument combinations. if require_targets: diff --git a/mypy/options.py b/mypy/options.py index 58278b1580e8..f1e1ddafb59c 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -216,6 +216,12 @@ def __init__(self) -> None: # supports globbing self.files: Optional[List[str]] = None + # A comma-separated list of packages for mypy to type check; + self.packages = None # type: Optional[List[str]] + + # A comma-separated list of modules for mypy to type check; + self.modules = None # type: Optional[List[str]] + # Write junit.xml to given file self.junit_xml: Optional[str] = None diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index 93eb893d3c00..7ea0ae3ff698 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -788,6 +788,59 @@ p/a.py:4: error: Argument 1 to "foo" has incompatible type "str"; expected "int" p/b/__init__.py:5: error: Argument 1 to "bar" has incompatible type "str"; expected "int" c.py:2: error: Argument 1 to "bar" has incompatible type "str"; expected "int" +[case testModulesAndPackagesInIni] +# cmd: mypy +[file mypy.ini] +\[mypy] +modules=c +packages=p.a,p.b +[file p/__init__.py] +[file p/a.py] +def foo(x): + # type: (int) -> str + return "x" +foo("wrong") +[file p/b/__init__.py] +from ..a import foo +def bar(a): + # type: (int) -> str + return foo(a) +bar("wrong") +[file c.py] +import p.b +p.b.bar("wrong") +[out] +p/a.py:4: error: Argument 1 to "foo" has incompatible type "str"; expected "int" +p/b/__init__.py:5: error: Argument 1 to "bar" has incompatible type "str"; expected "int" +c.py:2: error: Argument 1 to "bar" has incompatible type "str"; expected "int" + +[case testModulesAndPackagesAndFilesInIni] +# cmd: mypy +[file mypy.ini] +\[mypy] +modules=c +packages=p.a,p.b +files=meh.py +[out] +May only specify one of: module/package or files. Ignoring key: files +Can't find package 'p.a' +== Return code: 2 + + +[case testModulesAndPackagesAndFilesInIniModLater] +# cmd: mypy +[file mypy.ini] +\[mypy] +files=meh.py +modules=c +packages=p.a,p.b +[out] +May only specify one of: module/package or files. Ignoring key: modules +May only specify one of: module/package or files. Ignoring key: packages +mypy: cannot read file 'meh.py': No such file or directory +== Return code: 2 + + [case testSrcPEP420Packages] # cmd: mypy -p anamespace --namespace-packages [file mypy.ini] @@ -1271,7 +1324,6 @@ y = 0 # type: str [out] pkg.py:1: error: Incompatible types in assignment (expression has type "int", variable has type "str") - [case testCmdlineModuleAndIniFiles] # cmd: mypy -m pkg [file mypy.ini]