Skip to content

Conversation

srittau
Copy link
Collaborator

@srittau srittau commented Mar 14, 2025

Cf. #10737

@srittau srittau marked this pull request as draft March 14, 2025 11:19

This comment has been minimized.

@srittau srittau added the topic: io I/O related issues label Mar 14, 2025
@srittau
Copy link
Collaborator Author

srittau commented Mar 14, 2025

Primer hits:

  • django-stubs (both hits): name field is annotated as str | None. I think having an explicit override here makes sense, as this is usually not an expected type by code accessing a name property.

This looks much better than I feared. I wish we had "kwonly" type vars, but I still think this is an improvement as it allows use to tighten the types to name fields of other I/O types in future PRs, which could lead to better type safety around this property with its rather unintuitive types.

@srittau srittau marked this pull request as ready for review March 14, 2025 12:14

This comment has been minimized.

Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

django-stubs (https://github.com/typeddjango/django-stubs)
+ django-stubs/db/models/fields/files.pyi:22: error: Incompatible types in assignment (expression has type "Optional[str]", base class "IO" defined the type as "str")  [assignment]
+ django-stubs/core/files/base.pyi:12: error: Incompatible types in assignment (expression has type "Optional[str]", base class "IO" defined the type as "str")  [assignment]

pytest-robotframework (https://github.com/detachhead/pytest-robotframework)
- pytest_robotframework/_internal/pytest/plugin.py:452: error: "_RedirectStream[IO[str]]" has no attribute "_stream"  [attr-defined]
+ pytest_robotframework/_internal/pytest/plugin.py:452: error: "_RedirectStream[IO[str, str]]" has no attribute "_stream"  [attr-defined]

discord.py (https://github.com/Rapptz/discord.py)
- ...:1014: note: "update" of "TypedDict" defined here
+ ...:1019: note: "update" of "TypedDict" defined here
- ...:1014: note: "update" of "TypedDict" defined here
+ ...:1019: note: "update" of "TypedDict" defined here

werkzeug (https://github.com/pallets/werkzeug)
- tests/test_wsgi.py:261: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes]]"  [arg-type]
+ tests/test_wsgi.py:261: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes, str]]"  [arg-type]
- tests/test_wsgi.py:265: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes]]"  [arg-type]
+ tests/test_wsgi.py:265: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes, str]]"  [arg-type]
- tests/test_wsgi.py:270: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes]]"  [arg-type]
+ tests/test_wsgi.py:270: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes, str]]"  [arg-type]
- tests/test_wsgi.py:274: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes]]"  [arg-type]
+ tests/test_wsgi.py:274: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes, str]]"  [arg-type]
- tests/test_wsgi.py:280: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes]]"  [arg-type]
+ tests/test_wsgi.py:280: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes, str]]"  [arg-type]
- tests/test_wsgi.py:288: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes]]"  [arg-type]
+ tests/test_wsgi.py:288: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes, str]]"  [arg-type]
- tests/test_wsgi.py:297: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes]]"  [arg-type]
+ tests/test_wsgi.py:297: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes, str]]"  [arg-type]
- tests/test_wsgi.py:305: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes]]"  [arg-type]
+ tests/test_wsgi.py:305: error: Argument 1 to "_RangeWrapper" has incompatible type "Union[Iterable[str], Iterable[bytes]]"; expected "Union[Iterable[bytes], IO[bytes, str]]"  [arg-type]
- tests/test_wrappers.py:465: error: Incompatible types in assignment (expression has type "LowercasingStream", variable has type "IO[bytes]")  [assignment]
+ tests/test_wrappers.py:465: error: Incompatible types in assignment (expression has type "LowercasingStream", variable has type "IO[bytes, str]")  [assignment]
- tests/test_test.py:166: error: Item "IO[bytes]" of "Optional[IO[bytes]]" has no attribute "getvalue"  [union-attr]
+ tests/test_test.py:166: error: Item "IO[bytes, str]" of "Optional[IO[bytes, str]]" has no attribute "getvalue"  [union-attr]
- tests/test_test.py:166: error: Item "None" of "Optional[IO[bytes]]" has no attribute "getvalue"  [union-attr]
+ tests/test_test.py:166: error: Item "None" of "Optional[IO[bytes, str]]" has no attribute "getvalue"  [union-attr]
- tests/test_test.py:168: error: Item "IO[bytes]" of "Optional[IO[bytes]]" has no attribute "getvalue"  [union-attr]
+ tests/test_test.py:168: error: Item "IO[bytes, str]" of "Optional[IO[bytes, str]]" has no attribute "getvalue"  [union-attr]
- tests/test_test.py:168: error: Item "None" of "Optional[IO[bytes]]" has no attribute "getvalue"  [union-attr]
+ tests/test_test.py:168: error: Item "None" of "Optional[IO[bytes, str]]" has no attribute "getvalue"  [union-attr]
- tests/test_test.py:438: error: Argument 2 to "add_file" of "FileMultiDict" has incompatible type "SpecialInput"; expected "Union[str, PathLike[str], IO[bytes], FileStorage]"  [arg-type]
+ tests/test_test.py:438: error: Argument 2 to "add_file" of "FileMultiDict" has incompatible type "SpecialInput"; expected "Union[str, PathLike[str], IO[bytes, str], FileStorage]"  [arg-type]
- tests/test_formparser.py:196: error: Non-overlapping equality check (left operand type: "tuple[IO[bytes], MultiDict[str, str], MultiDict[str, FileStorage]]", right operand type: "tuple[str, MultiDict[Never, Never], MultiDict[Never, Never]]")  [comparison-overlap]
+ tests/test_formparser.py:196: error: Non-overlapping equality check (left operand type: "tuple[IO[bytes, str], MultiDict[str, str], MultiDict[str, FileStorage]]", right operand type: "tuple[str, MultiDict[Never, Never], MultiDict[Never, Never]]")  [comparison-overlap]
- tests/test_formparser.py:196: error: Argument 1 to "parse" of "FormDataParser" has incompatible type "str"; expected "IO[bytes]"  [arg-type]
+ tests/test_formparser.py:196: error: Argument 1 to "parse" of "FormDataParser" has incompatible type "str"; expected "IO[bytes, str]"  [arg-type]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any], None] = ..., stdout: Union[int, IO[Any], None] = ..., stderr: Union[int, IO[Any], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[bool] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Optional[bool] = ..., encoding: str, errors: Optional[str] = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[str]
+ src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any, str], None] = ..., stdout: Union[int, IO[Any, str], None] = ..., stderr: Union[int, IO[Any, str], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[bool] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Optional[bool] = ..., encoding: str, errors: Optional[str] = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[str]
- src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any], None] = ..., stdout: Union[int, IO[Any], None] = ..., stderr: Union[int, IO[Any], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[bool] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Optional[bool] = ..., encoding: Optional[str] = ..., errors: str, user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[str]
+ src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any, str], None] = ..., stdout: Union[int, IO[Any, str], None] = ..., stderr: Union[int, IO[Any, str], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[bool] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Optional[bool] = ..., encoding: Optional[str] = ..., errors: str, user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[str]
- src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any], None] = ..., stdout: Union[int, IO[Any], None] = ..., stderr: Union[int, IO[Any], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., *, universal_newlines: Literal[True], startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., text: Optional[bool] = ..., encoding: Optional[str] = ..., errors: Optional[str] = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[str]
+ src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any, str], None] = ..., stdout: Union[int, IO[Any, str], None] = ..., stderr: Union[int, IO[Any, str], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., *, universal_newlines: Literal[True], startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., text: Optional[bool] = ..., encoding: Optional[str] = ..., errors: Optional[str] = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[str]
- src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any], None] = ..., stdout: Union[int, IO[Any], None] = ..., stderr: Union[int, IO[Any], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[bool] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Literal[True], encoding: Optional[str] = ..., errors: Optional[str] = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[str]
+ src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any, str], None] = ..., stdout: Union[int, IO[Any, str], None] = ..., stderr: Union[int, IO[Any, str], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[bool] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Literal[True], encoding: Optional[str] = ..., errors: Optional[str] = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[str]
- src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any], None] = ..., stdout: Union[int, IO[Any], None] = ..., stderr: Union[int, IO[Any], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[Literal[False]] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Optional[Literal[False]] = ..., encoding: None = ..., errors: None = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[bytes]
+ src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any, str], None] = ..., stdout: Union[int, IO[Any, str], None] = ..., stderr: Union[int, IO[Any, str], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[Literal[False]] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Optional[Literal[False]] = ..., encoding: None = ..., errors: None = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[bytes]
- src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any], None] = ..., stdout: Union[int, IO[Any], None] = ..., stderr: Union[int, IO[Any], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[bool] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Optional[bool] = ..., encoding: Optional[str] = ..., errors: Optional[str] = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[Any]
+ src/prefect/cli/shell.py:99: note:     def [AnyStr: (str, bytes)] __init__(self, args: Union[Union[str, bytes, PathLike[str], PathLike[bytes]], Sequence[Union[str, bytes, PathLike[str], PathLike[bytes]]]], bufsize: int = ..., executable: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., stdin: Union[int, IO[Any, str], None] = ..., stdout: Union[int, IO[Any, str], None] = ..., stderr: Union[int, IO[Any, str], None] = ..., preexec_fn: Optional[Callable[[], Any]] = ..., close_fds: bool = ..., shell: bool = ..., cwd: Union[str, bytes, PathLike[str], PathLike[bytes], None] = ..., env: Union[Mapping[bytes, Union[str, bytes, PathLike[str], PathLike[bytes]]], Mapping[str, Union[str, bytes, PathLike[str], PathLike[bytes]]], None] = ..., universal_newlines: Optional[bool] = ..., startupinfo: Optional[Any] = ..., creationflags: int = ..., restore_signals: bool = ..., start_new_session: bool = ..., pass_fds: Collection[int] = ..., *, text: Optional[bool] = ..., encoding: Optional[str] = ..., errors: Optional[str] = ..., user: Union[str, int, None] = ..., group: Union[str, int, None] = ..., extra_groups: Optional[Iterable[Union[str, int]]] = ..., umask: int = ...) -> Popen[Any]
- src/prefect/cli/shell.py:106: error: Incompatible types in assignment (expression has type "Callable[[IO[str], list[str]], None]", variable has type "Callable[[IO[str], Callable[[str], None]], None]")  [assignment]
+ src/prefect/cli/shell.py:106: error: Incompatible types in assignment (expression has type "Callable[[IO[str, str], list[str]], None]", variable has type "Callable[[IO[str, str], Callable[[str], None]], None]")  [assignment]

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

Labels

topic: io I/O related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant