Skip to content

Commit

Permalink
Address errors found by mypy.stubtype
Browse files Browse the repository at this point in the history
These errors fell into one of the following categories

- Stubs that existed in the .pyi file that had no corresponding function
  in the .py file (likely becuase functionality was removed but the stub
  was not updated)
- The annotation in the .pyi file did not match the annotation in the .py
  file
- The .pyi file simply had no entry for a function in the .py file
- Annotations existed, but they were in the .py file and not the .pyi
  file

The last category is the most interesting. The behavior of mypy is to
prioritize the .pyi file if it exists, which means that if there is a
.pyi file any annotations in the .py file are ignored by mypy. This
behavior was surprising, since the expectation is that the annotations
would be the union of the .pyi and .py file, but instead if pulls from
only the .pyi file (likely to avoid conflicts if annotations mismatch).

Going forward, hopefully the presence of the mypy.stubtype check will
ensure that new code adds annotations to the .pyi file instead of in the
.py file.
  • Loading branch information
SethMMorton committed Dec 21, 2024
1 parent c32588c commit 466a031
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 99 deletions.
73 changes: 10 additions & 63 deletions path/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

from __future__ import annotations

import builtins
import contextlib
import datetime
import errno
Expand Down Expand Up @@ -52,19 +51,6 @@
with contextlib.suppress(ImportError):
import grp

from typing import (
TYPE_CHECKING,
Callable,
Iterator,
overload,
)

if TYPE_CHECKING:
from _typeshed import (
OpenBinaryMode,
OpenTextMode,
)

from . import classes, masks, matchers
from .compat.py38 import removeprefix, removesuffix

Expand Down Expand Up @@ -232,7 +218,7 @@ def cwd(cls):
return cls(os.getcwd())

@classmethod
def home(cls) -> Path:
def home(cls):
return cls(os.path.expanduser('~'))

#
Expand Down Expand Up @@ -660,45 +646,6 @@ def bytes(self):
with self.open('rb') as f:
return f.read()

@overload
def chunks(
self,
size: int,
mode: OpenTextMode = ...,
buffering: int = ...,
encoding: str | None = ...,
errors: str | None = ...,
newline: str | None = ...,
closefd: bool = ...,
opener: Callable[[str, int], int] | None = ...,
) -> Iterator[str]: ...

@overload
def chunks(
self,
size: int,
mode: OpenBinaryMode,
buffering: int = ...,
encoding: str | None = ...,
errors: str | None = ...,
newline: str | None = ...,
closefd: bool = ...,
opener: Callable[[str, int], int] | None = ...,
) -> Iterator[builtins.bytes]: ...

@overload
def chunks(
self,
size: int,
mode: str,
buffering: int = ...,
encoding: str | None = ...,
errors: str | None = ...,
newline: str | None = ...,
closefd: bool = ...,
opener: Callable[[str, int], int] | None = ...,
) -> Iterator[str | builtins.bytes]: ...

def chunks(self, size, *args, **kwargs):
"""Returns a generator yielding chunks of the file, so it can
be read piece by piece with a simple for loop.
Expand Down Expand Up @@ -742,12 +689,12 @@ def read_bytes(self):

def write_text(
self,
text: str,
encoding: str | None = None,
errors: str = 'strict',
linesep: str | None = os.linesep,
append: bool = False,
) -> None:
text,
encoding=None,
errors='strict',
linesep=os.linesep,
append=False,
):
r"""Write the given text to this file.
The default behavior is to overwrite any existing file;
Expand Down Expand Up @@ -1199,7 +1146,7 @@ def renames(self, new):
os.renames(self, new)
return self._next_class(new)

def replace(self, target_or_old: Path | str, *args) -> Path:
def replace(self, target_or_old, *args):
"""
Replace a path or substitute substrings.
Expand Down Expand Up @@ -1314,7 +1261,7 @@ def remove_p(self):

# --- Links

def hardlink_to(self, target: str) -> None:
def hardlink_to(self, target):
"""
Create a hard link at self, pointing to target.
Expand All @@ -1330,7 +1277,7 @@ def link(self, newpath):
os.link(self, newpath)
return self._next_class(newpath)

def symlink_to(self, target: str, target_is_directory: bool = False) -> None:
def symlink_to(self, target, target_is_directory=False):
"""
Create a symbolic link at self, pointing to target.
Expand Down
Loading

0 comments on commit 466a031

Please sign in to comment.