Skip to content

Commit

Permalink
Eliminate "file" property, and other tweaks
Browse files Browse the repository at this point in the history
Closes #19.
  • Loading branch information
jwodder committed Nov 1, 2023
1 parent 070c2dd commit 35786ff
Show file tree
Hide file tree
Showing 21 changed files with 45 additions and 165 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ v2.0.0 (in development)
- Files in `RECORD` now represent their digest information in a `"digest"`
key that is either `null` or a subobject with `"algorithm"` and
`"digest"` fields
- The `.file` property in wheel inspection results (containing the file's
size and digest) has been removed
- `RECORD` entries with negative sizes are now detected & errorred on earlier


Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ package_dir=
python_requires = ~=3.7
install_requires =
attrs >= 18.1
cached-property ~= 1.5; python_version < "3.8"
entry-points-txt ~= 0.1.0
headerparser ~= 0.4.0
packaging >= 17.1
Expand Down
72 changes: 36 additions & 36 deletions src/wheel_inspect/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,23 @@
import io
import os
from pathlib import Path
import sys
from typing import IO, Any, Dict, List, Optional, TextIO, TypeVar, overload
from zipfile import ZipFile
import attr
from wheel_filename import ParsedWheelFilename, parse_wheel_filename
from . import errors as exc
from .metadata import parse_metadata
from .record import Record
from .util import AnyPath, digest_file, find_dist_info_dir
from .wheel_info import parse_wheel_info

if sys.version_info[:2] >= (3, 8):
from functools import cached_property
else:
from cached_property import cached_property


T = TypeVar("T", bound="DistInfoProvider")


Expand Down Expand Up @@ -80,14 +88,16 @@ def has_dist_info_file(self, path: str) -> bool:
"""
...

def get_metadata(self) -> Dict[str, Any]:
@cached_property
def metadata(self) -> Dict[str, Any]:
try:
with self.open_dist_info_file("METADATA", encoding="utf-8") as fp:
return parse_metadata(fp)
except exc.MissingDistInfoFileError:
raise exc.MissingMetadataError()

def get_record(self) -> Record:
@cached_property
def record(self) -> Record:
try:
with self.open_dist_info_file("RECORD", encoding="utf-8", newline="") as fp:
# The csv module requires this file to be opened with
Expand All @@ -96,7 +106,8 @@ def get_record(self) -> Record:
except exc.MissingDistInfoFileError:
raise exc.MissingRecordError()

def get_wheel_info(self) -> Dict[str, Any]:
@cached_property
def wheel_info(self) -> Dict[str, Any]:
try:
with self.open_dist_info_file("WHEEL", encoding="utf-8") as fp:
return parse_wheel_info(fp)
Expand Down Expand Up @@ -198,19 +209,21 @@ def has_dist_info_file(self, path: str) -> bool:
return (self.path / path).exists()


@attr.s(auto_attribs=True)
class WheelFile(DistInfoProvider, FileProvider):
def __init__(self, path: AnyPath):
self.path: Path = Path(os.fsdecode(path))
self.filename: ParsedWheelFilename = parse_wheel_filename(self.path)
self.fp: IO[bytes] = self.path.open("rb")
self.zipfile: ZipFile = ZipFile(self.fp)
self._dist_info: Optional[str] = None
filename: ParsedWheelFilename
fp: IO[bytes]
zipfile: ZipFile

@classmethod
def from_path(cls, path: AnyPath) -> WheelFile:
# Recommend the use of this method in case __init__'s signature changes
# later
return cls(path)
p = Path(os.fsdecode(path))
filename = parse_wheel_filename(p)
fp = p.open("rb")
zipfile = ZipFile(fp)
return cls(filename=filename, fp=fp, zipfile=zipfile)

def __enter__(self) -> WheelFile:
return self
Expand All @@ -226,37 +239,24 @@ def close(self) -> None:
def closed(self) -> bool:
return self.fp.closed

@property
@cached_property
def dist_info(self) -> str:
if self._dist_info is None:
if self.zipfile is None:
raise RuntimeError(
"WheelFile.dist_info cannot be determined when WheelFile"
" is not open in context"
)
self._dist_info = find_dist_info_dir(
self.zipfile.namelist(),
self.filename.project,
self.filename.version,
)
return self._dist_info
return find_dist_info_dir(
self.zipfile.namelist(),
self.filename.project,
self.filename.version,
)

def basic_metadata(self) -> Dict[str, Any]:
namebits = self.filename
about: Dict[str, Any] = {
"filename": self.path.name,
"project": namebits.project,
"version": namebits.version,
"buildver": namebits.build,
"pyver": namebits.python_tags,
"abi": namebits.abi_tags,
"arch": namebits.platform_tags,
"file": {
"size": self.path.stat().st_size,
},
"filename": str(self.filename),
"project": self.filename.project,
"version": self.filename.version,
"buildver": self.filename.build,
"pyver": self.filename.python_tags,
"abi": self.filename.abi_tags,
"arch": self.filename.platform_tags,
}
self.fp.seek(0)
about["file"]["digests"] = digest_file(self.fp, ["md5", "sha256"])
return about

@overload
Expand Down
8 changes: 4 additions & 4 deletions src/wheel_inspect/inspecting.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def inspect(obj: DistInfoProvider) -> Dict[str, Any]:
has_dist_info = True

try:
record = obj.get_record()
record = obj.record
except errors.WheelValidationError as e:
about["valid"] = False
about["validation_error"] = {
Expand All @@ -109,7 +109,7 @@ def inspect(obj: DistInfoProvider) -> Dict[str, Any]:

if has_dist_info:
try:
metadata = obj.get_metadata()
metadata = obj.metadata
except errors.WheelValidationError as e:
metadata = {}
about["valid"] = False
Expand All @@ -121,7 +121,7 @@ def inspect(obj: DistInfoProvider) -> Dict[str, Any]:
about["dist_info"]["metadata"] = metadata

try:
about["dist_info"]["wheel"] = obj.get_wheel_info()
about["dist_info"]["wheel"] = obj.wheel_info
except errors.WheelValidationError as e:
about["valid"] = False
about["validation_error"] = {
Expand Down Expand Up @@ -190,7 +190,7 @@ def inspect_wheel(path: AnyPath) -> Dict[str, Any]:
Examine the Python wheel at the given path and return various information
about the contents within as a JSON-serializable `dict`
"""
with WheelFile(path) as wf:
with WheelFile.from_path(path) as wf:
return inspect(wf)


Expand Down
18 changes: 0 additions & 18 deletions src/wheel_inspect/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@
"pyver",
"abi",
"arch",
"file",
]
)

Expand Down Expand Up @@ -277,22 +276,5 @@
"items": {"type": "string"},
"description": "A list of architectures with which the wheel is compatible as extracted from the filename",
},
"file": {
"type": "object",
"required": ["size", "digests"],
"additionalProperties": False,
"properties": {
"size": {"type": "integer"},
"digests": {
"type": "object",
"required": ["md5", "sha256"],
"additionalProperties": False,
"properties": {
"md5": {"type": "string", "pattern": "^[0-9A-Fa-f]{32}$"},
"sha256": {"type": "string", "pattern": "^[0-9A-Fa-f]{64}$"},
},
},
},
},
}
)
7 changes: 0 additions & 7 deletions test/data/wheels/NLPTriples-0.1.7-py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,6 @@
"wheel_version": "1.0"
}
},
"file": {
"digests": {
"md5": "0b7ec3e02daa303263e2583e44878d05",
"sha256": "cddf7f060fa4ae42c309deacfbb12c02276b23bc4d7fde3d8c800b6029b149d9"
},
"size": 5212
},
"filename": "NLPTriples-0.1.7-py3-none-any.whl",
"project": "NLPTriples",
"pyver": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,6 @@
"wheel_version": "1.0"
}
},
"file": {
"digests": {
"md5": "3b01bf52c846983dfcfc38eff4d1f38b",
"sha256": "3df544165e616adf9ce6e1c1cbdf3820b0efc709f0bc6fc3e00ba4731038e0a6"
},
"size": 9689
},
"filename": "SQLAlchemy_Fixture_Factory-1.0.0-py2.py3-none-any.whl",
"project": "SQLAlchemy_Fixture_Factory",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/appr-0.7.4-py2.py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -2272,13 +2272,6 @@
"wheel_version": "1.0"
}
},
"file": {
"digests": {
"md5": "6645b8ec3ecb1378caf00b27581f6496",
"sha256": "b59f63d727d3d591dcb3365f32c521e5f0178915fb54cc949e8ff408d10db8cd"
},
"size": 484721
},
"filename": "appr-0.7.4-py2.py3-none-any.whl",
"project": "appr",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/digest_mismatch-1.0.0-py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,6 @@
"wheel_version": "1.0"
}
},
"file": {
"digests": {
"md5": "ca80fa9355ee5ade1d589e38c5120a94",
"sha256": "92e4e787e216997a40c9432479ae8e3a46e1a5344630303b20bbe5578cf59576"
},
"size": 1288
},
"filename": "digest_mismatch-1.0.0-py3-none-any.whl",
"project": "digest_mismatch",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/dirs_in_record-1.0.0-py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,6 @@
"wheel_version": "1.0"
}
},
"file": {
"digests": {
"md5": "9ec7edf8473aa1240f82d14ad8205297",
"sha256": "b554c3135119cf1c0e24f81e50f709add7ce948b3bd9deb8428cbe79447dad84"
},
"size": 1420
},
"filename": "dirs_in_record-1.0.0-py3-none-any.whl",
"project": "dirs_in_record",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/dist_info_mismatch-0.1.0-py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@
"readme_renders": null
},
"dist_info": {},
"file": {
"digests": {
"md5": "46d520d361f5652c27efd170fc6f3f1e",
"sha256": "7b075fbbda5473b4a7f8291d14670cdd1b6922537748d68ae465b712fa783a84"
},
"size": 1214
},
"filename": "dist_info_mismatch-0.1.0-py3-none-any.whl",
"project": "dist_info_mismatch",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/gitgud2-2.1-py2.py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,6 @@
},
"zip_safe": true
},
"file": {
"digests": {
"md5": "e8a776fd026119ce67a285a0f3f39c22",
"sha256": "a86e30d3c3f463f6e2221f506a8fe4a2b4c671593029f408d94d7c3271abb9b5"
},
"size": 4560
},
"filename": "gitgud2-2.1-py2.py3-none-any.whl",
"project": "gitgud2",
"pyver": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,6 @@
"wheel_version": "1.0"
}
},
"file": {
"digests": {
"md5": "de02937c567aae5dcde8d88a8c126d81",
"sha256": "d489af7673decc8faa03e139592d6b49555fd9f7e82fe827f20a8df052117ec0"
},
"size": 1342
},
"filename": "missing_dir_in_record-1.0.0-py3-none-any.whl",
"project": "missing_dir_in_record",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/multilint-2.4.0-py2.py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,6 @@
"wheel_version": "1.0"
}
},
"file": {
"digests": {
"md5": "07e43f021f0859985ea08e13fe6065bc",
"sha256": "f1a36263fcd7a08de8e5828a268e984accd34c7b91e98f4fde85de54e9c30a7e"
},
"size": 6179
},
"filename": "multilint-2.4.0-py2.py3-none-any.whl",
"project": "multilint",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/osx_tags-0.1.3-py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,6 @@
},
"zip_safe": true
},
"file": {
"digests": {
"md5": "58850890d66a8ba7be02c00922396a64",
"sha256": "2997cb228ed406435184b33358ed3e72dd242154be7c3ebdaa0be3ec9dc7c409"
},
"size": 5014
},
"filename": "osx_tags-0.1.3-py3-none-any.whl",
"project": "osx_tags",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/pytest_venv-0.2-py2.py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,6 @@
"wheel_version": "1.0"
}
},
"file": {
"digests": {
"md5": "0157c8201a91e8ae9e8ddea9503b59b3",
"sha256": "ec842cbc60affbea6b1136bf9876ca858d0b77f6c58740e69a6e0ef708f43ea3"
},
"size": 4908
},
"filename": "pytest_venv-0.2-py2.py3-none-any.whl",
"project": "pytest_venv",
"pyver": [
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/qypi-0.4.1-py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@
"any"
],
"valid": true,
"file": {
"size": 16158,
"digests": {
"md5": "1196d31e100b5ac25b509e4c7e13cb6b",
"sha256": "488a65d6bd8c10f211e098d2d6e4a66df003be12f028b8f6f858ac2863579eb1"
}
},
"dist_info": {
"metadata": {
"metadata_version": "2.0",
Expand Down
7 changes: 0 additions & 7 deletions test/data/wheels/setuptools-36.0.1-py2.py3-none-any.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@
"any"
],
"valid": true,
"file": {
"size": 476152,
"digests": {
"md5": "7a52500dcfd7c4f37f5d20e462c93560",
"sha256": "f2900e560efc479938a219433c48f15a4ff4ecfe575a65de385eeb44f2425587"
}
},
"dist_info": {
"metadata": {
"metadata_version": "2.0",
Expand Down
Loading

0 comments on commit 35786ff

Please sign in to comment.