# Path: delocate/pkginfo.py
# def read_pkg_info(path: Union[bytes, str, PathLike]) -> Message:
#     """Read a PKG-INFO or METADATA file."""
#     with open(path, encoding="utf-8") as headers:
#         return Parser().parse(headers)
# 
# def write_pkg_info(path: Union[bytes, str, PathLike], message: Message) -> None:
#     """Write to a PKG-INFO or METADATA file."""
#     with open(path, "w", encoding="utf-8") as out:
#         Generator(out, mangle_from_=False, maxheaderlen=0).flatten(message)
# 
# Path: delocate/tmpdirs.py
# class InTemporaryDirectory(TemporaryDirectory):
#     """Create, return, and change directory to a temporary directory
# 
#     Examples
#     --------
#     >>> import os
#     >>> my_cwd = os.getcwd()
#     >>> with InTemporaryDirectory() as tmpdir:
#     ...     _ = open('test.txt', 'wt').write('some text')
#     ...     assert os.path.isfile('test.txt')
#     ...     assert os.path.isfile(os.path.join(tmpdir, 'test.txt'))
#     >>> os.path.exists(tmpdir)
#     False
#     >>> os.getcwd() == my_cwd
#     True
#     """
# 
#     def __enter__(self):
#         self._pwd = os.getcwd()
#         os.chdir(self.name)
#         return super(InTemporaryDirectory, self).__enter__()
# 
#     def __exit__(self, exc, value, tb):
#         os.chdir(self._pwd)
#         return super(InTemporaryDirectory, self).__exit__(exc, value, tb)
# 
# Path: delocate/tools.py
# T = TypeVar("T")
# IN_RE = re.compile(
#     r"(.*) \(compatibility version (\d+\.\d+\.\d+), "
#     r"current version (\d+\.\d+\.\d+)(?:, \w+)?\)"
# )
# _OTOOL_ARCHITECTURE_RE = re.compile(
#     r"^(?P<name>.*?)(?: \(architecture (?P<architecture>\w+)\))?:$"
# )
# RE_PERM_DEN = re.compile(r"Permission denied[.) ]*$")
# BAD_OBJECT_TESTS = [
#     # otool version cctools-862
#     lambda s: "is not an object file" in s,
#     # cctools-862 (.ico)
#     lambda s: "The end of the file was unexpectedly encountered" in s,
#     # cctools-895
#     lambda s: "The file was not recognized as a valid object file" in s,
#     # 895 binary file
#     lambda s: "Invalid data was encountered while parsing the file" in s,
#     # cctools-900
#     lambda s: "Object is not a Mach-O file type" in s,
#     # cctools-949
#     lambda s: "object is not a Mach-O file type" in s,
#     # File may not have read permissions
#     lambda s: RE_PERM_DEN.search(s) is not None,
# ]
# _LINE0_RE = re.compile(r"^(?: \(architecture .*\))?:(?P<further_report>.*)")
# RPATH_RE = re.compile(r"path (?P<rpath>.*) \(offset \d+\)")
# class InstallNameError(Exception):
# def back_tick(
#     cmd: Union[str, Sequence[str]],
#     ret_err: bool = False,
#     as_str: bool = True,
#     raise_err: Optional[bool] = None,
# ) -> Any:
# def unique_by_index(sequence):
# def chmod_perms(fname):
# def ensure_permissions(mode_flags=stat.S_IWUSR):
#     def decorator(f):
#         def modify(filename, *args, **kwargs):
# def parse_install_name(line: str) -> Tuple[str, str, str]:
# def _parse_otool_listing(stdout: str) -> Dict[str, List[str]]:
# def _check_ignore_archs(input: Dict[str, T]) -> T:
# def _parse_otool_install_names(
#     stdout: str,
# ) -> Dict[str, List[Tuple[str, str, str]]]:
# def _line0_says_object(stdout_stderr: str, filename: str) -> bool:
# def get_install_names(filename: str) -> Tuple[str, ...]:
# def get_install_id(filename: str) -> Optional[str]:
# def _get_install_ids(filename: str) -> Dict[str, str]:
# def set_install_name(
#     filename: str, oldname: str, newname: str, ad_hoc_sign: bool = True
# ) -> None:
# def set_install_id(filename: str, install_id: str, ad_hoc_sign: bool = True):
# def _parse_otool_rpaths(stdout: str) -> Dict[str, List[str]]:
# def get_rpaths(filename: str) -> Tuple[str, ...]:
# def get_environment_variable_paths():
# def add_rpath(filename: str, newpath: str, ad_hoc_sign: bool = True) -> None:
# def zip2dir(zip_fname: str, out_dir: str) -> None:
# def dir2zip(in_dir, zip_fname):
# def find_package_dirs(root_path: str) -> Set[str]:
# def cmp_contents(filename1, filename2):
# def get_archs(libname: str) -> FrozenSet[str]:
# def lipo_fuse(
#     in_fname1: str, in_fname2: str, out_fname: str, ad_hoc_sign: bool = True
# ) -> str:
# def replace_signature(filename: str, identity: str) -> None:
# def validate_signature(filename: str) -> None:


import csv
import glob
import hashlib
import os
import sys
from itertools import product
from os.path import abspath, basename, dirname, exists
from os.path import join as pjoin
from os.path import relpath
from os.path import sep as psep
from os.path import splitext
from delocate.pkginfo import read_pkg_info, write_pkg_info
from wheel.util import native, urlsafe_b64encode
from wheel.wheelfile import WheelFile
from .tmpdirs import InTemporaryDirectory
from .tools import dir2zip, open_rw, unique_by_index, zip2dir
""" General tools for working with wheels

Tools that aren't specific to delocation
"""





class WheelToolsError(Exception):
    pass


def _open_for_csv(name, mode):
    """Deal with Python 2/3 open API differences"""
    if sys.version_info[0] < 3:
        return open_rw(name, mode + "b")

# Path: delocate/pkginfo.py
# def read_pkg_info(path: Union[bytes, str, PathLike]) -> Message:
#     """Read a PKG-INFO or METADATA file."""
#     with open(path, encoding="utf-8") as headers:
#         return Parser().parse(headers)
# 
# def write_pkg_info(path: Union[bytes, str, PathLike], message: Message) -> None:
#     """Write to a PKG-INFO or METADATA file."""
#     with open(path, "w", encoding="utf-8") as out:
#         Generator(out, mangle_from_=False, maxheaderlen=0).flatten(message)
# 
# Path: delocate/tmpdirs.py
# class InTemporaryDirectory(TemporaryDirectory):
#     """Create, return, and change directory to a temporary directory
# 
#     Examples
#     --------
#     >>> import os
#     >>> my_cwd = os.getcwd()
#     >>> with InTemporaryDirectory() as tmpdir:
#     ...     _ = open('test.txt', 'wt').write('some text')
#     ...     assert os.path.isfile('test.txt')
#     ...     assert os.path.isfile(os.path.join(tmpdir, 'test.txt'))
#     >>> os.path.exists(tmpdir)
#     False
#     >>> os.getcwd() == my_cwd
#     True
#     """
# 
#     def __enter__(self):
#         self._pwd = os.getcwd()
#         os.chdir(self.name)
#         return super(InTemporaryDirectory, self).__enter__()
# 
#     def __exit__(self, exc, value, tb):
#         os.chdir(self._pwd)
#         return super(InTemporaryDirectory, self).__exit__(exc, value, tb)
# 
# Path: delocate/tools.py
# T = TypeVar("T")
# IN_RE = re.compile(
#     r"(.*) \(compatibility version (\d+\.\d+\.\d+), "
#     r"current version (\d+\.\d+\.\d+)(?:, \w+)?\)"
# )
# _OTOOL_ARCHITECTURE_RE = re.compile(
#     r"^(?P<name>.*?)(?: \(architecture (?P<architecture>\w+)\))?:$"
# )
# RE_PERM_DEN = re.compile(r"Permission denied[.) ]*$")
# BAD_OBJECT_TESTS = [
#     # otool version cctools-862
#     lambda s: "is not an object file" in s,
#     # cctools-862 (.ico)
#     lambda s: "The end of the file was unexpectedly encountered" in s,
#     # cctools-895
#     lambda s: "The file was not recognized as a valid object file" in s,
#     # 895 binary file
#     lambda s: "Invalid data was encountered while parsing the file" in s,
#     # cctools-900
#     lambda s: "Object is not a Mach-O file type" in s,
#     # cctools-949
#     lambda s: "object is not a Mach-O file type" in s,
#     # File may not have read permissions
#     lambda s: RE_PERM_DEN.search(s) is not None,
# ]
# _LINE0_RE = re.compile(r"^(?: \(architecture .*\))?:(?P<further_report>.*)")
# RPATH_RE = re.compile(r"path (?P<rpath>.*) \(offset \d+\)")
# class InstallNameError(Exception):
# def back_tick(
#     cmd: Union[str, Sequence[str]],
#     ret_err: bool = False,
#     as_str: bool = True,
#     raise_err: Optional[bool] = None,
# ) -> Any:
# def unique_by_index(sequence):
# def chmod_perms(fname):
# def ensure_permissions(mode_flags=stat.S_IWUSR):
#     def decorator(f):
#         def modify(filename, *args, **kwargs):
# def parse_install_name(line: str) -> Tuple[str, str, str]:
# def _parse_otool_listing(stdout: str) -> Dict[str, List[str]]:
# def _check_ignore_archs(input: Dict[str, T]) -> T:
# def _parse_otool_install_names(
#     stdout: str,
# ) -> Dict[str, List[Tuple[str, str, str]]]:
# def _line0_says_object(stdout_stderr: str, filename: str) -> bool:
# def get_install_names(filename: str) -> Tuple[str, ...]:
# def get_install_id(filename: str) -> Optional[str]:
# def _get_install_ids(filename: str) -> Dict[str, str]:
# def set_install_name(
#     filename: str, oldname: str, newname: str, ad_hoc_sign: bool = True
# ) -> None:
# def set_install_id(filename: str, install_id: str, ad_hoc_sign: bool = True):
# def _parse_otool_rpaths(stdout: str) -> Dict[str, List[str]]:
# def get_rpaths(filename: str) -> Tuple[str, ...]:
# def get_environment_variable_paths():
# def add_rpath(filename: str, newpath: str, ad_hoc_sign: bool = True) -> None:
# def zip2dir(zip_fname: str, out_dir: str) -> None:
# def dir2zip(in_dir, zip_fname):
# def find_package_dirs(root_path: str) -> Set[str]:
# def cmp_contents(filename1, filename2):
# def get_archs(libname: str) -> FrozenSet[str]:
# def lipo_fuse(
#     in_fname1: str, in_fname2: str, out_fname: str, ad_hoc_sign: bool = True
# ) -> str:
# def replace_signature(filename: str, identity: str) -> None:
# def validate_signature(filename: str) -> None:


# Path: delocate/wheeltools.py
import csv
import glob
import hashlib
import os
import sys
from itertools import product
from os.path import abspath, basename, dirname, exists
from os.path import join as pjoin
from os.path import relpath
from os.path import sep as psep
from os.path import splitext
from delocate.pkginfo import read_pkg_info, write_pkg_info
from wheel.util import native, urlsafe_b64encode
from wheel.wheelfile import WheelFile
from .tmpdirs import InTemporaryDirectory
from .tools import dir2zip, open_rw, unique_by_index, zip2dir

""" General tools for working with wheels

Tools that aren't specific to delocation
"""





class WheelToolsError(Exception):
    pass


def _open_for_csv(name, mode):
    """Deal with Python 2/3 open API differences"""
    if sys.version_info[0] < 3:
        return open_rw(name, mode + "b")

    return open_rw(name, mode, newline="", encoding="utf-8")