Skip to content

bytes formatting incorrect in python 3 #2070

Closed

Description

@euresti

The following runs properly:

def foo(a: bytes, b:bytes) -> bytes:
    return b'%s:%s' % (a, b)
assert foo(b'a', b'b') == b'a:b'

However mypy complains:

example.py: note: In function "foo":
example.py:2: error: Incompatible return value type (got "str", expected "bytes")

Activity

  1. added this to the milestone on Aug 31, 2016
  2. gvanrossum commented on Aug 31, 2016

    @gvanrossum
    Member

    Oooh, good catch! I suspect the % checking code for bytes was too hastily adapted from the same for strings. There are many things wrong there: the checker always assumes the full formatting language used for str, while bytes have a separate (weaker) language. It always returns builtins.str as the return type (which is actually the error you're seeing). And I don't think the checker is invoked for unicode strings in PY2 mode...

  3. gvanrossum commented on Aug 31, 2016

    @gvanrossum
    Member

    (Also, though not affecting mypy's behavior, typeshed has no __mod__ operator for bytes defined. It's new in Python 3.5, so mypy really should check python_version too.)

  4. gvanrossum commented on Sep 15, 2016

    @gvanrossum
    Member

    @buckbaskin If you want to tackle this that's great! IIRC it should be a fairly simple refactoring and doing this will get you up to speed with how to run the tests. (Hint: pip install -r test-requirements.txt and then you can run tests with py.test, see README.md.)

  5. buckbaskin commented on Sep 21, 2016

    @buckbaskin
    Contributor

    It looks like the type checking code for bytes is just to use the string version (see checkexpr.py). The lines effectively check to see if it either matches StrExpr or BytesExpr and casts to StrExpr if it matches either one. This leads to the bug, where the BytesExpr is supposed to stay a BytesExpr.

    Would the correct way to fix this be to create a new checker for Bytes? Or possibly to add a method to what is now StringFormatterChecker that checks bytes instead?

  6. gvanrossum commented on Sep 22, 2016

    @gvanrossum
    Member

    The quick and dirty fix would be to just change the return type to be the same as the arg type. But the bytes % operator supports a smaller mini-language, so technically StringFormatterChecker should grow another method to handle that. Or maybe a subclass? The main thing that ought to change seems to be conversion_type().

    But I'll settle for the quick and dirty fix as a first installment!

  7. buckbaskin commented on Sep 22, 2016

    @buckbaskin
    Contributor

    In the pull request, I added a separate method that handles BytesExpr. I don't think that the type checking for what can be interpolated into a b'' is correct (it still uses the logic for a string) but the code example given in the bug no longer has an error.
    On a parallel thought, is there a place where I could include a test that will check to see that something like the above example passes without error? I ran a manual check before I made the pull request.

  8. gvanrossum commented on Sep 22, 2016

    @gvanrossum
    Member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions