Skip to content
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

Type checking silently skips bad typing after encountering module cattr #6643

Closed
petergaultney opened this issue Apr 7, 2019 · 2 comments
Closed

Comments

@petergaultney
Copy link

I'm not sure whether this has anything to do with cattrs specifically, but it does seem to be related to the location of the usage of that module within the test file. Any type error placed before its first usage is correctly caught, and any (that I've tried) placed after it is not correctly caught.

  • Are you reporting a bug, or opening a feature request?

Bug

  • Please insert below the code you are checking with mypy,
    or a mock-up repro if the source is private. We would appreciate
    if you try to simplify your case to a minimal repro.
import typing as ty
import cattr


def drop_nonattrs(d: dict, Type: type) -> dict:
    """gets rid of all members of the dictionary that wouldn't fit in the given 'attrs' Type"""
    attrs_attrs = getattr(Type, '__attrs_attrs__', None)
    if attrs_attrs is None:
        raise ValueError(f'type {Type} is not an attrs class')
    attrs: ty.Set[str] = {attr.name for attr in attrs_attrs}

    combined_dict = dict()
    combined_dict += 3   # this line is an error and is caught

    return {key: val for key, val in d.items() if key in attrs}


def structure_ignore_extras(d: dict, Type: type):
    """This will drop top-level attributes that aren't expected"""
    combined_dict = dict()
    combined_dict += 3   # this line is an error and is caught

    return cattr.structure(drop_nonattrs(d, Type), Type)


def structure(*args, **kwargs):
    """A wrapper so that you only have to import this module"""
    combined_dict = dict()
    combined_dict += 3   # this line is an error and is NOT caught

    return cattr.structure(*args, **kwargs)


def combine(*args, **kwargs):
    """Allows you to combine multiple objects before structuring a new one!"""
    combined_dict = dict()
    combined_dict += 3   # this line is an error and is NOT caught
  • What is the actual behavior/output?
$ mypy test.py --ignore-missing
test.py:12: error: Need type annotation for 'combined_dict'
test.py:13: error: Unsupported operand types for + ("Dict[Any, Any]" and "int")
test.py:13: error: Incompatible types in assignment (expression has type "int", variable has type "Dict[Any, Any]")
test.py:20: error: Need type annotation for 'combined_dict'
test.py:21: error: Unsupported operand types for + ("Dict[Any, Any]" and "int")
test.py:21: error: Incompatible types in assignment (expression has type "int", variable has type "Dict[Any, Any]")
  • What is the behavior/output you expect?

I would expect similar errors for lines 28, 29, 36, and 37.

  • What are the versions of mypy and Python you are using?

0.700, 3.7.2

Do you see the same issue after installing mypy from Git master?

Yes

  • What are the mypy flags you are using? (For example --strict-optional)

--ignore-missing-imports, but it happens with or without it.

@ilevkivskyi
Copy link
Member

Non-annotated functions are not checked, use --check-untyped-defs if you want them to be checked anyway.

@petergaultney
Copy link
Author

Wow, I've been using MyPy for a year and didn't realize it wasn't checking those at all. I see it in the documentation now, but I guess I hadn't ever really read the intro bits.

Kind of terrifying, to be honest, but good to know. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants