95 ) |
95 ) |
96 return [d._dist for d in dists] |
96 return [d._dist for d in dists] |
97 |
97 |
98 |
98 |
99 __pkgname__ = "pip-licenses" |
99 __pkgname__ = "pip-licenses" |
100 __version__ = "4.0.2" |
100 __version__ = "4.1.0" |
101 __author__ = "raimon" |
101 __author__ = "raimon" |
102 __license__ = "MIT" |
102 __license__ = "MIT" |
103 __summary__ = ( |
103 __summary__ = ( |
104 "Dump the software license list of Python packages installed with pip." |
104 "Dump the software license list of Python packages installed with pip." |
105 ) |
105 ) |
267 cast(List[str], pkg_info["license_classifier"]), |
267 cast(List[str], pkg_info["license_classifier"]), |
268 cast(str, pkg_info["license"]), |
268 cast(str, pkg_info["license"]), |
269 ) |
269 ) |
270 |
270 |
271 if fail_on_licenses: |
271 if fail_on_licenses: |
272 failed_licenses = license_names.intersection(fail_on_licenses) |
272 failed_licenses = case_insensitive_set_intersect( |
|
273 license_names, fail_on_licenses |
|
274 ) |
273 if failed_licenses: |
275 if failed_licenses: |
274 sys.stderr.write( |
276 sys.stderr.write( |
275 "fail-on license {} was found for package " |
277 "fail-on license {} was found for package " |
276 "{}:{}".format( |
278 "{}:{}".format( |
277 "; ".join(sorted(failed_licenses)), |
279 "; ".join(sorted(failed_licenses)), |
280 ) |
282 ) |
281 ) |
283 ) |
282 sys.exit(1) |
284 sys.exit(1) |
283 |
285 |
284 if allow_only_licenses: |
286 if allow_only_licenses: |
285 uncommon_licenses = license_names.difference(allow_only_licenses) |
287 uncommon_licenses = case_insensitive_set_diff( |
|
288 license_names, allow_only_licenses |
|
289 ) |
286 if len(uncommon_licenses) == len(license_names): |
290 if len(uncommon_licenses) == len(license_names): |
287 sys.stderr.write( |
291 sys.stderr.write( |
288 "license {} not in allow-only licenses was found" |
292 "license {} not in allow-only licenses was found" |
289 " for package {}:{}".format( |
293 " for package {}:{}".format( |
290 "; ".join(sorted(uncommon_licenses)), |
294 "; ".join(sorted(uncommon_licenses)), |
365 }) |
369 }) |
366 |
370 |
367 return licenses |
371 return licenses |
368 |
372 |
369 |
373 |
|
374 def case_insensitive_set_intersect(set_a, set_b): |
|
375 """Same as set.intersection() but case-insensitive""" |
|
376 common_items = set() |
|
377 set_b_lower = {item.lower() for item in set_b} |
|
378 for elem in set_a: |
|
379 if elem.lower() in set_b_lower: |
|
380 common_items.add(elem) |
|
381 return common_items |
|
382 |
|
383 |
|
384 def case_insensitive_set_diff(set_a, set_b): |
|
385 """Same as set.difference() but case-insensitive""" |
|
386 uncommon_items = set() |
|
387 set_b_lower = {item.lower() for item in set_b} |
|
388 for elem in set_a: |
|
389 if not elem.lower() in set_b_lower: |
|
390 uncommon_items.add(elem) |
|
391 return uncommon_items |
|
392 |
|
393 |
370 def find_license_from_classifier(classifiers: list[str]) -> list[str]: |
394 def find_license_from_classifier(classifiers: list[str]) -> list[str]: |
371 licenses = [] |
395 licenses = [] |
372 for classifier in filter(lambda c: c.startswith("License"), classifiers): |
396 for classifier in filter(lambda c: c.startswith("License"), classifiers): |
373 license = classifier.split(" :: ")[-1] |
397 license = classifier.split(" :: ")[-1] |
374 |
398 |