79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
from typing import FrozenSet, Optional, Set
|
|
|
|
from pip._vendor.packaging.utils import canonicalize_name
|
|
|
|
from pip._internal.exceptions import CommandError
|
|
|
|
|
|
class FormatControl:
|
|
"""Helper for managing formats from which a package can be installed."""
|
|
|
|
__slots__ = ["no_binary", "only_binary"]
|
|
|
|
def __init__(
|
|
self,
|
|
no_binary: Optional[Set[str]] = None,
|
|
only_binary: Optional[Set[str]] = None,
|
|
) -> None:
|
|
if no_binary is None:
|
|
no_binary = set()
|
|
if only_binary is None:
|
|
only_binary = set()
|
|
|
|
self.no_binary = no_binary
|
|
self.only_binary = only_binary
|
|
|
|
def __eq__(self, other: object) -> bool:
|
|
if not isinstance(other, self.__class__):
|
|
return NotImplemented
|
|
|
|
if self.__slots__ != other.__slots__:
|
|
return False
|
|
|
|
return all(getattr(self, k) == getattr(other, k) for k in self.__slots__)
|
|
|
|
def __repr__(self) -> str:
|
|
return f"{self.__class__.__name__}({self.no_binary}, {self.only_binary})"
|
|
|
|
@staticmethod
|
|
def handle_mutual_excludes(value: str, target: Set[str], other: Set[str]) -> None:
|
|
if value.startswith("-"):
|
|
raise CommandError(
|
|
"--no-binary / --only-binary option requires 1 argument."
|
|
)
|
|
new = value.split(",")
|
|
while ":all:" in new:
|
|
other.clear()
|
|
target.clear()
|
|
target.add(":all:")
|
|
del new[: new.index(":all:") + 1]
|
|
# Without a none, we want to discard everything as :all: covers it
|
|
if ":none:" not in new:
|
|
return
|
|
for name in new:
|
|
if name == ":none:":
|
|
target.clear()
|
|
continue
|
|
name = canonicalize_name(name)
|
|
other.discard(name)
|
|
target.add(name)
|
|
|
|
def get_allowed_formats(self, canonical_name: str) -> FrozenSet[str]:
|
|
result = {"binary", "source"}
|
|
if canonical_name in self.only_binary:
|
|
result.discard("source")
|
|
elif canonical_name in self.no_binary:
|
|
result.discard("binary")
|
|
elif ":all:" in self.only_binary:
|
|
result.discard("source")
|
|
elif ":all:" in self.no_binary:
|
|
result.discard("binary")
|
|
return frozenset(result)
|
|
|
|
def disallow_binaries(self) -> None:
|
|
self.handle_mutual_excludes(
|
|
":all:",
|
|
self.no_binary,
|
|
self.only_binary,
|
|
)
|