Skip to content

Use Union[bytes, Text] instead of AnyStr #1819

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 2 commits into from
Jan 11, 2018
Merged

Conversation

n8henrie
Copy link
Contributor

@n8henrie n8henrie commented Jan 9, 2018

It seems that AnyStr has the main advantage of ensuring that multiple arguments (or argument(s) and return values) have the same type (i.e. str and bytes are both okay but shouldn't be mixed). However it makes it more difficult to cast to a single type.

With a Union, something like:

def foo(a: Union[bytes, Text]) -> Text:
    if isinstance(a, bytes):
        a = a.decode()
    return "Hello, " + a

works fine. With AnyStr, you have to define a new intermediate variable, something like:

def foo(a: AnyStr) -> str:
    if isinstance(a, bytes):
        b = a.decode()
    else:
        b = a
    return "Hello, " + b

If there's no advantage to using AnyStr (since there's no other AnyStr argument or return value), I think the Union would be simpler, have no significant disadvantage, and there is precedent for similar changes.

It's only the case that if there's exactly one parameter of type exactly AnyStr, and no other use of AnyStr in the signature, then Union[str, bytes] should be acceptable.

- gvanrossum

Discussion:

It seems that AnyStr has the main advantage of ensuring that multiple arguments (or argument(s) and return values) have the same type (i.e. `str` and `bytes` are both okay but shouldn't be mixed). However it makes it significantly more difficult to cast to a single type.

With a Union, something like:

```python
def foo(a: Union[bytes, Text]) -> Text:
    if isinstance(a, bytes):
        a = a.decode()
    return "Hello, " + a
```

works fine. With AnyStr, you have to define a new intermediate variable, something like:

```python
def foo(a: AnyStr) -> str:
    if isinstance(a, bytes):
        b = a.decode()
    else:
        b = a
    return "Hello, " + b
```

If there's no advantage to using AnyStr (since there's no other AnyStr argument or return value), I think the Union would be simpler, have no significant disadvantage, and there is [precedent for similar changes](python#1054).

> It's only the case that if there's exactly one parameter of type exactly AnyStr, and no other use of AnyStr in the signature, then Union[str, bytes] should be acceptable.

-  [gvanrossum](python#439 (comment))

Discussion: 

- python#1054
- python/mypy#1141
- python#439
@matthiaskramm
Copy link
Contributor

stdlib/3.4/asyncio/subprocess.pyi:21: error: Signature of "pipe_data_received" incompatible with supertype "SubprocessProtocol"

@matthiaskramm matthiaskramm merged commit 9429ac0 into python:master Jan 11, 2018
@n8henrie n8henrie deleted the patch-5 branch January 11, 2018 21:33
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

Successfully merging this pull request may close these issues.

2 participants