Skip to content

Commit

Permalink
Add stub with typing info.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kentzo committed Nov 7, 2019
1 parent a076827 commit e5e0d2f
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 53 deletions.
77 changes: 24 additions & 53 deletions git_archive_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,7 @@
import sys
import re

__version__ = "1.19.4"


try:
# Python 3.3+
from shlex import quote
except ImportError:
_find_unsafe = re.compile(r'[^a-zA-Z0-9_@%+=:,./-]').search

def quote(s):
"""Return a shell-escaped version of the string *s*."""
if not s:
return "''"

if _find_unsafe(s) is None:
return s

return "'" + s.replace("'", "'\"'\"'") + "'"
__version__ = "1.20.0-dev0"


try:
Expand All @@ -62,17 +45,6 @@ def fsdecode(filename):
else:
return filename


def git_fsdecode(filename):
"""
Decode filename from git output into str.
"""
if sys.platform.startswith('win32'):
return filename.decode('utf-8')
else:
return fsdecode(filename)


try:
# Python 3.2+
from os import fsencode
Expand All @@ -84,6 +56,16 @@ def fsencode(filename):
return filename


def git_fsdecode(filename):
"""
Decode filename from git output into str.
"""
if sys.platform.startswith('win32'):
return filename.decode('utf-8')
else:
return fsdecode(filename)


def git_fsencode(filename):
"""
Encode filename from str into git input.
Expand All @@ -99,20 +81,22 @@ def git_fsencode(filename):
from os import fspath as _fspath

def fspath(filename, decoder=fsdecode, encoder=fsencode):
"""
Convert filename into bytes or str, depending on what's the best type
to represent paths for current Python and platform.
"""
# Python 3.6+: str can represent any path (PEP 383)
# str is not required on Windows (PEP 529)
# Decoding is still applied for consistency and to follow PEP 519 recommendation.
return decoder(_fspath(filename))
except ImportError:
def fspath(filename, decoder=fsdecode, encoder=fsencode):
"""
Python 3.4 and 3.5: str can represent any path (PEP 383),
but str is required on Windows (no PEP 529)
Python 2.6 and 2.7: str cannot represent any path (no PEP 383),
str is required on Windows (no PEP 529)
bytes is required on POSIX (no PEP 383)
"""
# Python 3.4 and 3.5: str can represent any path (PEP 383),
# but str is required on Windows (no PEP 529)
#
# Python 2.6 and 2.7: str cannot represent any path (no PEP 383),
# str is required on Windows (no PEP 529)
# bytes is required on POSIX (no PEP 383)
if sys.version_info > (3,):
import pathlib
if isinstance(filename, pathlib.PurePath):
Expand Down Expand Up @@ -167,13 +151,10 @@ def __init__(self, prefix='', exclude=True, force_sub=False, extra=None, main_re
bar
@param exclude: Determines whether archiver should follow rules specified in .gitattributes files.
@type exclude: bool
@param force_sub: Determines whether submodules are initialized and updated before archiving.
@type force_sub: bool
@param extra: List of extra paths to include in the resulting archive.
@type extra: list
@param main_repo_abspath: Absolute path to the main repository (or one of subdirectories).
If given path is path to a subdirectory (but not a submodule directory!) it will be replaced
Expand All @@ -182,7 +163,6 @@ def __init__(self, prefix='', exclude=True, force_sub=False, extra=None, main_re
@param git_version: Version of Git that determines whether various workarounds are on.
If None, tries to resolve via Git's CLI.
@type git_version: tuple or None
"""
self._should_decode_path = None
self._check_attr_gens = {}
Expand Down Expand Up @@ -217,11 +197,11 @@ def create(self, output_path, dry_run=False, output_format=None, compresslevel=N
@param output_path: Output file path.
@param dry_run: Determines whether create should do nothing but print what it would archive.
@type dry_run: bool
@param output_format: Determines format of the output archive. If None, format is determined from extension
of output_file_path.
@type output_format: str
@param compresslevel: Optional compression level. Interpretation depends on the output format.
"""
output_path = fspath(output_path)

Expand Down Expand Up @@ -291,7 +271,6 @@ def is_file_excluded(self, repo_abspath, repo_file_path):
@param repo_file_path: Path to a file relative to repo_abspath.
@return: True if file should be excluded. Otherwise False.
@rtype: bool
"""
next(self._check_attr_gens[repo_abspath])
attrs = self._check_attr_gens[repo_abspath].send(repo_file_path)
Expand All @@ -303,7 +282,6 @@ def archive_all_files(self, archiver):
@param archiver: Callable that accepts 2 arguments:
abspath to file on the system and relative path within archive.
@type archiver: Callable
"""
for file_path in self.extra:
archiver(path.abspath(file_path), path.join(self.prefix, file_path))
Expand All @@ -323,7 +301,6 @@ def walk_git_files(self, repo_path=fspath('')):
@param repo_path: Path to the git submodule repository relative to main_repo_abspath.
@return: Iterator to traverse files under git control relative to main_repo_abspath.
@rtype: Iterable
"""
repo_abspath = path.join(self.main_repo_abspath, fspath(repo_path))
assert repo_abspath not in self._check_attr_gens
Expand Down Expand Up @@ -399,8 +376,6 @@ def check_git_attr(self, repo_abspath, attrs):
@param repo_abspath: Absolute path to a git repository.
@param attrs: Attributes to check
@rtype: generator
"""
def make_process():
env = dict(environ, GIT_FLUSH='1')
Expand Down Expand Up @@ -484,7 +459,7 @@ def read_attrs_old(process, repo_file_path):
repo_file_attrs = {}

for path, attr, value in reader(process, repo_file_path):
attr = attr if attr in attrs else attr.decode('utf-8') # use str or bytes depending on what user passed
attr = attr.decode('utf-8')
repo_file_attrs[attr] = value

yield repo_file_attrs
Expand All @@ -508,12 +483,10 @@ def run_git_shell(cls, cmd, cwd=None):
Run git shell command, read output and decode it into a unicode string.
@param cmd: Command to be executed.
@type cmd: str
@param cwd: Working directory.
@return: Output of the command.
@rtype: bytes
@raise CalledProcessError: Raises exception if return code of the command is non-zero.
"""
Expand All @@ -534,8 +507,6 @@ def get_git_version(cls):
Return version of git current shell points to.
If version cannot be parsed None is returned.
@rtype: tuple or None
"""
try:
output = cls.run_git_shell('git version')
Expand Down
62 changes: 62 additions & 0 deletions git_archive_all.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from os import PathLike as _PathLike
import logging
from typing import Callable, Collection, ClassVar, Dict, Generator, Iterable, List, Optional, Tuple, Union

PathLike = Union[str, bytes, _PathLike]
PathStr = Union[str, bytes]

def fsdecode(filename: PathLike) -> str: ...

def fsencode(filename: PathLike) -> bytes: ...

def git_fsdecode(filename: bytes) -> str: ...

def git_fsencode(filename: str) -> bytes: ...

def fspath(filename: PathLike, decoder=Callable[[PathLike], str], encoder=Callable[[PathLike], bytes]) -> PathStr: ...

def git_fspath(filename: bytes) -> PathStr: ...

class GitArchiver(object):
TARFILE_FORMATS: ClassVar[Dict[str, str]]
ZIPFILE_FORMATS: ClassVar[Tuple[str]]
LOG: ClassVar[logging.Logger]

_should_decode_path: Optional[bool]
_check_attr_gens: Dict[str, Generator[Dict[str, bytes], PathStr, None]]
git_version: Optional[Tuple[int]]
main_repo_abspath: PathStr
prefix: PathStr
exclude: bool
extra: List[PathStr]
force_sub: bool

def __init__(self,
prefix: PathLike,
exclude: bool,
force_sub: bool,
extra: Iterable[PathLike] = None,
main_repo_abspath: PathLike = None,
git_version: Tuple[int] = None) -> None: ...

def create(self,
output_path: PathLike,
dry_run: bool,
output_format: str = None,
compresslevel: int = None) -> None: ...

def is_file_excluded(self, repo_abspath: PathStr, repo_file_path: PathStr) -> bool: ...

def archive_all_files(self, archiver: Callable[[PathStr, PathStr], None]) -> None: ...

def walk_git_files(self, repo_path: PathStr = None) -> Generator[PathStr, None, None]: ...

def check_git_attr(self, repo_abspath: PathStr, attrs: Collection[str]) -> Generator[Dict[str, bytes], PathStr, None]: ...

def resolve_git_main_repo_abspath(self, abspath: PathLike) -> PathStr: ...

@classmethod
def run_git_shell(cls, cmd: str, cwd: PathStr = None) -> bytes: ...

@classmethod
def get_git_version(cls) -> Optional[Tuple[int]]: ...

0 comments on commit e5e0d2f

Please sign in to comment.