Light Mode

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

Commit a89f9fc

Browse files
committed
fixes
1 parent e5dc3c3 commit a89f9fc

File tree

13 files changed

+260
-261
lines changed
  • CHANGELOG.md
  • README.md
  • documentation/reference/licensecheck
    • checker.md
    • cli.md
    • packageinfo.md
    • resolvers
      • uv.md
  • licensecheck
    • checker.py
    • cli.py
    • packageinfo.py
    • resolvers
      • native.py
      • uv.py
  • pyproject.toml
  • tests/platform_independent
    • test_checker.py

13 files changed

+260
-261
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
All major and minor version changes will be documented in this file. Details of
44
patch-level version changes can be found in [commit messages](../../commits/master).
55

6+
## 2025.0.1 - 2025/03/16
7+
8+
- update the cli interface to remove some confusing functionality
9+
- refactor the library / code qa improvements
10+
- Allow for alias of classifier in setup.cfg, thanks https://github.com/ericwb: #106
11+
- Add support for SPDX license expression metadata after PEP 639: #107
12+
- Add use regex/glob pattern to ignore multiple packages, thanks https://github.com/JulianKimmig: #108
13+
- Prioritise ['project'] table over ['tool.poetry'] in pyproject.toml: #104
14+
- Add option to show only failing packages: #98
15+
616
## 2024.3 - 2024/08/26
717

818
- Use uv to parse dependencies before falling back to the native resolver

README.md

Lines changed: 183 additions & 224 deletions
Large diffs are not rendered by default.

documentation/reference/licensecheck/checker.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
## check
1212

13-
[Show source in checker.py:43](../../../licensecheck/checker.py#L43)
13+
[Show source in checker.py:47](../../../licensecheck/checker.py#L47)
1414

1515
#### Signature
1616

@@ -39,13 +39,16 @@ def check(
3939

4040
## resolve_requirements
4141

42-
[Show source in checker.py:17](../../../licensecheck/checker.py#L17)
42+
[Show source in checker.py:18](../../../licensecheck/checker.py#L18)
4343

4444
#### Signature
4545

4646
```python
4747
def resolve_requirements(
48-
requirements_paths: list[str], groups: list[str], skip_dependencies: list[ucstr]
48+
requirements_paths: list[str],
49+
groups: list[str],
50+
skip_dependencies: list[ucstr],
51+
index_url: str,
4952
) -> set[ucstr]: ...
5053
```
5154

documentation/reference/licensecheck/cli.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def cli() -> None: ...
2424

2525
## main
2626

27-
[Show source in cli.py:112](../../../licensecheck/cli.py#L112)
27+
[Show source in cli.py:117](../../../licensecheck/cli.py#L117)
2828

2929
Test entry point.
3030

@@ -35,5 +35,5 @@ Note: FHConfParser (Parses in the following order: `pyproject.toml`,
3535
#### Signature
3636

3737
```python
38-
def main(args: dict | argparse.Namespace) -> int: ...
38+
def main(args: dict) -> int: ...
3939
```

documentation/reference/licensecheck/packageinfo.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
## LocalPackageInfo
2424

25-
[Show source in packageinfo.py:75](../../../licensecheck/packageinfo.py#L75)
25+
[Show source in packageinfo.py:77](../../../licensecheck/packageinfo.py#L77)
2626

2727
Handles retrieval of package info from local installation.
2828

@@ -34,7 +34,7 @@ class LocalPackageInfo: ...
3434

3535
### LocalPackageInfo.get_info
3636

37-
[Show source in packageinfo.py:78](../../../licensecheck/packageinfo.py#L78)
37+
[Show source in packageinfo.py:80](../../../licensecheck/packageinfo.py#L80)
3838

3939
Retrieve package metadata from local installation.
4040

@@ -61,7 +61,7 @@ def get_info(package: ucstr) -> PackageInfo: ...
6161

6262
### LocalPackageInfo.get_size
6363

64-
[Show source in packageinfo.py:104](../../../licensecheck/packageinfo.py#L104)
64+
[Show source in packageinfo.py:106](../../../licensecheck/packageinfo.py#L106)
6565

6666
Retrieve installed package size.
6767

@@ -97,12 +97,12 @@ Manages retrieval of local and remote package information.
9797

9898
```python
9999
class PackageInfoManager:
100-
def __init__(self, pypi_api: str = "https://pypi.org/pypi/") -> None: ...
100+
def __init__(self, base_pypi_url: str = "https://pypi.org") -> None: ...
101101
```
102102

103103
### PackageInfoManager().getPackages
104104

105-
[Show source in packageinfo.py:34](../../../licensecheck/packageinfo.py#L34)
105+
[Show source in packageinfo.py:36](../../../licensecheck/packageinfo.py#L36)
106106

107107
Retrieve package information from local installation or PyPI.
108108

@@ -126,7 +126,7 @@ def getPackages(self, reqs: set[ucstr]) -> set[PackageInfo]: ...
126126

127127
### PackageInfoManager().get_package_info
128128

129-
[Show source in packageinfo.py:48](../../../licensecheck/packageinfo.py#L48)
129+
[Show source in packageinfo.py:50](../../../licensecheck/packageinfo.py#L50)
130130

131131
Retrieve package information, preferring local data.
132132

@@ -154,7 +154,7 @@ def get_package_info(self, package: ucstr) -> PackageInfo: ...
154154

155155
## ProjectMetadata
156156

157-
[Show source in packageinfo.py:192](../../../licensecheck/packageinfo.py#L192)
157+
[Show source in packageinfo.py:194](../../../licensecheck/packageinfo.py#L194)
158158

159159
Handles extraction of project metadata from configuration files.
160160

@@ -166,7 +166,7 @@ class ProjectMetadata: ...
166166

167167
### ProjectMetadata.get_license
168168

169-
[Show source in packageinfo.py:220](../../../licensecheck/packageinfo.py#L220)
169+
[Show source in packageinfo.py:222](../../../licensecheck/packageinfo.py#L222)
170170

171171
Extract license from project metadata.
172172

@@ -188,7 +188,7 @@ def get_license() -> ucstr: ...
188188

189189
### ProjectMetadata.get_metadata
190190

191-
[Show source in packageinfo.py:195](../../../licensecheck/packageinfo.py#L195)
191+
[Show source in packageinfo.py:197](../../../licensecheck/packageinfo.py#L197)
192192

193193
Extract project metadata from setup.cfg or pyproject.toml.
194194

@@ -208,7 +208,7 @@ def get_metadata() -> dict[str, Any]: ...
208208

209209
## RemotePackageInfo
210210

211-
[Show source in packageinfo.py:115](../../../licensecheck/packageinfo.py#L115)
211+
[Show source in packageinfo.py:117](../../../licensecheck/packageinfo.py#L117)
212212

213213
Handles retrieval of package info from PyPI.
214214

@@ -220,7 +220,7 @@ class RemotePackageInfo: ...
220220

221221
### RemotePackageInfo.get_info
222222

223-
[Show source in packageinfo.py:118](../../../licensecheck/packageinfo.py#L118)
223+
[Show source in packageinfo.py:120](../../../licensecheck/packageinfo.py#L120)
224224

225225
Retrieve package metadata from PyPI.
226226

@@ -248,7 +248,7 @@ def get_info(package: ucstr, pypi_api: str) -> PackageInfo: ...
248248

249249
### RemotePackageInfo.get_size
250250

251-
[Show source in packageinfo.py:148](../../../licensecheck/packageinfo.py#L148)
251+
[Show source in packageinfo.py:150](../../../licensecheck/packageinfo.py#L150)
252252

253253
Retrieve package size from PyPI metadata.
254254

@@ -270,7 +270,7 @@ def get_size(data: dict[str, Any]) -> int: ...
270270

271271
## from_classifiers
272272

273-
[Show source in packageinfo.py:173](../../../licensecheck/packageinfo.py#L173)
273+
[Show source in packageinfo.py:175](../../../licensecheck/packageinfo.py#L175)
274274

275275
Extract license from classifiers.
276276

@@ -295,7 +295,7 @@ def from_classifiers(classifiers: list[str] | None) -> ucstr: ...
295295

296296
## meta_get
297297

298-
[Show source in packageinfo.py:160](../../../licensecheck/packageinfo.py#L160)
298+
[Show source in packageinfo.py:162](../../../licensecheck/packageinfo.py#L162)
299299

300300
Retrieve metadata value safely.
301301

documentation/reference/licensecheck/resolvers/uv.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
```python
1717
def get_reqs(
18-
skipDependencies: list[ucstr], extras: list[str], requirementsPaths: list[str]
18+
skipDependencies: list[ucstr],
19+
extras: list[str],
20+
requirementsPaths: list[str],
21+
index_url: str = "https://pypi.org",
1922
) -> set[ucstr]: ...
2023
```
2124

licensecheck/checker.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pathlib import Path
77

88
import tomli
9+
from loguru import logger
910

1011
from licensecheck import license_matrix
1112
from licensecheck.packageinfo import PackageInfoManager
@@ -18,15 +19,18 @@ def resolve_requirements(
1819
requirements_paths: list[str],
1920
groups: list[str],
2021
skip_dependencies: list[ucstr],
22+
index_url: str,
2123
) -> set[ucstr]:
2224
try:
2325
return res_uv.get_reqs(
2426
skipDependencies=skip_dependencies,
2527
extras=groups,
2628
requirementsPaths=requirements_paths,
29+
index_url=index_url,
2730
)
2831

29-
except RuntimeError:
32+
except RuntimeError as e:
33+
logger.warning(e)
3034
pyproject = {}
3135
if "pyproject.toml" in requirements_paths:
3236
pyproject = tomli.loads(Path("pyproject.toml").read_text("utf-8"))
@@ -60,7 +64,12 @@ def check(
6064
only_licenses = only_licenses or []
6165
skip_dependencies = skip_dependencies or []
6266

63-
requirements = resolve_requirements(requirements_paths, groups, skip_dependencies)
67+
requirements = resolve_requirements(
68+
requirements_paths,
69+
groups,
70+
skip_dependencies,
71+
index_url=package_info_manager.pypi_search,
72+
)
6473

6574
ignoreLicensesType = license_matrix.licenseType(
6675
ucstr(JOINS.join(ignore_licenses)), ignore_licenses

licensecheck/cli.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def cli() -> None: # pragma: no cover
3434
parser.add_argument(
3535
"--requirements-paths",
3636
"-r",
37-
help="Filenames to read from (omit for stdin)",
37+
help="Filenames to read from (omit for stdin if piping, else pyproject.toml)",
3838
nargs="+",
3939
)
4040
parser.add_argument(
@@ -91,7 +91,7 @@ def cli() -> None: # pragma: no cover
9191
parser.add_argument(
9292
"--pypi-api",
9393
help="Specify a custom pypi api endpoint, for example if using a custom pypi server",
94-
default="https://pypi.org/pypi/",
94+
default="https://pypi.org",
9595
)
9696
parser.add_argument(
9797
"--zero",
@@ -100,16 +100,21 @@ def cli() -> None: # pragma: no cover
100100
action="store_true",
101101
)
102102
args = vars(parser.parse_args())
103+
103104
stdin_path = Path("__stdin__")
104-
if stdin:
105-
stdin_path.write_text("\n".join(stdin.readlines()), "utf-8")
105+
if not args.get("requirements_paths"):
106+
if stdin.isatty():
107+
args["requirements_paths"] = ["pyproject.toml"]
108+
else:
109+
stdin_path.write_text("\n".join(stdin.readlines()), encoding="utf-8")
110+
106111
ec = main(args)
107112
stdin_path.unlink(missing_ok=True)
108113

109114
sysexit(ec)
110115

111116

112-
def main(args: dict | argparse.Namespace) -> int:
117+
def main(args: dict) -> int:
113118
"""Test entry point.
114119
115120
Note: FHConfParser (Parses in the following order: `pyproject.toml`,
@@ -142,7 +147,7 @@ def main(args: dict | argparse.Namespace) -> int:
142147

143148
# Get my license
144149
this_license_text = (
145-
args["license"] if args.get("license") else packageinfo.getMyPackageLicense()
150+
args["license"] if args.get("license") else packageinfo.ProjectMetadata.get_license()
146151
)
147152
this_license = license_matrix.licenseType(this_license_text)[0]
148153

licensecheck/packageinfo.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323
class PackageInfoManager:
2424
"""Manages retrieval of local and remote package information."""
2525

26-
def __init__(self, pypi_api: str = "https://pypi.org/pypi/") -> None:
26+
def __init__(self, base_pypi_url: str = "https://pypi.org") -> None:
2727
"""Manage retrieval of local and remote package information.
2828
2929
:param str pypi_api: url of pypi server. Typically the public instance, defaults
30-
to "https://pypi.org/pypi/"
30+
to "https://pypi.org"
3131
"""
32-
self.pypi_api = pypi_api
32+
self.base_pypi_url = base_pypi_url
33+
self.pypi_api = base_pypi_url + "/pypi/"
34+
self.pypi_search = base_pypi_url + "/simple/"
3335

3436
def getPackages(self, reqs: set[ucstr]) -> set[PackageInfo]:
3537
"""Retrieve package information from local installation or PyPI.

licensecheck/resolvers/native.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ def resolveExtraReq(extraReq: str) -> ucstr | None:
110110
msg = "Could not find specification of requirements (pyproject.toml)."
111111
raise RuntimeError(msg) from error
112112
for extra in extras:
113-
reqLists.append(project["optional-dependencies"][extra])
113+
extra_info = project.get("optional-dependencies", {}).get(extra)
114+
reqLists.append(extra_info) if extra_info else ""
114115
for reqList in reqLists:
115116
for req in reqList:
116117
reqs.add(resolveReq(req))

0 commit comments

Comments
(0)