internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: python/mypy

Issue:
Spurious error formatting bytes subclass with overridden __str__
* Please insert below the code you are checking with mypy.

```python
class HexBytes(bytes):
    def __str__(self) -> str:
        return self.hex()

value = HexBytes(b"aaa")
print(f"{value}")
```

* What is the actual behavior/output?

```
$ python3 mypy_bytes_subclass.py 
616161

$ mypy mypy_bytes_subclass.py 
mypy_bytes_subclass.py:6: error: On Python 3 '{}'.format(b'abc') produces "b'abc'"; use !r if this is a desired behavior
Found 1 error in 1 file (checked 1 source file)
```

* What is the behavior/output you expect?

I would expect no error to be produced in this situation, as `__str__` has been overridden, so the code does not exhibit the behaviour mentioned in the error.

* What are the versions of mypy and Python you are using?
  Do you see the same issue after installing mypy from Git master?

mypy 0.760, python 3.7.5
The same issue appears with `mypy-0.770+dev.e7866d0839202234db1f975a68a9284bb59d8544` (installed from git)



Discussion:
Good catch! We have a similar logic for overridden `__eq__()` in `--strict-equality` checks, it will make sense to add similar here.

Should be not hard to fix.

Resolving patch:
diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py
--- a/mypy/checkstrformat.py
+++ b/mypy/checkstrformat.py
@@ -382,7 +382,8 @@ def perform_special_format_checks(self, spec: ConversionSpecifier, call: CallExp
                     self.msg.requires_int_or_char(call, format_call=True)
         if (not spec.type or spec.type == 's') and not spec.conversion:
             if self.chk.options.python_version >= (3, 0):
-                if has_type_component(actual_type, 'builtins.bytes'):
+                if (has_type_component(actual_type, 'builtins.bytes') and
+                        not custom_special_method(actual_type, '__str__')):
                     self.msg.fail("On Python 3 '{}'.format(b'abc') produces \"b'abc'\";"
                                   " use !r if this is a desired behavior", call,
                                   code=codes.STR_BYTES_PY3)


Test patch:
diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test
--- a/test-data/unit/check-expressions.test
+++ b/test-data/unit/check-expressions.test
@@ -1556,6 +1556,12 @@ def func(x: A) -> A:
 '{!r}'.format(b)
 '{!r}'.format(x)
 '{!r}'.format(n)
+
+class D(bytes):
+    def __str__(self) -> str:
+        return "overrides __str__ of bytes"
+
+'{}'.format(D())
 [builtins fixtures/primitives.pyi]
 
 [case testFormatCallFormatTypesBytesNotPy2]
Repository: python/mypy

Issue:
Unused `type: ignore` error log coloring bug when using `show-error-codes`
* Are you reporting a bug, or opening a feature request?

Bug in log output coloring

* Please insert below the code you are checking with mypy

```python
def test(self, _):  # type: ignore[foo]
    pass
```

* What is the actual behavior/output?

Mypy correctly shows an error for the unused `type: ignore` comment, but the last letter ("t" from "comment") is colored yellow (where the error code would be shown). This does only happen with `--show-error-codes`.

```
$ mypy --warn-unused-ignores --show-error-codes test.py
```

![image](https://user-images.githubusercontent.com/19366641/71784937-6ec13100-2ff1-11ea-8091-b6bc41e163a4.png)

```
$ mypy --warn-unused-ignores test.py
```

![image](https://user-images.githubusercontent.com/19366641/71784998-500f6a00-2ff2-11ea-8ce8-2f7d5e0b65e8.png)

* What is the behavior/output you expect?

Last character shouldn't be colored OR mypy should show an error code here as well, something like:

```
test.py:1: error: unused 'type: ignore' comment  [unused-type-ignore]
```

Not sure if that makes sense as this code couldn't be used in a `type: ignore` comment to... ignore a `type: ignore` comment...

* What are the versions of mypy and Python you are using?
  Do you see the same issue after installing mypy from Git master?

```
$ python -V
Python 3.7.5
$ mypy -V
mypy 0.761
```

Same happens with mypy installed from git master:

```
$ mypy -V
mypy 0.770+dev.cdd91ba819646b0138b05a8e9180faba4ef0ff92
```

* What are the mypy flags you are using? (For example --strict-optional)

`--warn-unused-ignores` and `--show-error-codes`




Discussion:

Resolving patch:
diff --git a/mypy/util.py b/mypy/util.py
--- a/mypy/util.py
+++ b/mypy/util.py
@@ -607,8 +607,11 @@ def colorize(self, error: str) -> str:
                 return (loc + self.style('error:', 'red', bold=True) +
                         self.highlight_quote_groups(msg))
             codepos = msg.rfind('[')
-            code = msg[codepos:]
-            msg = msg[:codepos]
+            if codepos != -1:
+                code = msg[codepos:]
+                msg = msg[:codepos]
+            else:
+                code = ""  # no error code specified
             return (loc + self.style('error:', 'red', bold=True) +
                     self.highlight_quote_groups(msg) + self.style(code, 'yellow'))
         elif ': note:' in error:


Test patch:
Repository: python/mypy

Issue:
Consider adding --strict-equality to --strict
This doesn't report any errors with `--strict-equality`:

```python
def foo() -> bool:
    x: int = 5
    y: str = "foo"
    return x == y


def bar() -> bool:
    x = 5
    y = "bar"
    return x == y


def is_magic(x: bytes) -> bool:
    # Error: Non-overlapping equality check (left operand type: "bytes",
    #        right operand type: "str")  [comparison-overlap]
    return x == "magic"


if __name__ == "__main__":
    print(foo())
    print(bar())
    print(is_magic(b"magic"))
```

even though the third example [is from the docs](https://github.com/python/mypy/blob/d7268ee3336a7d2bba894794a6193872631414a5/docs/source/error_code_list2.rst#check-that-comparisons-are-overlapping-comparison-overlap).

Versions:
- Python: 3.7.4
- mypy: 0.750+dev.59617e8f895ca12a6fb0ec46f378ce384a757118



Discussion:
I don't know what you are doing, everything works perfectly for me. Maybe you have have a broken install, or something else.
I was using `--strict`, not `--strict-equality`.
> I was using `--strict`, not `--strict-equality`.

Hm, actually now that it is a bit more "mature" we can make it a strict flag, unless @msullivan is against.

See also https://github.com/python/mypy/issues/7469
Fine by me.

Resolving patch:
diff --git a/mypy/main.py b/mypy/main.py
--- a/mypy/main.py
+++ b/mypy/main.py
@@ -602,7 +602,7 @@ def add_invertible_flag(flag: str,
                         help="Treat imports as private unless aliased",
                         group=strictness_group)
 
-    add_invertible_flag('--strict-equality', default=False, strict_flag=False,
+    add_invertible_flag('--strict-equality', default=False, strict_flag=True,
                         help="Prohibit equality, identity, and container checks for"
                              " non-overlapping types",
                         group=strictness_group)


Test patch:
diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test
--- a/test-data/unit/check-flags.test
+++ b/test-data/unit/check-flags.test
@@ -1149,6 +1149,14 @@ def f(c: A) -> None:  # E: Missing type parameters for generic type "A"
     pass
 [out]
 
+[case testStrictAndStrictEquality]
+# flags: --strict
+x = 0
+y = ''
+if x == y:  # E: Non-overlapping equality check (left operand type: "int", right operand type: "str")
+    int()
+[builtins fixtures/ops.pyi]
+
 [case testStrictEqualityPerFile]
 # flags: --config-file tmp/mypy.ini
 import b
Repository: python/mypy

Issue:
Mypy doesn't detect unreachable if
* Are you reporting a bug, or opening a feature request?
Feature request (?)

* 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.
```python
class A:
    pass

if type(1) in (A,):
    print("this should give a warning")

if type(1) == A:
    print("this works")
```
* What is the actual behavior/output?
```
t.py:7: error: Non-overlapping equality check (left operand type: "Type[int]", right operand type: "Type[A]")
Found 1 error in 1 file (checked 1 source file)
```
* What is the behavior/output you expect?
Two errors, one for each impossible branch.
* What are the versions of mypy and Python you are using?
  Do you see the same issue after installing mypy from Git master?
Tried with `0.720`, `0.761` and `0.770+dev.974a58d3cb3029044b481f9e3154fa3a185cf0f3`
* What are the mypy flags you are using? (For example --strict-optional)
Tried with combinations of `--strict`, `--strict-equality`, and `--warn-unreachable`



Discussion:
It looks like strict equality container checks don't work with fixed-length tuples. Another example:

```py
# mypy: strict-equality
from typing import Tuple

t1: Tuple[str, ...]
t2: Tuple[str, str]

if 1 in t1:  # Non-overlapping container check (expected)
    pass

if 1 in t2:  # No error (unexpected!)
    pass
```

Resolving patch:
diff --git a/mypy/checker.py b/mypy/checker.py
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -3461,6 +3461,8 @@ def analyze_container_item_type(self, typ: Type) -> Optional[Type]:
             super_instance = map_instance_to_supertype(typ, supertype)
             assert len(super_instance.args) == 1
             return super_instance.args[0]
+        if isinstance(typ, TupleType):
+            return self.analyze_container_item_type(tuple_fallback(typ))
         return None
 
     def analyze_index_variables(self, index: Expression, item_type: Type,


Test patch:
diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test
--- a/test-data/unit/check-expressions.test
+++ b/test-data/unit/check-expressions.test
@@ -2754,6 +2754,13 @@ assert u'foo' == 'foo'
 assert u'foo' == u'bar'  # E: Non-overlapping equality check (left operand type: "Literal[u'foo']", right operand type: "Literal[u'bar']")
 [builtins_py2 fixtures/python2.pyi]
 
+[case testStrictEqualityWithFixedLengthTupleInCheck]
+# flags: --strict-equality
+if 1 in ('x', 'y'):  # E: Non-overlapping container check (element type: "int", container item type: "str")
+    pass
+[builtins fixtures/tuple.pyi]
+[typing fixtures/typing-full.pyi]
+
 [case testUnimportedHintAny]
 def f(x: Any) -> None:  # E: Name 'Any' is not defined \
                         # N: Did you forget to import it from "typing"? (Suggestion: "from typing import Any")
Repository: python/mypy

Issue:
Unreachable Warning Code
There are sometimes cases where I'd like deliberately put something in a statically-unreachable section---maybe some asserts, maybe some debug info, etc.---in case it does hit that case at runtime.  I currently silence them with a `# type: ignore[misc]` which isn't particularly informative to someone reading the code.  Could we give `unreachable` its own dedicated error/warning code?

EDIT: just so it's clear, I do want to keep the warning on to detect legitimate issues.


Discussion:
Sure, PR is welcome!

Resolving patch:
diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py
--- a/mypy/errorcodes.py
+++ b/mypy/errorcodes.py
@@ -103,6 +103,8 @@ def __str__(self) -> str:
 NO_ANY_RETURN = ErrorCode(
     'no-any-return', 'Reject returning value with "Any" type if return type is not "Any"',
     'General')  # type: Final
+UNREACHABLE = ErrorCode(
+    'unreachable', "Warn about unreachable statements or expressions", 'General')  # type: Final
 
 # Syntax errors are often blocking.
 SYNTAX = ErrorCode(
diff --git a/mypy/messages.py b/mypy/messages.py
--- a/mypy/messages.py
+++ b/mypy/messages.py
@@ -1235,7 +1235,7 @@ def note_call(self,
                   context, code=code)
 
     def unreachable_statement(self, context: Context) -> None:
-        self.fail("Statement is unreachable", context)
+        self.fail("Statement is unreachable", context, code=codes.UNREACHABLE)
 
     def redundant_left_operand(self, op_name: str, context: Context) -> None:
         """Indicates that the left operand of a boolean expression is redundant:
@@ -1249,7 +1249,8 @@ def redundant_right_operand(self, op_name: str, context: Context) -> None:
         it does not change the truth value of the entire condition as a whole.
         'op_name' should either be the string "and" or the string "or".
         """
-        self.fail("Right operand of '{}' is never evaluated".format(op_name), context)
+        self.fail("Right operand of '{}' is never evaluated".format(op_name),
+                  context, code=codes.UNREACHABLE)
 
     def redundant_condition_in_comprehension(self, truthiness: bool, context: Context) -> None:
         self.redundant_expr("If condition in comprehension", truthiness, context)
@@ -1261,7 +1262,8 @@ def redundant_condition_in_assert(self, truthiness: bool, context: Context) -> N
         self.redundant_expr("Condition in assert", truthiness, context)
 
     def redundant_expr(self, description: str, truthiness: bool, context: Context) -> None:
-        self.fail("{} is always {}".format(description, str(truthiness).lower()), context)
+        self.fail("{} is always {}".format(description, str(truthiness).lower()),
+                  context, code=codes.UNREACHABLE)
 
     def report_protocol_problems(self,
                                  subtype: Union[Instance, TupleType, TypedDictType],


Test patch:
Repository: python/mypy

Issue:
Incorrect join of str and subclass of unicode
Joins of `str` and a subclass of `unicode` (in Python 2) are calculated inconsistently:

```py
class S(unicode): pass

reveal_type('' if bool() else S())  # Sequence[unicode]
reveal_type(S() if bool() else '')  # unicode
```

This is probably caused by the promotion from `str` to `unicode` being handled differently depending on the order of the join operands.


Discussion:

Resolving patch:
diff --git a/mypy/join.py b/mypy/join.py
--- a/mypy/join.py
+++ b/mypy/join.py
@@ -353,8 +353,7 @@ def default(self, typ: Type) -> ProperType:
 
 
 def join_instances(t: Instance, s: Instance) -> ProperType:
-    """Calculate the join of two instance types.
-    """
+    """Calculate the join of two instance types."""
     if t.type == s.type:
         # Simplest case: join two types with the same base type (but
         # potentially different arguments).
@@ -395,6 +394,11 @@ def join_instances_via_supertype(t: Instance, s: Instance) -> ProperType:
         if best is None or is_better(res, best):
             best = res
     assert best is not None
+    promote = get_proper_type(t.type._promote)
+    if isinstance(promote, Instance):
+        res = join_instances(promote, s)
+        if is_better(res, best):
+            best = res
     return best
 
 


Test patch:
diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test
--- a/test-data/unit/check-inference.test
+++ b/test-data/unit/check-inference.test
@@ -3137,3 +3137,10 @@ y = defaultdict(list)  # E: Need type annotation for 'y'
 y['a'] = []
 reveal_type(y)  # N: Revealed type is 'collections.defaultdict[Any, Any]'
 [builtins fixtures/dict.pyi]
+
+[case testJoinOfStrAndUnicodeSubclass_python2]
+class S(unicode): pass
+reveal_type(S() if bool() else '')  # N: Revealed type is 'builtins.unicode'
+reveal_type('' if bool() else S())  # N: Revealed type is 'builtins.unicode'
+reveal_type(S() if bool() else str())  # N: Revealed type is 'builtins.unicode'
+reveal_type(str() if bool() else S())  # N: Revealed type is 'builtins.unicode'
Repository: python/mypy

Issue:
typeshed CI is broken
It looks like #8405 breaks the mypy tests in typeshed CI

Details here:
https://travis-ci.org/python/typeshed/jobs/653578206
https://travis-ci.org/python/typeshed/builds/653578203

cc @JukkaL 


Discussion:
Maybe use abspath instead of normpath in is_typeshed_file?

Resolving patch:
diff --git a/mypy/util.py b/mypy/util.py
--- a/mypy/util.py
+++ b/mypy/util.py
@@ -705,4 +705,4 @@ def format_error(self, n_errors: int, n_files: int, n_sources: int,
 
 def is_typeshed_file(file: str) -> bool:
     # gross, but no other clear way to tell
-    return 'typeshed' in os.path.normpath(file).split(os.sep)
+    return 'typeshed' in os.path.abspath(file).split(os.sep)


Test patch:
Repository: python/mypy

Issue:
'if callable(fn)' should infer that 'fn' is not None
Reporting a bug.

Code.
```
fn = None
if callable(fn):
  fn()
```

Actual output.
```
$ mypy  xyz.py 
xyz.py:3: error: "None" not callable
Found 1 error in 1 file (checked 1 source file)
```

Expected behavior.
I would expect `if callable(fn)` to infer a non-None type.

This is a workaround, but shouldn't be necessary:
```
fn = None
if fn and callable(fn):
  fn()
```

mypy version.
```
$ mypy --version
mypy 0.770
$ python --version
Python 3.8.2
```



Discussion:
Yeah that seems reasonable. I'd review a PR for it. The code to update is `conditional_callable_type_map` in `checker.py`.

Resolving patch:
diff --git a/mypy/checker.py b/mypy/checker.py
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -3823,10 +3823,13 @@ def partition_by_callable(self, typ: Type,
         if isinstance(typ, AnyType):
             return [typ], [typ]
 
+        if isinstance(typ, NoneType):
+            return [], [typ]
+
         if isinstance(typ, UnionType):
             callables = []
             uncallables = []
-            for subtype in typ.relevant_items():
+            for subtype in typ.items:
                 # Use unsound_partition when handling unions in order to
                 # allow the expected type discrimination.
                 subcallables, subuncallables = self.partition_by_callable(subtype,


Test patch:
diff --git a/test-data/unit/check-callable.test b/test-data/unit/check-callable.test
--- a/test-data/unit/check-callable.test
+++ b/test-data/unit/check-callable.test
@@ -449,3 +449,27 @@ if callable():  # E: Too few arguments for "callable"
     pass
 
 [builtins fixtures/callable.pyi]
+
+[case testCallableWithNoneArgs]
+
+fn = None
+if callable(fn):
+  fn()
+
+[builtins fixtures/callable.pyi]
+
+[case testCallableUnionOfNoneAndCallable]
+
+from typing import Union, Callable
+
+def f() -> int:
+    return 42
+
+fn = f  # type: Union[None, Callable[[], int]]
+
+if callable(fn):
+    reveal_type(fn) # N: Revealed type is 'def () -> builtins.int'
+else:
+    reveal_type(fn) # N: Revealed type is 'None'
+
+[builtins fixtures/callable.pyi]
Repository: python/mypy

Issue:
Bytes TypedDict keys don't always generate errors
The expression `d[b'x']` does not generate an error in the example below, even though it's clearly broken, since `b'x' != 'x'`.

```
from typing import TypedDict

D = TypedDict("D", {"x": int})

def f(d: D) -> None:
    d[b'x']  # No error -- but should be
    d[b'x'] = 2  #  Argument 1 has incompatible type "bytes"; expected "str" -- OK
    d[b'xy']  # TypedDict "D" has no key 'xy'
```


Discussion:

Resolving patch:
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -2972,7 +2972,9 @@ def visit_typeddict_index_expr(self, td_type: TypedDictType, index: Expression)
                 if isinstance(key_type, Instance) and key_type.last_known_value is not None:
                     key_type = key_type.last_known_value
 
-                if isinstance(key_type, LiteralType) and isinstance(key_type.value, str):
+                if (isinstance(key_type, LiteralType)
+                        and isinstance(key_type.value, str)
+                        and key_type.fallback.type.fullname != 'builtins.bytes'):
                     key_names.append(key_type.value)
                 else:
                     self.msg.typeddict_key_must_be_string_literal(td_type, index)


Test patch:
diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test
--- a/test-data/unit/check-typeddict.test
+++ b/test-data/unit/check-typeddict.test
@@ -2054,3 +2054,18 @@ d: TD = dict()
 d2: TD = dict(foo=1)
 [builtins fixtures/dict.pyi]
 [typing fixtures/typing-typeddict.pyi]
+
+[case testTypedDictBytesKey]
+from typing import TypedDict
+
+class TD(TypedDict):
+    foo: int
+
+d: TD = {b'foo': 2} # E: Expected TypedDict key to be string literal
+d[b'foo'] = 3 # E: TypedDict key must be a string literal; expected one of ('foo') \
+    # E: Argument 1 has incompatible type "bytes"; expected "str"
+d[b'foo'] # E: TypedDict key must be a string literal; expected one of ('foo')
+d[3] # E: TypedDict key must be a string literal; expected one of ('foo')
+d[True] # E: TypedDict key must be a string literal; expected one of ('foo')
+[builtins fixtures/dict.pyi]
+[typing fixtures/typing-typeddict.pyi]
Repository: python/mypy

Issue:
Non-overlapping identity check false-positive starting in 0.780
https://mypy-play.net/?mypy=latest&python=3.8&flags=strict&gist=9b082c260ecb9586b358a06c8583edc2

```
class A:
    y: bool
    def update(self) -> None:
        pass
    
a = A()
assert a.y is True
a.update()
assert a.y is False
```

gives

```
main.py:9: error: Non-overlapping identity check (left operand type: "Literal[True]", right operand type: "Literal[False]")
Found 1 error in 1 file (checked 1 source file)
```

This may be reasonable opinionated behavior, but wanted to flag it as a behavior change between 0.770 and 0.780
I would personally consider this to be a false positive. It's not obvious how to change the source code to make mypy happy here.


Discussion:

Resolving patch:
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -2306,6 +2306,10 @@ def dangerous_comparison(self, left: Type, right: Type,
                 left = map_instance_to_supertype(left, abstract_set)
                 right = map_instance_to_supertype(right, abstract_set)
                 return not is_overlapping_types(left.args[0], right.args[0])
+        if isinstance(left, LiteralType) and isinstance(right, LiteralType):
+            if isinstance(left.value, bool) and isinstance(right.value, bool):
+                # Comparing different booleans is not dangerous.
+                return False
         return not is_overlapping_types(left, right, ignore_promotions=False)
 
     def get_operator_method(self, op: str) -> str:


Test patch:
diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test
--- a/test-data/unit/check-literal.test
+++ b/test-data/unit/check-literal.test
@@ -3228,3 +3228,18 @@ y: Literal[F.A]
 reveal_type(x)  # N: Revealed type is 'Literal[__main__.Foo.A]'
 reveal_type(y)  # N: Revealed type is 'Literal[__main__.Foo.A]'
 [builtins fixtures/tuple.pyi]
+
+[case testStrictEqualityLiteralTrueVsFalse]
+# mypy: strict-equality
+
+class C:
+    a = True
+
+    def update(self) -> None:
+        self.a = False
+
+c = C()
+assert c.a is True
+c.update()
+assert c.a is False
+[builtins fixtures/bool.pyi]