Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Respectos.Pathlike#2086

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
George-Ogden wants to merge18 commits intogitpython-developers:main
base:main
Choose a base branch
Loading
fromGeorge-Ogden:true-pathlike
Draft
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
18 commits
Select commitHold shift + click to select a range
e3f38ff
Move clone tests into dedicated file
George-OgdenNov 27, 2025
24abf10
Allow Pathlike urls and destinations when cloning
George-OgdenNov 27, 2025
ad1ae5f
Simplify logic with direct path conversion
George-OgdenNov 27, 2025
5d26325
Allow Pathlike paths when creating a git repo
George-OgdenNov 27, 2025
59c3c80
Fix missing path conversion
George-OgdenNov 27, 2025
91d4cc5
Use os.fspath instead of __fspath__ for reading paths
George-OgdenNov 28, 2025
0414bf7
Replace extra occurrences of str with fspath
George-OgdenNov 28, 2025
3801505
Convert paths in constructors and large function calls
George-OgdenNov 28, 2025
086e832
Fix union type conversion to path
George-OgdenNov 28, 2025
b3908ed
Use converted file path
George-OgdenNov 29, 2025
50aea99
Remove redundant `fspath`
George-OgdenNov 29, 2025
57a3af1
Remove redundant `fspath`
George-OgdenNov 29, 2025
df8087a
Remove a large number of redundant fspaths
George-OgdenNov 29, 2025
1722561
Remove redundant str call
George-OgdenNov 29, 2025
921ca8a
Limit mypy version due to Cygwin errors
George-OgdenNov 29, 2025
b5abe0f
Merge branch 'main' into true-pathlike
George-OgdenNov 29, 2025
12e15ba
Validate every fspath with tests
George-OgdenNov 29, 2025
8434967
Fix type hints
George-OgdenNov 29, 2025
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

Some comments aren't visible on the classic Files Changed page.

2 changes: 1 addition & 1 deletiongit/config.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -578,7 +578,7 @@ def _included_paths(self) -> List[Tuple[str, str]]:
value,
)
if self._repo.git_dir:
if fnmatch.fnmatchcase(str(self._repo.git_dir), value):
if fnmatch.fnmatchcase(os.fspath(self._repo.git_dir), value):
paths += self.items(section)

elif keyword == "onbranch":
Expand Down
12 changes: 6 additions & 6 deletionsgit/index/base.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -407,7 +407,7 @@ def raise_exc(e: Exception) -> NoReturn:
r = str(self.repo.working_tree_dir)
rs = r + os.sep
for path in paths:
abs_path =str(path)
abs_path =os.fspath(path)
if not osp.isabs(abs_path):
abs_path = osp.join(r, path)
# END make absolute path
Expand DownExpand Up@@ -656,10 +656,10 @@ def _to_relative_path(self, path: PathLike) -> PathLike:
return path
if self.repo.bare:
raise InvalidGitRepositoryError("require non-bare repository")
if not osp.normpath(str(path)).startswith(str(self.repo.working_tree_dir)):
if not osp.normpath(path).startswith(str(self.repo.working_tree_dir)):
raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir))
result = os.path.relpath(path, self.repo.working_tree_dir)
ifstr(path).endswith(os.sep) and not result.endswith(os.sep):
ifos.fspath(path).endswith(os.sep) and not result.endswith(os.sep):
result += os.sep
return result

Expand DownExpand Up@@ -1036,7 +1036,7 @@ def remove(
args.append("--")

# Preprocess paths.
paths = self._items_to_rela_paths(items)
paths =list(map(os.fspath,self._items_to_rela_paths(items))) # type: ignore[arg-type]
removed_paths = self.repo.git.rm(args, paths, **kwargs).splitlines()

# Process output to gain proper paths.
Expand DownExpand Up@@ -1359,11 +1359,11 @@ def make_exc() -> GitCommandError:
try:
self.entries[(co_path, 0)]
except KeyError:
folder =str(co_path)
folder = co_path
if not folder.endswith("/"):
folder += "/"
for entry in self.entries.values():
ifstr(entry.path).startswith(folder):
ifos.fspath(entry.path).startswith(folder):
p = entry.path
self._write_path_to_stdin(proc, p, p, make_exc, fprogress, read_from_stdout=False)
checked_out_files.append(p)
Expand Down
2 changes: 1 addition & 1 deletiongit/index/fun.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -87,7 +87,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
return

env = os.environ.copy()
env["GIT_INDEX_FILE"] = safe_decode(str(index.path))
env["GIT_INDEX_FILE"] = safe_decode(os.fspath(index.path))
env["GIT_EDITOR"] = ":"
cmd = [hp]
try:
Expand Down
4 changes: 2 additions & 2 deletionsgit/index/util.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@

# typing ----------------------------------------------------------------------

from typing import Any, Callable, TYPE_CHECKING, Optional, Type
from typing import Any, Callable, TYPE_CHECKING, Optional, Type, cast

from git.types import Literal, PathLike, _T

Expand DownExpand Up@@ -106,7 +106,7 @@ def git_working_dir(func: Callable[..., _T]) -> Callable[..., _T]:
@wraps(func)
def set_git_working_dir(self: "IndexFile", *args: Any, **kwargs: Any) -> _T:
cur_wd = os.getcwd()
os.chdir(str(self.repo.working_tree_dir))
os.chdir(cast(PathLike,self.repo.working_tree_dir))
try:
return func(self, *args, **kwargs)
finally:
Expand Down
3 changes: 2 additions & 1 deletiongit/objects/blob.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@
__all__ = ["Blob"]

from mimetypes import guess_type
import os
import sys

if sys.version_info >= (3, 8):
Expand DownExpand Up@@ -44,5 +45,5 @@ def mime_type(self) -> str:
"""
guesses = None
if self.path:
guesses = guess_type(str(self.path))
guesses = guess_type(os.fspath(self.path))
return guesses and guesses[0] or self.DEFAULT_MIME_TYPE
4 changes: 2 additions & 2 deletionsgit/objects/submodule/base.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -352,7 +352,7 @@ def _clone_repo(
module_abspath_dir = osp.dirname(module_abspath)
if not osp.isdir(module_abspath_dir):
os.makedirs(module_abspath_dir)
module_checkout_path = osp.join(str(repo.working_tree_dir), path)
module_checkout_path = osp.join(repo.working_tree_dir, path) # type: ignore[arg-type]

if url.startswith("../"):
remote_name = cast("RemoteReference", repo.active_branch.tracking_branch()).remote_name
Expand DownExpand Up@@ -541,7 +541,7 @@ def add(
if sm.exists():
# Reretrieve submodule from tree.
try:
sm = repo.head.commit.tree[str(path)]
sm = repo.head.commit.tree[os.fspath(path)]
sm._name = name
return sm
except KeyError:
Expand Down
3 changes: 2 additions & 1 deletiongit/refs/reference.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,6 +3,7 @@

__all__ = ["Reference"]

import os
from git.util import IterableObj, LazyMixin

from .symbolic import SymbolicReference, T_References
Expand DownExpand Up@@ -65,7 +66,7 @@ def __init__(self, repo: "Repo", path: PathLike, check_path: bool = True) -> Non
If ``False``, you can provide any path.
Otherwise the path must start with the default path prefix of this type.
"""
if check_path and notstr(path).startswith(self._common_path_default + "/"):
if check_path and notos.fspath(path).startswith(self._common_path_default + "/"):
raise ValueError(f"Cannot instantiate {self.__class__.__name__!r} from path {path}")
self.path: str # SymbolicReference converts to string at the moment.
super().__init__(repo, path)
Expand Down
21 changes: 11 additions & 10 deletionsgit/refs/symbolic.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,7 @@
__all__ = ["SymbolicReference"]

import os
from pathlib import Path

from gitdb.exc import BadName, BadObject

Expand DownExpand Up@@ -76,10 +77,10 @@ class SymbolicReference:

def __init__(self, repo: "Repo", path: PathLike, check_path: bool = False) -> None:
self.repo = repo
self.path = path
self.path: PathLike = path

def __str__(self) -> str:
returnstr(self.path)
returnos.fspath(self.path)

def __repr__(self) -> str:
return '<git.%s "%s">' % (self.__class__.__name__, self.path)
Expand All@@ -103,7 +104,7 @@ def name(self) -> str:
In case of symbolic references, the shortest assumable name is the path
itself.
"""
returnstr(self.path)
returnos.fspath(self.path)

@property
def abspath(self) -> PathLike:
Expand DownExpand Up@@ -178,7 +179,7 @@ def _check_ref_name_valid(ref_path: PathLike) -> None:
"""
previous: Union[str, None] = None
one_before_previous: Union[str, None] = None
for c instr(ref_path):
for c inos.fspath(ref_path):
if c in " ~^:?*[\\":
raise ValueError(
f"Invalid reference '{ref_path}': references cannot contain spaces, tildes (~), carets (^),"
Expand DownExpand Up@@ -212,7 +213,7 @@ def _check_ref_name_valid(ref_path: PathLike) -> None:
raise ValueError(f"Invalid reference '{ref_path}': references cannot end with a forward slash (/)")
elif previous == "@" and one_before_previous is None:
raise ValueError(f"Invalid reference '{ref_path}': references cannot be '@'")
elif any(component.endswith(".lock") for component instr(ref_path).split("/")):
elif any(component.endswith(".lock") for component inPath(ref_path).parts):
raise ValueError(
f"Invalid reference '{ref_path}': references cannot have slash-separated components that end with"
" '.lock'"
Expand All@@ -235,7 +236,7 @@ def _get_ref_info_helper(
tokens: Union[None, List[str], Tuple[str, str]] = None
repodir = _git_dir(repo, ref_path)
try:
with open(os.path.join(repodir,str(ref_path)), "rt", encoding="UTF-8") as fp:
with open(os.path.join(repodir, ref_path), "rt", encoding="UTF-8") as fp: # type: ignore[arg-type]
value = fp.read().rstrip()
# Don't only split on spaces, but on whitespace, which allows to parse lines like:
# 60b64ef992065e2600bfef6187a97f92398a9144 branch 'master' of git-server:/path/to/repo
Expand DownExpand Up@@ -614,7 +615,7 @@ def to_full_path(cls, path: Union[PathLike, "SymbolicReference"]) -> PathLike:
full_ref_path = path
if not cls._common_path_default:
return full_ref_path
if notstr(path).startswith(cls._common_path_default + "/"):
if notos.fspath(path).startswith(cls._common_path_default + "/"):
full_ref_path = "%s/%s" % (cls._common_path_default, path)
return full_ref_path

Expand DownExpand Up@@ -706,7 +707,7 @@ def _create(
if not force and os.path.isfile(abs_ref_path):
target_data = str(target)
if isinstance(target, SymbolicReference):
target_data =str(target.path)
target_data =os.fspath(target.path)
if not resolve:
target_data = "ref: " + target_data
with open(abs_ref_path, "rb") as fd:
Expand DownExpand Up@@ -842,7 +843,7 @@ def _iter_items(

# Read packed refs.
for _sha, rela_path in cls._iter_packed_refs(repo):
if rela_path.startswith(str(common_path)):
if rela_path.startswith(os.fspath(common_path)):
rela_paths.add(rela_path)
# END relative path matches common path
# END packed refs reading
Expand DownExpand Up@@ -930,4 +931,4 @@ def from_path(cls: Type[T_References], repo: "Repo", path: PathLike) -> T_Refere

def is_remote(self) -> bool:
""":return: True if this symbolic reference points to a remote branch"""
returnstr(self.path).startswith(self._remote_common_path_default + "/")
returnos.fspath(self.path).startswith(self._remote_common_path_default + "/")
19 changes: 9 additions & 10 deletionsgit/repo/base.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -126,6 +126,7 @@ class Repo:
working_dir: PathLike
"""The working directory of the git command."""

# stored as string for easier processing, but annotated as path for clearer intention
_working_tree_dir: Optional[PathLike] = None

git_dir: PathLike
Expand DownExpand Up@@ -215,15 +216,13 @@ def __init__(
epath = path or os.getenv("GIT_DIR")
if not epath:
epath = os.getcwd()
epath = os.fspath(epath)
if Git.is_cygwin():
# Given how the tests are written, this seems more likely to catch Cygwin
# git used from Windows than Windows git used from Cygwin. Therefore
# changing to Cygwin-style paths is the relevant operation.
epath = cygpath(str(epath))
epath = cygpath(epath)

epath = epath or path or os.getcwd()
if not isinstance(epath, str):
epath = str(epath)
if expand_vars and re.search(self.re_envvars, epath):
warnings.warn(
"The use of environment variables in paths is deprecated"
Expand DownExpand Up@@ -957,7 +956,7 @@ def is_dirty(
if not submodules:
default_args.append("--ignore-submodules")
if path:
default_args.extend(["--",str(path)])
default_args.extend(["--",os.fspath(path)])
if index:
# diff index against HEAD.
if osp.isfile(self.index.path) and len(self.git.diff("--cached", *default_args)):
Expand DownExpand Up@@ -1357,9 +1356,9 @@ def _clone(
) -> "Repo":
odbt = kwargs.pop("odbt", odb_default_type)

#When pathlib.Path or other class-basedpath ispassed
if not isinstance(path, str):
path =str(path)
#url may be apathand this has no effect if itisa string
url = os.fspath(url)
Copy link
Member

Choose a reason for hiding this comment

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

URL is not a path though.

Copy link
ContributorAuthor

@George-OgdenGeorge-OgdenNov 29, 2025
edited
Loading

Choose a reason for hiding this comment

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

Here,url can be a path if you're cloning a local repo, and if it's notos.fspath will leave strings alone.

path =os.fspath(path)

## A bug win cygwin's Git, when `--bare` or `--separate-git-dir`
# it prepends the cwd or(?) the `url` into the `path, so::
Expand All@@ -1376,7 +1375,7 @@ def _clone(
multi = shlex.split(" ".join(multi_options))

if not allow_unsafe_protocols:
Git.check_unsafe_protocols(str(url))
Git.check_unsafe_protocols(url)
if not allow_unsafe_options:
Git.check_unsafe_options(options=list(kwargs.keys()), unsafe_options=cls.unsafe_git_clone_options)
if not allow_unsafe_options and multi_options:
Expand All@@ -1385,7 +1384,7 @@ def _clone(
proc = git.clone(
multi,
"--",
Git.polish_url(str(url)),
Git.polish_url(url),
clone_path,
with_extended_output=True,
as_process=True,
Expand Down
24 changes: 12 additions & 12 deletionsgit/util.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -36,7 +36,7 @@
import logging
import os
import os.path as osp
import pathlib
from pathlib import Path
import platform
import re
import shutil
Expand DownExpand Up@@ -272,9 +272,9 @@ def stream_copy(source: BinaryIO, destination: BinaryIO, chunk_size: int = 512 *
def join_path(a: PathLike, *p: PathLike) -> PathLike:
R"""Join path tokens together similar to osp.join, but always use ``/`` instead of
possibly ``\`` on Windows."""
path =str(a)
path =os.fspath(a)
for b in p:
b =str(b)
b =os.fspath(b)
if not b:
continue
if b.startswith("/"):
Expand All@@ -290,18 +290,18 @@ def join_path(a: PathLike, *p: PathLike) -> PathLike:
if sys.platform == "win32":

def to_native_path_windows(path: PathLike) -> PathLike:
path =str(path)
path =os.fspath(path)
return path.replace("/", "\\")

def to_native_path_linux(path: PathLike) -> str:
path =str(path)
path =os.fspath(path)
return path.replace("\\", "/")

to_native_path = to_native_path_windows
else:
# No need for any work on Linux.
def to_native_path_linux(path: PathLike) -> str:
returnstr(path)
returnos.fspath(path)

to_native_path = to_native_path_linux

Expand DownExpand Up@@ -372,7 +372,7 @@ def is_exec(fpath: str) -> bool:
progs = []
if not path:
path = os.environ["PATH"]
for folder instr(path).split(os.pathsep):
for folder inos.fspath(path).split(os.pathsep):
folder = folder.strip('"')
if folder:
exe_path = osp.join(folder, program)
Expand All@@ -397,7 +397,7 @@ def _cygexpath(drive: Optional[str], path: str) -> str:
p = cygpath(p)
elif drive:
p = "/proc/cygdrive/%s/%s" % (drive.lower(), p)
p_str =str(p) # ensure it is a str and not AnyPath
p_str =os.fspath(p) # ensure it is a str and not AnyPath
return p_str.replace("\\", "/")


Expand All@@ -418,7 +418,7 @@ def _cygexpath(drive: Optional[str], path: str) -> str:

def cygpath(path: str) -> str:
"""Use :meth:`git.cmd.Git.polish_url` instead, that works on any environment."""
path =str(path) # Ensure is str and not AnyPath.
path =os.fspath(path) # Ensure is str and not AnyPath.
# Fix to use Paths when 3.5 dropped. Or to be just str if only for URLs?
if not path.startswith(("/cygdrive", "//", "/proc/cygdrive")):
for regex, parser, recurse in _cygpath_parsers:
Expand All@@ -438,7 +438,7 @@ def cygpath(path: str) -> str:


def decygpath(path: PathLike) -> str:
path =str(path)
path =os.fspath(path)
m = _decygpath_regex.match(path)
if m:
drive, rest_path = m.groups()
Expand All@@ -465,7 +465,7 @@ def _is_cygwin_git(git_executable: str) -> bool:
# Just a name given, not a real path.
uname_cmd = osp.join(git_dir, "uname")

if not (pathlib.Path(uname_cmd).is_file() and os.access(uname_cmd, os.X_OK)):
if not (Path(uname_cmd).is_file() and os.access(uname_cmd, os.X_OK)):
_logger.debug(f"Failed checking if running in CYGWIN: {uname_cmd} is not an executable")
_is_cygwin_cache[git_executable] = is_cygwin
return is_cygwin
Expand DownExpand Up@@ -523,7 +523,7 @@ def expand_path(p: PathLike, expand_vars: bool = ...) -> str:


def expand_path(p: Union[None, PathLike], expand_vars: bool = True) -> Optional[PathLike]:
if isinstance(p,pathlib.Path):
if isinstance(p, Path):
return p.resolve()
try:
p = osp.expanduser(p) # type: ignore[arg-type]
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp