Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add inverted options and strict mode #2710

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 9 commits into from
Jan 24, 2017
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
5 changes: 4 additions & 1 deletion docs/source/command_line.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ flag (or its long form ``--help``)::
[--warn-incomplete-stub] [--warn-redundant-casts]
[--warn-no-return] [--warn-unused-ignores] [--show-error-context]
[--fast-parser] [-i] [--cache-dir DIR] [--strict-optional]
[--strict-optional-whitelist [GLOB [GLOB ...]]]
[--strict-optional-whitelist [GLOB [GLOB ...]]] [--strict]
[--junit-xml JUNIT_XML] [--pdb] [--show-traceback] [--stats]
[--inferstats] [--custom-typing MODULE]
[--custom-typeshed-dir DIR] [--scripts-are-modules]
Expand Down Expand Up @@ -371,6 +371,9 @@ Here are some more useful flags:
type other than ``bool``. Instead use explicit checks like ``if x > 0`` or
``while x is not None``.

- ``--strict`` mode enables all optional error checking flags. You can see the
list of flags enabled by strict mode in the full ``mypy -h`` output.

For the remaining flags you can read the full ``mypy -h`` output.

.. note::
Expand Down
95 changes: 74 additions & 21 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,29 @@ def __init__(self, prog: Optional[str]) -> None:
super().__init__(prog=prog, max_help_position=28)


# Define pairs of flag prefixes with inverse meaning.
flag_prefix_pairs = [
('allow', 'disallow'),
('show', 'hide'),
]
flag_prefix_map = {} # type: Dict[str, str]
for a, b in flag_prefix_pairs:
flag_prefix_map[a] = b
flag_prefix_map[b] = a


def invert_flag_name(flag: str) -> str:
split = flag[2:].split('-', 1)
if len(split) == 2:
prefix, rest = split
if prefix in flag_prefix_map:
return '--{}-{}'.format(flag_prefix_map[prefix], rest)
elif prefix == 'no':
return '--{}'.format(rest)

return '--no-{}'.format(flag[2:])


def process_options(args: List[str],
require_targets: bool = True
) -> Tuple[List[BuildSource], Options]:
Expand All @@ -135,6 +158,32 @@ def process_options(args: List[str],
fromfile_prefix_chars='@',
formatter_class=AugmentedHelpFormatter)

strict_flag_names = [] # type: List[str]
strict_flag_assignments = [] # type: List[Tuple[str, bool]]

def add_invertible_flag(flag: str,
*,
inverse: str = None,
default: bool,
dest: str = None,
help: str,
strict_flag: bool = False
) -> None:
if inverse is None:
inverse = invert_flag_name(flag)
arg = parser.add_argument(flag, # type: ignore # incorrect stub for add_argument
action='store_false' if default else 'store_true',
dest=dest,
help=help + " (inverse: {})".format(inverse))
dest = arg.dest
arg = parser.add_argument(inverse, # type: ignore # incorrect stub for add_argument
action='store_true' if default else 'store_false',
dest=dest,
help=argparse.SUPPRESS)
if strict_flag:
strict_flag_names.append(flag)
strict_flag_assignments.append((dest, not default))

# Unless otherwise specified, arguments will be parsed directly onto an
# Options object. Options that require further processing should have
# their `dest` prefixed with `special-opts:`, which will cause them to be
Expand All @@ -154,37 +203,36 @@ def process_options(args: List[str],
help="silently ignore imports of missing modules")
parser.add_argument('--follow-imports', choices=['normal', 'silent', 'skip', 'error'],
default='normal', help="how to treat imports (default normal)")
parser.add_argument('--disallow-untyped-calls', action='store_true',
add_invertible_flag('--disallow-untyped-calls', default=False, strict_flag=True,
help="disallow calling functions without type annotations"
" from functions with type annotations")
parser.add_argument('--disallow-untyped-defs', action='store_true',
add_invertible_flag('--disallow-untyped-defs', default=False, strict_flag=True,
help="disallow defining functions without type annotations"
" or with incomplete type annotations")
parser.add_argument('--check-untyped-defs', action='store_true',
add_invertible_flag('--check-untyped-defs', default=False, strict_flag=True,
help="type check the interior of functions without type annotations")
parser.add_argument('--disallow-subclassing-any', action='store_true',
add_invertible_flag('--disallow-subclassing-any', default=False, strict_flag=True,
help="disallow subclassing values of type 'Any' when defining classes")
parser.add_argument('--warn-incomplete-stub', action='store_true',
add_invertible_flag('--warn-incomplete-stub', default=False,
help="warn if missing type annotation in typeshed, only relevant with"
" --check-untyped-defs enabled")
parser.add_argument('--warn-redundant-casts', action='store_true',
add_invertible_flag('--warn-redundant-casts', default=False, strict_flag=True,
help="warn about casting an expression to its inferred type")
parser.add_argument('--warn-no-return', action='store_true',
add_invertible_flag('--warn-no-return', default=False,
help="warn about functions that end without returning")
parser.add_argument('--warn-unused-ignores', action='store_true',
add_invertible_flag('--warn-unused-ignores', default=False, strict_flag=True,
help="warn about unneeded '# type: ignore' comments")
parser.add_argument('--show-error-context', action='store_false',
add_invertible_flag('--show-error-context', default=True,
dest='hide_error_context',
help='Precede errors with "note:" messages explaining context')
parser.add_argument('--fast-parser', action='store_true',
help="enable fast parser (recommended except on Windows)")
add_invertible_flag('--fast-parser', default=False,
help="enable fast parser (recommended)")
parser.add_argument('-i', '--incremental', action='store_true',
help="enable experimental module cache")
parser.add_argument('--cache-dir', action='store', metavar='DIR',
help="store module cache info in the given folder in incremental mode "
"(defaults to '{}')".format(defaults.CACHE_DIR))
parser.add_argument('--strict-optional', action='store_true',
dest='strict_optional',
add_invertible_flag('--strict-optional', default=False, strict_flag=True,
help="enable experimental strict Optional checks")
parser.add_argument('--strict-optional-whitelist', metavar='GLOB', nargs='*',
help="suppress strict Optional errors in all but the provided files "
Expand All @@ -207,15 +255,17 @@ def process_options(args: List[str],
parser.add_argument('--config-file',
help="Configuration file, must have a [mypy] section "
"(defaults to {})".format(defaults.CONFIG_FILE))
parser.add_argument('--show-column-numbers', action='store_true',
dest='show_column_numbers',
add_invertible_flag('--show-column-numbers', default=False,
help="Show column numbers in error messages")
parser.add_argument('--find-occurrences', metavar='CLASS.MEMBER',
dest='special-opts:find_occurrences',
help="print out all usages of a class member (experimental)")
parser.add_argument('--strict-boolean', action='store_true',
dest='strict_boolean',
add_invertible_flag('--strict-boolean', default=False, strict_flag=True,
help='enable strict boolean checks in conditions')
strict_help = "Strict mode. Enables the following flags: {}".format(
", ".join(strict_flag_names))
parser.add_argument('--strict', action='store_true', dest='special-opts:strict',
help=strict_help)
# hidden options
# --shadow-file a.py tmp.py will typecheck tmp.py in place of a.py.
# Useful for tools to make transformations to a file to get more
Expand All @@ -229,9 +279,6 @@ def process_options(args: List[str],
parser.add_argument('--debug-cache', action='store_true', help=argparse.SUPPRESS)
# --dump-graph will dump the contents of the graph of SCCs and exit.
parser.add_argument('--dump-graph', action='store_true', help=argparse.SUPPRESS)
parser.add_argument('--hide-error-context', action='store_true',
dest='hide_error_context',
help=argparse.SUPPRESS)
# deprecated options
parser.add_argument('-f', '--dirty-stubs', action='store_true',
dest='special-opts:dirty_stubs',
Expand Down Expand Up @@ -270,7 +317,7 @@ def process_options(args: List[str],
help="type-check given files or directories")

# Parse arguments once into a dummy namespace so we can get the
# filename for the config file.
# filename for the config file and know if the user requested all strict options.
dummy = argparse.Namespace()
parser.parse_args(args, dummy)
config_file = defaults.CONFIG_FILE
Expand All @@ -284,6 +331,12 @@ def process_options(args: List[str],
if config_file and os.path.exists(config_file):
parse_config_file(options, config_file)

# Set strict flags before parsing (if strict mode enabled), so other command
# line options can override.
if getattr(dummy, 'special-opts:strict'):
for dest, value in strict_flag_assignments:
setattr(options, dest, value)

# Parse command line for real, using a split namespace.
special_opts = argparse.Namespace()
parser.parse_args(args, SplitNamespace(options, special_opts, 'special-opts:'))
Expand Down