diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index ac919b6cbb63f..d01fa48936443 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -21,6 +21,10 @@ Most flags correspond closely to :ref:`command-line flags ` but there are some differences in flag names and some flags may take a different value based on the module being processed. +Some flags support user home directory and environment variable expansion. +To refer to the user home directory, use ``~`` at the beginning of the path. +To expand environment variables use ``$VARNAME`` or ``${VARNAME}``. + Config file format ****************** @@ -355,7 +359,8 @@ a list of import discovery options that may be used ``python_executable`` (string) Specifies the path to the Python executable to inspect to collect - a list of available :ref:`PEP 561 packages `. Defaults to + a list of available :ref:`PEP 561 packages `. User + home directory and environment variables will be expanded. Defaults to the executable used to run mypy. ``no_silence_site_packages`` (bool, default False) @@ -366,13 +371,15 @@ a list of import discovery options that may be used ``mypy_path`` (string) Specifies the paths to use, after trying the paths from ``MYPYPATH`` environment variable. Useful if you'd like to keep stubs in your repo, along with the config file. + Multiple paths are always separated with a ``:`` or ``,`` regardless of the platform. + User home directory and environment variables will be expanded. ``files`` (string) A comma-separated list of paths which should be checked by mypy if none are given on the command line. Supports recursive file globbing using [the glob library](https://docs.python.org/3/library/glob.html), where `*` (e.g. `*.py`) matches files in the current directory and `**/` (e.g. `**/*.py`) matches files in any directories below - the current one. + the current one. User home directory and environment variables will be expanded. Platform configuration @@ -447,7 +454,8 @@ section of the command line docs. ``custom_typeshed_dir`` (string) Specifies an alternative directory to look for stubs instead of the - default ``typeshed`` directory. + default ``typeshed`` directory. User home directory and environment + variables will be expanded. ``warn_incomplete_stub`` (bool, default False) Warns about missing type annotations in typeshed. This is only relevant diff --git a/mypy/config_parser.py b/mypy/config_parser.py index 509b2d5e84d77..47d6008f7299a 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -34,6 +34,14 @@ def parse_version(v: str) -> Tuple[int, int]: return major, minor +def expand_path(path: str) -> str: + """Expand the user home directory and any environment variables contained within + the provided path. + """ + + return os.path.expandvars(os.path.expanduser(path)) + + def split_and_match_files(paths: str) -> List[str]: """Take a string representing a list of files/directories (with support for globbing through the glob library). @@ -45,7 +53,7 @@ def split_and_match_files(paths: str) -> List[str]: expanded_paths = [] for path in paths.split(','): - path = path.strip() + path = expand_path(path.strip()) globbed_files = fileglob.glob(path, recursive=True) if globbed_files: expanded_paths.extend(globbed_files) @@ -63,8 +71,8 @@ def split_and_match_files(paths: str) -> List[str]: 'python_version': parse_version, 'strict_optional_whitelist': lambda s: s.split(), 'custom_typing_module': str, - 'custom_typeshed_dir': str, - 'mypy_path': lambda s: [p.strip() for p in re.split('[,:]', s)], + 'custom_typeshed_dir': expand_path, + 'mypy_path': lambda s: [expand_path(p.strip()) for p in re.split('[,:]', s)], 'files': split_and_match_files, 'quickstart_file': str, 'junit_xml': str, @@ -75,6 +83,8 @@ def split_and_match_files(paths: str) -> List[str]: 'always_true': lambda s: [p.strip() for p in s.split(',')], 'always_false': lambda s: [p.strip() for p in s.split(',')], 'package_root': lambda s: [p.strip() for p in s.split(',')], + 'cache_dir': expand_path, + 'python_executable': expand_path, } # type: Final @@ -223,8 +233,6 @@ def parse_section(prefix: str, template: Options, except ValueError as err: print("%s%s: %s" % (prefix, key, err), file=stderr) continue - if key == 'cache_dir': - v = os.path.expandvars(os.path.expanduser(v)) if key == 'silent_imports': print("%ssilent_imports has been replaced by " "ignore_missing_imports=True; follow_imports=skip" % prefix, file=stderr)