Skip to content

VIP: Remove type ambiguity in bytes and string literals #1876

@iamdefinitelyahuman

Description

@iamdefinitelyahuman

Simple Summary

Bytes literals should require prepending with b, string literals should require not prepending with b.

As an example, the following contract currently compiles. I believe that every statement within bad should raise an InvalidLiteral exception:

@public
def good():
    a: bytes[3] = b'\x66\x6f\x6f'
    b: bytes[3] = b"foo"
    c: string[3] = "foo"

@public
def bad():
    a: bytes[3] = "foo"
    b: string[3] = b'\x66\x6f\x6f'
    c: string[3] = b"foo"

Motivation

Allowing literal bytes and strings to be interpreted as both string and bytes types introduces additional complexity in type checking. It becomes particularly burdensome within a for loop:

for i in ["foo", b'\x66\x6f\x6f', b"foo"]:
    # what is i?

Forcing the use of b"" for bytes, "" for strings makes code more readable and simplifies type checking.

Specification

Within the AST these types are differentiated as Str and Bytes. Implementing this will simply require more selective node class checks when parsing.

Backwards Compatibility

This is a breaking change, but updating contracts to use the new syntax will not be difficult.

Copyright

Copyright and related rights waived via CC0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions