Mon, 06 Mar 2023 09:50:18 +0100
Modified the pip licenses dialog to show the license data for packages contained in the packages list only.
--- a/src/eric7/APIs/Python3/eric7.api Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/APIs/Python3/eric7.api Mon Mar 06 09:50:18 2023 +0100 @@ -3382,8 +3382,7 @@ eric7.PipInterface.Pip.Pip.getIndexUrlPypi?4() eric7.PipInterface.Pip.Pip.getIndexUrlSearch?4() eric7.PipInterface.Pip.Pip.getInstalledPackages?4(envName, localPackages=True, notRequired=False, usersite=False) -eric7.PipInterface.Pip.Pip.getLicenses?4(envName, summary=False) -eric7.PipInterface.Pip.Pip.getLicensesSummary?4(envName) +eric7.PipInterface.Pip.Pip.getLicenses?4(envName) eric7.PipInterface.Pip.Pip.getNetworkAccessManager?4() eric7.PipInterface.Pip.Pip.getOutdatedPackages?4(envName, localPackages=True, notRequired=False, usersite=False, interpreter=None, ) eric7.PipInterface.Pip.Pip.getPackageDetails?4(name, version) @@ -3434,7 +3433,7 @@ eric7.PipInterface.PipLicensesDialog.PipLicensesDialog.LicensesVersionColumn?7 eric7.PipInterface.PipLicensesDialog.PipLicensesDialog.SummaryCountColumn?7 eric7.PipInterface.PipLicensesDialog.PipLicensesDialog.SummaryLicenseColumn?7 -eric7.PipInterface.PipLicensesDialog.PipLicensesDialog?1(pip, environment, localPackages=True, usersite=False, parent=None) +eric7.PipInterface.PipLicensesDialog.PipLicensesDialog?1(pip, environment, packages=None, parent=None) eric7.PipInterface.PipPackageDetailsDialog.PipPackageDetailsDialog.ButtonInstall?7 eric7.PipInterface.PipPackageDetailsDialog.PipPackageDetailsDialog.ButtonRemove?7 eric7.PipInterface.PipPackageDetailsDialog.PipPackageDetailsDialog.ButtonUpgrade?7 @@ -3591,12 +3590,10 @@ eric7.PipInterface.piplicenses.create_licenses_list?4(args: "CustomNamespace", output_fields=DEFAULT_OUTPUT_FIELDS) eric7.PipInterface.piplicenses.create_output_string?4(args: "CustomNamespace") eric7.PipInterface.piplicenses.create_parser?4() -eric7.PipInterface.piplicenses.create_summary_by_license_list?4(args: "CustomNamespace") eric7.PipInterface.piplicenses.create_summary_list?4(args: "CustomNamespace") eric7.PipInterface.piplicenses.enum_key_to_value?4(enum_key: Enum) eric7.PipInterface.piplicenses.filter_string?4(item: str) eric7.PipInterface.piplicenses.find_license_from_classifier?4(classifiers: list[str]) -eric7.PipInterface.piplicenses.get_installed_distributions?4() eric7.PipInterface.piplicenses.get_output_fields?4(args: CustomNamespace) eric7.PipInterface.piplicenses.get_packages?4(args: CustomNamespace, ) eric7.PipInterface.piplicenses.get_pkg_included_file?4(pkg, file_names_rgx: str)
--- a/src/eric7/Documentation/Help/source.qhp Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/Documentation/Help/source.qhp Mon Mar 06 09:50:18 2023 +0100 @@ -11906,7 +11906,6 @@ <keyword name="Pip.getIndexUrlSearch" id="Pip.getIndexUrlSearch" ref="eric7.PipInterface.Pip.html#Pip.getIndexUrlSearch" /> <keyword name="Pip.getInstalledPackages" id="Pip.getInstalledPackages" ref="eric7.PipInterface.Pip.html#Pip.getInstalledPackages" /> <keyword name="Pip.getLicenses" id="Pip.getLicenses" ref="eric7.PipInterface.Pip.html#Pip.getLicenses" /> - <keyword name="Pip.getLicensesSummary" id="Pip.getLicensesSummary" ref="eric7.PipInterface.Pip.html#Pip.getLicensesSummary" /> <keyword name="Pip.getNetworkAccessManager" id="Pip.getNetworkAccessManager" ref="eric7.PipInterface.Pip.html#Pip.getNetworkAccessManager" /> <keyword name="Pip.getOutdatedPackages" id="Pip.getOutdatedPackages" ref="eric7.PipInterface.Pip.html#Pip.getOutdatedPackages" /> <keyword name="Pip.getPackageDetails" id="Pip.getPackageDetails" ref="eric7.PipInterface.Pip.html#Pip.getPackageDetails" /> @@ -11994,6 +11993,7 @@ <keyword name="PipPackagesWidget (Module)" id="PipPackagesWidget (Module)" ref="eric7.PipInterface.PipPackagesWidget.html" /> <keyword name="PipPackagesWidget.__aboutToShowPipMenu" id="PipPackagesWidget.__aboutToShowPipMenu" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.__aboutToShowPipMenu" /> <keyword name="PipPackagesWidget.__addDependency" id="PipPackagesWidget.__addDependency" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.__addDependency" /> + <keyword name="PipPackagesWidget.__allPackageNames" id="PipPackagesWidget.__allPackageNames" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.__allPackageNames" /> <keyword name="PipPackagesWidget.__allUpdateableItems" id="PipPackagesWidget.__allUpdateableItems" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.__allUpdateableItems" /> <keyword name="PipPackagesWidget.__availablePipVersion" id="PipPackagesWidget.__availablePipVersion" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.__availablePipVersion" /> <keyword name="PipPackagesWidget.__checkVulnerability" id="PipPackagesWidget.__checkVulnerability" ref="eric7.PipInterface.PipPackagesWidget.html#PipPackagesWidget.__checkVulnerability" /> @@ -19261,7 +19261,6 @@ <keyword name="create_licenses_list" id="create_licenses_list" ref="eric7.PipInterface.piplicenses.html#create_licenses_list" /> <keyword name="create_output_string" id="create_output_string" ref="eric7.PipInterface.piplicenses.html#create_output_string" /> <keyword name="create_parser" id="create_parser" ref="eric7.PipInterface.piplicenses.html#create_parser" /> - <keyword name="create_summary_by_license_list" id="create_summary_by_license_list" ref="eric7.PipInterface.piplicenses.html#create_summary_by_license_list" /> <keyword name="create_summary_list" id="create_summary_list" ref="eric7.PipInterface.piplicenses.html#create_summary_list" /> <keyword name="critical" id="critical" ref="eric7.EricWidgets.EricMessageBox.html#critical" /> <keyword name="crypto (Package)" id="crypto (Package)" ref="index-eric7.Utilities.crypto.html" /> @@ -19609,7 +19608,6 @@ <keyword name="get_coding" id="get_coding" ref="eric7.Utilities.__init__.html#get_coding" /> <keyword name="get_codingBytes" id="get_codingBytes" ref="eric7.Utilities.__init__.html#get_codingBytes" /> <keyword name="get_installed_distributions" id="get_installed_distributions" ref="eric7.PipInterface.pipdeptree.html#get_installed_distributions" /> - <keyword name="get_installed_distributions" id="get_installed_distributions" ref="eric7.PipInterface.piplicenses.html#get_installed_distributions" /> <keyword name="get_output_fields" id="get_output_fields" ref="eric7.PipInterface.piplicenses.html#get_output_fields" /> <keyword name="get_packages" id="get_packages" ref="eric7.PipInterface.piplicenses.html#get_packages" /> <keyword name="get_parser" id="get_parser" ref="eric7.PipInterface.pipdeptree.html#get_parser" />
--- a/src/eric7/Documentation/Source/eric7.PipInterface.Pip.html Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/Documentation/Source/eric7.PipInterface.Pip.html Mon Mar 06 09:50:18 2023 +0100 @@ -111,10 +111,6 @@ <td>Public method to get the licenses per package for a given environment.</td> </tr> <tr> -<td><a href="#Pip.getLicensesSummary">getLicensesSummary</a></td> -<td>Public method to get a summary of licenses found in a given environment.</td> -</tr> -<tr> <td><a href="#Pip.getNetworkAccessManager">getNetworkAccessManager</a></td> <td>Public method to get a reference to the network access manager object.</td> </tr> @@ -529,7 +525,7 @@ </dl> <a NAME="Pip.getLicenses" ID="Pip.getLicenses"></a> <h4>Pip.getLicenses</h4> -<b>getLicenses</b>(<i>envName, summary=False</i>) +<b>getLicenses</b>(<i>envName</i>) <p> Public method to get the licenses per package for a given environment. @@ -540,11 +536,6 @@ <dd> name of the environment to get the licenses for </dd> -<dt><i>summary</i> (bool (optional))</dt> -<dd> -flag indicating to get a summary listing (defaults to - False) -</dd> </dl> <dl> <dt>Return:</dt> @@ -559,34 +550,6 @@ dict </dd> </dl> -<a NAME="Pip.getLicensesSummary" ID="Pip.getLicensesSummary"></a> -<h4>Pip.getLicensesSummary</h4> -<b>getLicensesSummary</b>(<i>envName</i>) - -<p> - Public method to get a summary of licenses found in a given - environment. -</p> -<dl> - -<dt><i>envName</i> (str)</dt> -<dd> -name of the environment to get the licenses summary for -</dd> -</dl> -<dl> -<dt>Return:</dt> -<dd> -list of dictionaries containing the license and the count of - packages -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -dict -</dd> -</dl> <a NAME="Pip.getNetworkAccessManager" ID="Pip.getNetworkAccessManager"></a> <h4>Pip.getNetworkAccessManager</h4> <b>getNetworkAccessManager</b>(<i></i>)
--- a/src/eric7/Documentation/Source/eric7.PipInterface.PipLicensesDialog.html Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/Documentation/Source/eric7.PipInterface.PipLicensesDialog.html Mon Mar 06 09:50:18 2023 +0100 @@ -79,7 +79,7 @@ <a NAME="PipLicensesDialog.__init__" ID="PipLicensesDialog.__init__"></a> <h4>PipLicensesDialog (Constructor)</h4> -<b>PipLicensesDialog</b>(<i>pip, environment, localPackages=True, usersite=False, parent=None</i>) +<b>PipLicensesDialog</b>(<i>pip, environment, packages=None, parent=None</i>) <p> Constructor @@ -94,15 +94,10 @@ <dd> name of the environment to show the licenses for </dd> -<dt><i>localPackages</i> (bool)</dt> +<dt><i>packages</i> (list (optional))</dt> <dd> -flag indicating to show the licenses for local - packages only -</dd> -<dt><i>usersite</i> (bool)</dt> -<dd> -flag indicating to show the licenses for packages - installed in user-site directory only +list of packages to show licenses for (or None to show all + licenses (defaults to None) </dd> <dt><i>parent</i> (QWidget (optional))</dt> <dd>
--- a/src/eric7/Documentation/Source/eric7.PipInterface.PipPackagesWidget.html Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/Documentation/Source/eric7.PipInterface.PipPackagesWidget.html Mon Mar 06 09:50:18 2023 +0100 @@ -71,6 +71,10 @@ <td>Private method to add a dependency branch to a given parent.</td> </tr> <tr> +<td><a href="#PipPackagesWidget.__allPackageNames">__allPackageNames</a></td> +<td>Private method to get a list of all package names.</td> +</tr> +<tr> <td><a href="#PipPackagesWidget.__allUpdateableItems">__allUpdateableItems</a></td> <td>Private method to get a list of all items that can be updated.</td> </tr> @@ -468,6 +472,25 @@ reference to the parent item </dd> </dl> +<a NAME="PipPackagesWidget.__allPackageNames" ID="PipPackagesWidget.__allPackageNames"></a> +<h4>PipPackagesWidget.__allPackageNames</h4> +<b>__allPackageNames</b>(<i></i>) + +<p> + Private method to get a list of all package names. +</p> +<dl> +<dt>Return:</dt> +<dd> +list of all package names +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +list of str +</dd> +</dl> <a NAME="PipPackagesWidget.__allUpdateableItems" ID="PipPackagesWidget.__allUpdateableItems"></a> <h4>PipPackagesWidget.__allUpdateableItems</h4> <b>__allUpdateableItems</b>(<i></i>)
--- a/src/eric7/Documentation/Source/eric7.PipInterface.piplicenses.html Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/Documentation/Source/eric7.PipInterface.piplicenses.html Mon Mar 06 09:50:18 2023 +0100 @@ -105,10 +105,6 @@ <td></td> </tr> <tr> -<td><a href="#create_summary_by_license_list">create_summary_by_license_list</a></td> -<td></td> -</tr> -<tr> <td><a href="#create_summary_list">create_summary_list</a></td> <td></td> </tr> @@ -125,10 +121,6 @@ <td></td> </tr> <tr> -<td><a href="#get_installed_distributions">get_installed_distributions</a></td> -<td>Function to get the installed packages via pip.</td> -</tr> -<tr> <td><a href="#get_output_fields">get_output_fields</a></td> <td></td> </tr> @@ -474,13 +466,6 @@ <div align="right"><a href="#top">Up</a></div> <hr /> <hr /> -<a NAME="create_summary_by_license_list" ID="create_summary_by_license_list"></a> -<h2>create_summary_by_license_list</h2> -<b>create_summary_by_license_list</b>(<i>args: "CustomNamespace"</i>) - -<div align="right"><a href="#top">Up</a></div> -<hr /> -<hr /> <a NAME="create_summary_list" ID="create_summary_list"></a> <h2>create_summary_list</h2> <b>create_summary_list</b>(<i>args: "CustomNamespace"</i>) @@ -509,28 +494,6 @@ <div align="right"><a href="#top">Up</a></div> <hr /> <hr /> -<a NAME="get_installed_distributions" ID="get_installed_distributions"></a> -<h2>get_installed_distributions</h2> -<b>get_installed_distributions</b>(<i></i>) - -<p> - Function to get the installed packages via pip. -</p> -<dl> -<dt>Return:</dt> -<dd> -list of installed distributions -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -list -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -<hr /> <a NAME="get_output_fields" ID="get_output_fields"></a> <h2>get_output_fields</h2> <b>get_output_fields</b>(<i>args: CustomNamespace</i>)
--- a/src/eric7/PipInterface/Pip.py Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/PipInterface/Pip.py Mon Mar 06 09:50:18 2023 +0100 @@ -1047,15 +1047,12 @@ ## License handling methods below ####################################################################### - def getLicenses(self, envName, summary=False): + def getLicenses(self, envName): """ Public method to get the licenses per package for a given environment. @param envName name of the environment to get the licenses for @type str - @param summary flag indicating to get a summary listing (defaults to - False) - @type bool (optional) @return list of dictionaries containing the license and version per package @rtype dict @@ -1074,8 +1071,6 @@ "--with-urls", "--with-description", ] - if summary: - args.append("--summary-by-license") proc = QProcess() proc.start(interpreter, args) @@ -1089,16 +1084,3 @@ licenses = json.loads(output) return licenses - - def getLicensesSummary(self, envName): - """ - Public method to get a summary of licenses found in a given - environment. - - @param envName name of the environment to get the licenses summary for - @type str - @return list of dictionaries containing the license and the count of - packages - @rtype dict - """ - return self.getLicenses(envName, summary=True)
--- a/src/eric7/PipInterface/PipLicensesDialog.py Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/PipInterface/PipLicensesDialog.py Mon Mar 06 09:50:18 2023 +0100 @@ -11,6 +11,8 @@ import os import re +from collections import Counter + from PyQt6.QtCore import Qt, pyqtSlot from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem @@ -32,9 +34,7 @@ SummaryCountColumn = 0 SummaryLicenseColumn = 1 - def __init__( - self, pip, environment, localPackages=True, usersite=False, parent=None - ): + def __init__(self, pip, environment, packages=None, parent=None): """ Constructor @@ -42,12 +42,9 @@ @type Pip @param environment name of the environment to show the licenses for @type str - @param localPackages flag indicating to show the licenses for local - packages only - @type bool - @param usersite flag indicating to show the licenses for packages - installed in user-site directory only - @type bool + @param packages list of packages to show licenses for (or None to show all + licenses (defaults to None) + @type list (optional) @param parent reference to the parent widget (defaults to None) @type QWidget (optional) """ @@ -56,6 +53,7 @@ self.__pip = pip self.__environment = environment + self.__packages = packages[:] if packages is not None else None self.__allFilter = self.tr("<All>") @@ -91,19 +89,24 @@ self.licenseFilterComboBox.clear() licensesForFilter = set() + licenseSummaryList = [] # step 1: show the licenses per package self.licensesList.setUpdatesEnabled(False) licenses = self.__pip.getLicenses(self.__environment) for lic in licenses: - QTreeWidgetItem( - self.licensesList, - [ - lic["Name"], - lic["Version"], - lic["License"].replace("; ", "\n"), - ], - ) + if self.__packages is None or lic["Name"] in self.__packages: + QTreeWidgetItem( + self.licensesList, + [ + lic["Name"], + lic["Version"], + lic["License"].replace("; ", "\n"), + ], + ) + licenseSummaryList.extend( + x.strip() for x in lic["License"].split("; ") + ) self.licensesList.sortItems( PipLicensesDialog.LicensesPackageColumn, Qt.SortOrder.AscendingOrder @@ -114,16 +117,16 @@ # step 2: show the licenses summary self.summaryList.setUpdatesEnabled(False) - licenses = self.__pip.getLicensesSummary(self.__environment) - for lic in licenses: + licenseCounter = Counter(licenseSummaryList) + for lic in licenseCounter: QTreeWidgetItem( self.summaryList, [ - "{0:4d}".format(lic["Count"]), - lic["License"].replace("; ", "\n"), + "{0:4d}".format(licenseCounter[lic]), + lic, ], ) - licensesForFilter |= set(lic["License"].split("; ")) + licensesForFilter.add(lic) self.summaryList.sortItems( PipLicensesDialog.SummaryLicenseColumn, Qt.SortOrder.AscendingOrder
--- a/src/eric7/PipInterface/PipPackagesWidget.py Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/PipInterface/PipPackagesWidget.py Mon Mar 06 09:50:18 2023 +0100 @@ -377,6 +377,18 @@ if bool(itm.text(PipPackagesWidget.AvailableVersionColumn)) ] + def __allPackageNames(self): + """ + Private method to get a list of all package names. + + @return list of all package names + @rtype list of str + """ + packages = [] + for index in range(self.packagesList.topLevelItemCount()): + packages.append(self.packagesList.topLevelItem(index).text(0)) + return packages + def __allUpdateableItems(self): """ Private method to get a list of all items that can be updated. @@ -1984,21 +1996,10 @@ from .PipLicensesDialog import PipLicensesDialog environment = self.environmentsComboBox.currentText() - localPackages = ( - self.localDepCheckBox.isChecked() - if self.viewToggleButton.isChecked() - else self.localCheckBox.isChecked() - ) - usersite = ( - self.userDepCheckBox.isChecked() - if self.viewToggleButton.isChecked() - else self.userCheckBox.isChecked() - ) dlg = PipLicensesDialog( self.__pip, environment, - localPackages=localPackages, - usersite=usersite, + packages=self.__allPackageNames(), parent=self, ) dlg.exec()
--- a/src/eric7/PipInterface/piplicenses.py Sun Mar 05 17:07:49 2023 +0100 +++ b/src/eric7/PipInterface/piplicenses.py Mon Mar 06 09:50:18 2023 +0100 @@ -37,12 +37,7 @@ # - removed some not needed code # - changed 'create_licenses_table' to 'create_licenses_list' # - changed 'create_summary_table' to 'create_summary_list' -# - added 'create_summary_by_license_list' together with the -# '--summary-by-license' switch to count each individual -# license used # - changed 'create_output_string' to return a JSON string -# - added 'get_installed_distributions' to get the distributions -# via pip in order to filter for 'local only' and/or 'user only' # from __future__ import annotations @@ -57,42 +52,16 @@ from pathlib import Path from typing import TYPE_CHECKING, List, Type, cast +# modified for 'eric-ide' for Python < 3.8 +try: + from importlib import metadata as importlib_metadata +except ImportError: + importlib_metadata = None + if TYPE_CHECKING: from typing import Iterator, Optional, Sequence -def get_installed_distributions(): - """ - Function to get the installed packages via pip. - - @return list of installed distributions - @rtype list - """ - try: - from importlib import metadata as importlib_metadata - return importlib_metadata.distributions() - except ImportError: - try: - from pip._internal.metadata import get_environment - except ImportError: - # For backward compatibility with pip version 20.3.4 - from pip._internal.utils import misc - return misc.get_installed_distributions( - local_only=True, - user_only=False - ) - else: - from pip._internal.utils.compat import stdlib_pkgs - dists = get_environment(None).iter_installed_distributions( - local_only=True, - user_only=False, - skip=stdlib_pkgs, - include_editables=True, - editables_only=False, - ) - return [d._dist for d in dists] - - __pkgname__ = "pip-licenses" __version__ = "4.1.0" __author__ = "raimon" @@ -230,7 +199,11 @@ return pkg_info - pkgs = get_installed_distributions() + # modified for 'eric-ide' for Python < 3.8 + if importlib_metadata is None: + return [] + else: + pkgs = importlib_metadata.distributions() ignore_pkgs_as_lower = [pkg.lower() for pkg in args.ignore_packages] pkgs_as_lower = [pkg.lower() for pkg in args.packages] @@ -295,6 +268,7 @@ yield pkg_info +# modified for 'eric-ide' def create_licenses_list( args: "CustomNamespace", output_fields=DEFAULT_OUTPUT_FIELDS): @@ -324,6 +298,7 @@ return licenses +# modified for 'eric-ide' def create_summary_list(args: "CustomNamespace"): counts = Counter( "; ".join( @@ -348,23 +323,6 @@ return licenses -def create_summary_by_license_list(args: "CustomNamespace"): - licenses_list = [] - for pkg in get_packages(args): - licenses_list.extend(select_license_by_source( - args.from_, pkg['license_classifier'], pkg['license'])) - counts = Counter(licenses_list) - - licenses = [] - for license, count in counts.items(): - licenses.append({ - "Count": count, - "License": license, - }) - - return licenses - - def case_insensitive_set_intersect(set_a, set_b): """Same as set.intersection() but case-insensitive""" common_items = set() @@ -446,13 +404,12 @@ return output_fields +# modified for 'eric-ide' def create_output_string(args: "CustomNamespace"): output_fields = get_output_fields(args) if args.summary: licenses = create_summary_list(args) - elif args.summary_by_license: - licenses = create_summary_by_license_list(args) else: licenses = create_licenses_list(args, output_fields) @@ -509,9 +466,6 @@ from_: "FromArg" order: "OrderArg" summary: bool - summary_by_license: bool - local_only: bool - user_only:bool output_file: str ignore_packages: List[str] packages: List[str] @@ -658,11 +612,6 @@ default=False, help='dump summary of each license') common_options.add_argument( - '--summary-by-license', - action='store_true', - default=False, - help='dump summary of each individual license') - common_options.add_argument( '--output-file', action='store', type=str, help='save license list to file') @@ -686,16 +635,6 @@ default=[], help="only include selected packages in output", ) - common_options.add_argument( - '--local-only', - action='store_true', - default=False, - help='include only local packages') - common_options.add_argument( - '--user-only', - action='store_true', - default=False, - help='include only packages of the user site dir') format_options.add_argument( "-s",