Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
Copy Markdown
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