Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -930,9 +930,9 @@ def add_invertible_flag(
)

add_invertible_flag(
"--strict-bytes",
default=False,
strict_flag=True,
"--no-strict-bytes",
default=True,
dest="strict_bytes",
help="Disable treating bytearray and memoryview as subtypes of bytes",
group=strictness_group,
)
Expand Down
12 changes: 6 additions & 6 deletions mypy/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def __init__(self) -> None:
self.strict_equality_for_none = False

# Disable treating bytearray and memoryview as subtypes of bytes
self.strict_bytes = False
self.strict_bytes = True

# Deprecated, use extra_checks instead.
self.strict_concatenate = False
Expand Down Expand Up @@ -407,8 +407,8 @@ def __init__(self) -> None:
# (undocumented feature).
self.export_ref_info = False

self.disable_bytearray_promotion = False
self.disable_memoryview_promotion = False
self.disable_bytearray_promotion = True
self.disable_memoryview_promotion = True

# Sets custom output format
self.output: str | None = None
Expand Down Expand Up @@ -471,9 +471,9 @@ def process_strict_bytes(self) -> None:
# backwards compatibility
self.disable_bytearray_promotion = True
self.disable_memoryview_promotion = True
elif self.disable_bytearray_promotion and self.disable_memoryview_promotion:
# forwards compatibility
self.strict_bytes = True
else:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was done in #19002 and I don't think that's correct

There is a weird interaction that exists between specifying both --no-strict-bytes and one of these (undocumented) flags, but maybe that is a better fit for more generalised "preset" handling in config

self.disable_bytearray_promotion = False
self.disable_memoryview_promotion = False

def apply_changes(self, changes: dict[str, object]) -> Options:
# Note: effects of this method *must* be idempotent.
Expand Down
4 changes: 2 additions & 2 deletions mypy/test/testargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from mypy.main import infer_python_executable, process_options
from mypy.options import Options
from mypy.test.helpers import Suite, assert_equal
from mypy.test.helpers import Suite


class ArgSuite(Suite):
Expand All @@ -22,7 +22,7 @@ def test_coherence(self) -> None:
_, parsed_options = process_options([], require_targets=False)
# FIX: test this too. Requires changing working dir to avoid finding 'setup.cfg'
options.config_file = parsed_options.config_file
assert_equal(options.snapshot(), parsed_options.snapshot())
assert options.snapshot() == parsed_options.snapshot()

def test_executable_inference(self) -> None:
"""Test the --python-executable flag with --python-version"""
Expand Down
1 change: 1 addition & 0 deletions mypyc/test-data/fixtures/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ def __getitem__(self, i: int) -> int: ...
@overload
def __getitem__(self, i: slice) -> bytearray: ...
def decode(self, x: str = ..., y: str = ...) -> str: ...
def join(self, x: Iterable[object]) -> bytes: ...
def startswith(self, t: bytes) -> bool: ...
def endswith(self, t: bytes) -> bool: ...

Expand Down
66 changes: 0 additions & 66 deletions test-data/unit/check-flags.test
Original file line number Diff line number Diff line change
Expand Up @@ -2542,55 +2542,6 @@ x: int = "" # E: Incompatible types in assignment (expression has type "str", v
# flags: --hide-error-codes
x: int = "" # E: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testDisableBytearrayPromotion]
# flags: --disable-bytearray-promotion --strict-equality --warn-unreachable
def f(x: bytes) -> None: ...
f(bytearray(b"asdf")) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
f(memoryview(b"asdf"))
ba = bytearray(b"")
if ba == b"":
f(ba) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
if b"" == ba:
f(ba) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
if ba == bytes():
f(ba) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
if bytes() == ba:
f(ba) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
[builtins fixtures/primitives.pyi]

[case testDisableMemoryviewPromotion]
# flags: --disable-memoryview-promotion
def f(x: bytes) -> None: ...
f(bytearray(b"asdf"))
f(memoryview(b"asdf")) # E: Argument 1 to "f" has incompatible type "memoryview"; expected "bytes"
[builtins fixtures/primitives.pyi]

[case testDisableBytearrayMemoryviewPromotionStrictEquality]
# flags: --disable-bytearray-promotion --disable-memoryview-promotion --strict-equality
def f(x: bytes, y: bytearray, z: memoryview) -> None:
x == y
y == z
x == z
97 in x
97 in y
97 in z
x in y
x in z
[builtins fixtures/primitives.pyi]

[case testEnableBytearrayMemoryviewPromotionStrictEquality]
# flags: --strict-equality
def f(x: bytes, y: bytearray, z: memoryview) -> None:
x == y
y == z
x == z
97 in x
97 in y
97 in z
x in y
x in z
[builtins fixtures/primitives.pyi]

[case testStrictBytes]
# flags: --strict-bytes
def f(x: bytes) -> None: ...
Expand All @@ -2605,23 +2556,6 @@ f(bytearray(b"asdf"))
f(memoryview(b"asdf"))
[builtins fixtures/primitives.pyi]

[case testStrictBytesDisabledByDefault]
# TODO: probably change this default in Mypy v2.0, with https://github.com/python/mypy/pull/18371
# (this would also obsolete the testStrictBytesEnabledByStrict test, below)
def f(x: bytes) -> None: ...
f(bytearray(b"asdf"))
f(memoryview(b"asdf"))
[builtins fixtures/primitives.pyi]

[case testStrictBytesEnabledByStrict]
# flags: --strict --disable-error-code type-arg
# The type-arg thing is just work around the primitives.pyi isinstance Tuple not having type parameters,
# which isn't important for this.
def f(x: bytes) -> None: ...
f(bytearray(b"asdf")) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
f(memoryview(b"asdf")) # E: Argument 1 to "f" has incompatible type "memoryview"; expected "bytes"
[builtins fixtures/primitives.pyi]

[case testNoCrashFollowImportsForStubs]
# flags: --config-file tmp/mypy.ini
{**{"x": "y"}}
Expand Down
60 changes: 60 additions & 0 deletions test-data/unit/check-type-promotion.test
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,75 @@ f(1)
[builtins fixtures/primitives.pyi]

[case testPromoteBytearrayToByte]
# flags: --no-strict-bytes
def f(x: bytes) -> None: pass
f(bytearray(b''))
[builtins fixtures/primitives.pyi]

[case testPromoteMemoryviewToBytes]
# flags: --no-strict-bytes
def f(x: bytes) -> None: pass
f(memoryview(b''))
[builtins fixtures/primitives.pyi]

[case testDisableBytearrayMemoryviewPromotion]
# flags: --strict-bytes --strict-equality --warn-unreachable
def f(x: bytes) -> None: ...
f(bytearray(b"asdf")) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
f(memoryview(b"asdf")) # E: Argument 1 to "f" has incompatible type "memoryview"; expected "bytes"
ba = bytearray(b"")
if ba == b"":
f(ba) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
if b"" == ba:
f(ba) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
if ba == bytes():
f(ba) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
if bytes() == ba:
f(ba) # E: Argument 1 to "f" has incompatible type "bytearray"; expected "bytes"
[builtins fixtures/primitives.pyi]

[case testEnableBytearrayMemoryviewPromotion]
# flags: --no-strict-bytes --strict-equality --warn-unreachable
def f(x: bytes) -> None: ...
f(bytearray(b"asdf"))
f(memoryview(b"asdf"))
ba = bytearray(b"")
if ba == b"":
f(ba)
if b"" == ba:
f(ba)
if ba == bytes():
f(ba)
if bytes() == ba:
f(ba)
[builtins fixtures/primitives.pyi]

[case testDisableBytearrayMemoryviewPromotionStrictEquality]
# flags: --strict-equality --strict-bytes
def f(x: bytes, y: bytearray, z: memoryview) -> None:
x == y
y == z
x == z
97 in x
97 in y
97 in z
x in y
x in z
[builtins fixtures/primitives.pyi]

[case testEnableBytearrayMemoryviewPromotionStrictEquality]
# flags: --strict-equality --no-strict-bytes
def f(x: bytes, y: bytearray, z: memoryview) -> None:
x == y
y == z
x == z
97 in x
97 in y
97 in z
x in y
x in z
[builtins fixtures/primitives.pyi]

[case testNarrowingDownFromPromoteTargetType]
y = 0.0
y = 1
Expand Down