diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py --- a/src/eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Plugins/WizardPlugins/SetupWizard/SetupWizardDialog.py Wed Jul 13 14:55:47 2022 +0200 @@ -18,9 +18,7 @@ import trove_classifiers from PyQt6.QtCore import pyqtSlot, Qt -from PyQt6.QtWidgets import ( - QDialog, QDialogButtonBox, QTreeWidgetItem, QListWidgetItem -) +from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem, QListWidgetItem from EricWidgets.EricApplication import ericApp from EricWidgets import EricFileDialog @@ -37,14 +35,15 @@ class SetupWizardDialog(QDialog, Ui_SetupWizardDialog): """ Class implementing the setup.py wizard dialog. - + It displays a dialog for entering the parameters for the setup.py code generator. """ + def __init__(self, category, editor, parent=None): """ Constructor - + @param category category of setup file to create @type str @param editor reference to the editor object to receive the code @@ -55,58 +54,63 @@ """ if category not in ("setup.py", "setup.cfg", "pyproject.toml"): raise ValueError("illegal setup file category given") - + super().__init__(parent) self.setupUi(self) - + self.setWindowTitle(self.tr("{0} Wizard").format(category)) - + self.__replies = [] self.__category = category self.__editor = editor - + if category != "setup.py": self.introCheckBox.setVisible(False) self.importCheckBox.setVisible(False) self.metaDataCheckBox.setVisible(False) - + self.dataTabWidget.setCurrentIndex(0) - + self.packageRootPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) self.sourceDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) - + self.__mandatoryStyleSheet = ( "QLineEdit {border: 2px solid; border-color: #dd8888}" - if ericApp().usesDarkPalette() else - "QLineEdit {border: 2px solid; border-color: #800000}" + if ericApp().usesDarkPalette() + else "QLineEdit {border: 2px solid; border-color: #800000}" ) - for lineEdit in [self.nameEdit, self.versionEdit, - self.homePageUrlEdit, self.authorEdit, - self.authorEmailEdit, self.maintainerEdit, - self.maintainerEmailEdit]: + for lineEdit in [ + self.nameEdit, + self.versionEdit, + self.homePageUrlEdit, + self.authorEdit, + self.authorEmailEdit, + self.maintainerEdit, + self.maintainerEmailEdit, + ]: lineEdit.setStyleSheet(self.__mandatoryStyleSheet) - + self.__populateClassifiers() - - self.__okButton = self.buttonBox.button( - QDialogButtonBox.StandardButton.Ok) + + self.__okButton = self.buttonBox.button(QDialogButtonBox.StandardButton.Ok) self.__okButton.setEnabled(False) - + projectOpen = ericApp().getObject("Project").isOpen() self.projectButton.setEnabled(projectOpen) - + self.projectUrlsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder) self.entryPointsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder) - + self.descriptionContentTypeComboBox.addItem("", "") - for contentType, mimetype in sorted([ - (self.tr("Plain Text"), "text/plain"), - (self.tr("Markdown"), "text/markdown"), - (self.tr("reStructuredText"), "text/x-rst") - - ]): + for contentType, mimetype in sorted( + [ + (self.tr("Plain Text"), "text/plain"), + (self.tr("Markdown"), "text/markdown"), + (self.tr("reStructuredText"), "text/x-rst"), + ] + ): self.descriptionContentTypeComboBox.addItem(contentType, mimetype) - + self.homePageUrlEdit.textChanged.connect(self.__enableOkButton) self.nameEdit.textChanged.connect(self.__enableOkButton) self.versionEdit.textChanged.connect(self.__enableOkButton) @@ -114,24 +118,27 @@ self.authorEmailEdit.textChanged.connect(self.__enableOkButton) self.maintainerEdit.textChanged.connect(self.__enableOkButton) self.maintainerEmailEdit.textChanged.connect(self.__enableOkButton) - + def __enableOkButton(self): """ Private slot to set the state of the OK button. """ enable = ( - bool(self.nameEdit.text()) and - bool(self.versionEdit.text()) and - bool(self.homePageUrlEdit.text()) and - ((bool(self.authorEdit.text()) and - bool(self.authorEmailEdit.text())) or - (bool(self.maintainerEdit.text()) and - bool(self.maintainerEmailEdit.text()))) and - self.homePageUrlEdit.text().startswith(("http://", "https://")) + bool(self.nameEdit.text()) + and bool(self.versionEdit.text()) + and bool(self.homePageUrlEdit.text()) + and ( + (bool(self.authorEdit.text()) and bool(self.authorEmailEdit.text())) + or ( + bool(self.maintainerEdit.text()) + and bool(self.maintainerEmailEdit.text()) + ) + ) + and self.homePageUrlEdit.text().startswith(("http://", "https://")) ) - + self.__okButton.setEnabled(enable) - + def __populateClassifiers(self): """ Private method to populate the classifiers. @@ -139,34 +146,33 @@ self.licenseClassifierComboBox.clear() self.classifiersList.clear() self.developmentStatusComboBox.clear() - + self.developmentStatusComboBox.addItem("", "") - + self.__classifiersDict = {} for classifier in trove_classifiers.sorted_classifiers: if classifier.startswith("License ::"): self.licenseClassifierComboBox.addItem( - "/".join(classifier.split(" :: ")[1:]), - classifier + "/".join(classifier.split(" :: ")[1:]), classifier ) elif classifier.startswith("Development Status ::"): self.developmentStatusComboBox.addItem( - classifier.split(" :: ")[1], classifier) + classifier.split(" :: ")[1], classifier + ) else: self.__addClassifierEntry(classifier) self.__classifiersDict = {} - + self.licenseClassifierComboBox.setCurrentIndex( self.licenseClassifierComboBox.findText( - "(GPLv3)", - Qt.MatchFlag.MatchContains | Qt.MatchFlag.MatchCaseSensitive + "(GPLv3)", Qt.MatchFlag.MatchContains | Qt.MatchFlag.MatchCaseSensitive ) ) - + def __addClassifierEntry(self, classifier): """ Private method to add a new entry to the list of trove classifiers. - + @param classifier classifier containing the data for the entry @type str """ @@ -174,11 +180,10 @@ pitm = None dataList = classifier.split(" :: ") for index in range(len(dataList)): - key = " :: ".join(dataList[:index + 1]) + key = " :: ".join(dataList[: index + 1]) if key not in self.__classifiersDict: if pitm is None: - itm = QTreeWidgetItem( - self.classifiersList, [dataList[index]]) + itm = QTreeWidgetItem(self.classifiersList, [dataList[index]]) pitm = itm else: itm = QTreeWidgetItem(pitm, [dataList[index]]) @@ -188,11 +193,11 @@ pitm = self.__classifiersDict[key] itm.setCheckState(0, Qt.CheckState.Unchecked) itm.setData(0, Qt.ItemDataRole.UserRole, classifier) - + def __getLicenseText(self): """ Private method to get the license text. - + @return license text @rtype str """ @@ -203,11 +208,11 @@ if "(" in lic: lic = lic.rsplit("(", 1)[1].split(")", 1)[0] return lic - + def __getSetupPyCode(self, indLevel, indString): """ Private method to get the source code for a 'setup.py' file. - + @param indLevel indentation level @type int @param indString string used for indentation (space or tab) @@ -216,201 +221,226 @@ @rtype str """ # Note: all paths are created with '/'; setup will do the right thing - + # calculate our indentation level and the indentation string il = indLevel + 1 istring = il * indString i1string = (il + 1) * indString i2string = (il + 2) * indString estring = os.linesep + indLevel * indString - + # now generate the code if self.introCheckBox.isChecked(): sourceCode = "#!/usr/bin/env python3{0}".format(os.linesep) sourceCode += "# -*- coding: utf-8 -*-{0}{0}".format(os.linesep) else: sourceCode = "" - + if self.metaDataCheckBox.isChecked(): - sourceCode += '# metadata{0}'.format(os.linesep) + sourceCode += "# metadata{0}".format(os.linesep) sourceCode += '"{0}"{1}'.format( - self.summaryEdit.text() or "Setup routine", - os.linesep + self.summaryEdit.text() or "Setup routine", os.linesep ) sourceCode += '__version__ = "{0}"{1}'.format( - self.versionEdit.text(), os.linesep) + self.versionEdit.text(), os.linesep + ) sourceCode += '__license__ = "{0}"{1}'.format( - self.__getLicenseText(), os.linesep) + self.__getLicenseText(), os.linesep + ) sourceCode += '__author__ = "{0}"{1}'.format( - self.authorEdit.text() or self.maintainerEdit.text(), - os.linesep) + self.authorEdit.text() or self.maintainerEdit.text(), os.linesep + ) sourceCode += '__email__ = "{0}"{1}'.format( self.authorEmailEdit.text() or self.maintainerEmailEdit.text(), - os.linesep) + os.linesep, + ) sourceCode += '__url__ = "{0}"{1}'.format( - self.homePageUrlEdit.text(), os.linesep) + self.homePageUrlEdit.text(), os.linesep + ) sourceCode += '__date__ = "{0}"{1}'.format( - datetime.datetime.now().isoformat().split('.')[0], os.linesep) - sourceCode += '__prj__ = "{0}"{1}'.format( - self.nameEdit.text(), os.linesep) + datetime.datetime.now().isoformat().split(".")[0], os.linesep + ) + sourceCode += '__prj__ = "{0}"{1}'.format(self.nameEdit.text(), os.linesep) sourceCode += os.linesep - + if self.importCheckBox.isChecked(): additionalImport = ", find_packages" sourceCode += "from setuptools import setup{0}{1}".format( - additionalImport, os.linesep) + additionalImport, os.linesep + ) if sourceCode: sourceCode += "{0}{0}".format(os.linesep) - + if self.descriptionFromFilesCheckBox.isChecked(): - sourceCode += 'def get_long_description():{0}'.format(os.linesep) - sourceCode += '{0}descr = []{1}'.format(istring, os.linesep) + sourceCode += "def get_long_description():{0}".format(os.linesep) + sourceCode += "{0}descr = []{1}".format(istring, os.linesep) sourceCode += '{0}for fname in ("{1}"):{2}'.format( istring, '", "'.join(self.descriptionEdit.toPlainText().splitlines()), - os.linesep) + os.linesep, + ) sourceCode += ( '{0}with open(fname, "r", encoding="utf-8") as f:{1}' ).format(i1string, os.linesep) - sourceCode += '{0}descr.append(f.read()){1}'.format( - i2string, os.linesep) + sourceCode += "{0}descr.append(f.read()){1}".format(i2string, os.linesep) sourceCode += '{0}return "\\n\\n".join(descr){1}'.format( - istring, os.linesep) + istring, os.linesep + ) sourceCode += "{0}{0}".format(os.linesep) - - sourceCode += 'setup({0}'.format(os.linesep) + + sourceCode += "setup({0}".format(os.linesep) sourceCode += '{0}name="{1}",{2}'.format( - istring, self.nameEdit.text(), os.linesep) + istring, self.nameEdit.text(), os.linesep + ) sourceCode += '{0}version="{1}",{2}'.format( - istring, self.versionEdit.text(), os.linesep) - + istring, self.versionEdit.text(), os.linesep + ) + if self.summaryEdit.text(): sourceCode += '{0}description="{1}",{2}'.format( - istring, self.summaryEdit.text(), os.linesep) - + istring, self.summaryEdit.text(), os.linesep + ) + if self.descriptionFromFilesCheckBox.isChecked(): - sourceCode += '{0}long_description=get_long_description(),{1}'.format( - istring, os.linesep) + sourceCode += "{0}long_description=get_long_description(),{1}".format( + istring, os.linesep + ) elif self.descriptionEdit.toPlainText(): sourceCode += '{0}long_description="""{1}""",{2}'.format( - istring, self.descriptionEdit.toPlainText(), os.linesep) - + istring, self.descriptionEdit.toPlainText(), os.linesep + ) + if self.descriptionContentTypeComboBox.currentData(): sourceCode += '{0}long_description_content_type="{1}",{2}'.format( - istring, self.descriptionContentTypeComboBox.currentData(), os.linesep) - + istring, self.descriptionContentTypeComboBox.currentData(), os.linesep + ) + if self.authorEdit.text(): sourceCode += '{0}author="{1}",{2}'.format( - istring, self.authorEdit.text(), os.linesep) + istring, self.authorEdit.text(), os.linesep + ) sourceCode += '{0}author_email="{1}",{2}'.format( - istring, self.authorEmailEdit.text(), os.linesep) - + istring, self.authorEmailEdit.text(), os.linesep + ) + if self.maintainerEdit.text(): sourceCode += '{0}maintainer="{1}",{2}'.format( - istring, self.maintainerEdit.text(), os.linesep) + istring, self.maintainerEdit.text(), os.linesep + ) sourceCode += '{0}maintainer_email="{1}",{2}'.format( - istring, self.maintainerEmailEdit.text(), os.linesep) - + istring, self.maintainerEmailEdit.text(), os.linesep + ) + sourceCode += '{0}url="{1}",{2}'.format( - istring, self.homePageUrlEdit.text(), os.linesep) + istring, self.homePageUrlEdit.text(), os.linesep + ) if self.downloadUrlEdit.text(): sourceCode += '{0}download_url="{1}",{2}'.format( - istring, self.downloadUrlEdit.text(), os.linesep) - + istring, self.downloadUrlEdit.text(), os.linesep + ) + if self.projectUrlsList.topLevelItemCount(): - sourceCode += '{0}project_urls={{{1}'.format(istring, os.linesep) + sourceCode += "{0}project_urls={{{1}".format(istring, os.linesep) for row in range(self.projectUrlsList.topLevelItemCount()): urlItem = self.projectUrlsList.topLevelItem(row) sourceCode += '{0}"{1}": "{2}",{3}'.format( - i1string, urlItem.text(0), urlItem.text(1), os.linesep) - sourceCode += '{0}}},{1}'.format(istring, os.linesep) - + i1string, urlItem.text(0), urlItem.text(1), os.linesep + ) + sourceCode += "{0}}},{1}".format(istring, os.linesep) + classifiers = [] if not self.licenseClassifierCheckBox.isChecked(): sourceCode += '{0}license="{1}",{2}'.format( - istring, self.licenseEdit.text(), os.linesep) + istring, self.licenseEdit.text(), os.linesep + ) else: classifiers.append( self.licenseClassifierComboBox.itemData( - self.licenseClassifierComboBox.currentIndex())) - + self.licenseClassifierComboBox.currentIndex() + ) + ) + platforms = self.platformsEdit.toPlainText().splitlines() if platforms: - sourceCode += '{0}platforms=[{1}'.format(istring, os.linesep) + sourceCode += "{0}platforms=[{1}".format(istring, os.linesep) sourceCode += '{0}"{1}"{2}'.format( i1string, '",{0}{1}"'.format(os.linesep, i1string).join(platforms), - os.linesep) - sourceCode += '{0}],{1}'.format(istring, os.linesep) - + os.linesep, + ) + sourceCode += "{0}],{1}".format(istring, os.linesep) + if self.developmentStatusComboBox.currentIndex() != 0: classifiers.append(self.developmentStatusComboBox.currentData()) - + itm = self.classifiersList.topLevelItem(0) while itm: itm.setExpanded(True) if itm.checkState(0) == Qt.CheckState.Checked: classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole)) itm = self.classifiersList.itemBelow(itm) - + # cleanup classifiers list - remove all invalid entries classifiers = [c for c in classifiers if bool(c)] if classifiers: - sourceCode += '{0}classifiers=[{1}'.format(istring, os.linesep) + sourceCode += "{0}classifiers=[{1}".format(istring, os.linesep) sourceCode += '{0}"{1}"{2}'.format( i1string, '",{0}{1}"'.format(os.linesep, i1string).join(classifiers), - os.linesep) - sourceCode += '{0}],{1}'.format(istring, os.linesep) + os.linesep, + ) + sourceCode += "{0}],{1}".format(istring, os.linesep) del classifiers - + if self.keywordsEdit.text(): sourceCode += '{0}keywords="{1}",{2}'.format( - istring, self.keywordsEdit.text(), os.linesep) - + istring, self.keywordsEdit.text(), os.linesep + ) + if self.pyVersionEdit.text(): sourceCode += '{0}python_requires="{1}",{2}'.format( - istring, self.pyVersionEdit.text(), os.linesep) - - sourceCode += '{0}packages=find_packages('.format(istring) - src = Utilities.fromNativeSeparators( - self.sourceDirectoryPicker.text()) + istring, self.pyVersionEdit.text(), os.linesep + ) + + sourceCode += "{0}packages=find_packages(".format(istring) + src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text()) excludePatterns = [] for row in range(self.excludePatternList.count()): - excludePatterns.append( - self.excludePatternList.item(row).text()) + excludePatterns.append(self.excludePatternList.item(row).text()) if src: sourceCode += '{0}{1}"{2}"'.format(os.linesep, i1string, src) if excludePatterns: - sourceCode += ',' + sourceCode += "," else: - sourceCode += '{0}{1}'.format(os.linesep, istring) + sourceCode += "{0}{1}".format(os.linesep, istring) if excludePatterns: - sourceCode += '{0}{1}exclude=[{0}'.format(os.linesep, i1string) + sourceCode += "{0}{1}exclude=[{0}".format(os.linesep, i1string) sourceCode += '{0}"{1}"{2}'.format( i2string, - '",{0}{1}"'.format(os.linesep, i2string) - .join(excludePatterns), - os.linesep) - sourceCode += '{0}]{1}{2}'.format(i1string, os.linesep, istring) - sourceCode += '),{0}'.format(os.linesep) - + '",{0}{1}"'.format(os.linesep, i2string).join(excludePatterns), + os.linesep, + ) + sourceCode += "{0}]{1}{2}".format(i1string, os.linesep, istring) + sourceCode += "),{0}".format(os.linesep) + if self.includePackageDataCheckBox.isChecked(): - sourceCode += '{0}include_package_data = True,{1}'.format( - istring, os.linesep) - + sourceCode += "{0}include_package_data = True,{1}".format( + istring, os.linesep + ) + modules = [] for row in range(self.modulesList.count()): modules.append(self.modulesList.item(row).text()) if modules: - sourceCode += '{0}py_modules=[{1}'.format(istring, os.linesep) + sourceCode += "{0}py_modules=[{1}".format(istring, os.linesep) sourceCode += '{0}"{1}"{2}'.format( i1string, '",{0}{1}"'.format(os.linesep, i1string).join(modules), - os.linesep) - sourceCode += '{0}],{1}'.format(istring, os.linesep) + os.linesep, + ) + sourceCode += "{0}],{1}".format(istring, os.linesep) del modules - + if self.entryPointsList.topLevelItemCount(): entryPoints = { "console_scripts": [], @@ -421,131 +451,134 @@ entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)].append( "{0} = {1}".format(itm.text(1), itm.text(2)) ) - sourceCode += '{0}entry_points={{{1}'.format(istring, os.linesep) + sourceCode += "{0}entry_points={{{1}".format(istring, os.linesep) for epCategory in entryPoints: if entryPoints[epCategory]: sourceCode += '{0}"{1}": [{2}'.format( - i1string, epCategory, os.linesep) + i1string, epCategory, os.linesep + ) for entryPoint in entryPoints[epCategory]: sourceCode += '{0}"{1}",{2}'.format( - i2string, entryPoint, os.linesep) - sourceCode += '{0}],{1}'.format(i1string, os.linesep) - sourceCode += '{0}}},{1}'.format(istring, os.linesep) - + i2string, entryPoint, os.linesep + ) + sourceCode += "{0}],{1}".format(i1string, os.linesep) + sourceCode += "{0}}},{1}".format(istring, os.linesep) + sourceCode += "){0}".format(estring) return sourceCode - + def __getSetupCfgCode(self): """ Private method to get the source code for a 'setup.cfg' file. - + @return generated code @rtype str """ from . import SetupCfgUtilities + metadata = { "name": self.nameEdit.text(), "version": self.versionEdit.text(), } - + if self.summaryEdit.text(): metadata["description"] = self.summaryEdit.text() - + if self.descriptionEdit.toPlainText(): metadata["long_description"] = ( "file: {0}".format( ", ".join(self.descriptionEdit.toPlainText().splitlines()) ) - if self.descriptionFromFilesCheckBox.isChecked() else - self.descriptionEdit.toPlainText() + if self.descriptionFromFilesCheckBox.isChecked() + else self.descriptionEdit.toPlainText() ) - + if self.descriptionContentTypeComboBox.currentData(): - metadata["long_description_content_type"] = ( - self.descriptionContentTypeComboBox.currentData() - ) - + metadata[ + "long_description_content_type" + ] = self.descriptionContentTypeComboBox.currentData() + if self.authorEdit.text(): metadata["author"] = self.authorEdit.text() metadata["author_email"] = self.authorEmailEdit.text() - + if self.maintainerEdit.text(): metadata["maintainer"] = self.maintainerEdit.text() metadata["maintainer_email"] = self.maintainerEmailEdit.text() - + metadata["url"] = self.homePageUrlEdit.text() if self.downloadUrlEdit.text(): metadata["download_url"] = self.downloadUrlEdit.text() - + if self.projectUrlsList.topLevelItemCount(): projectURLs = {} for row in range(self.projectUrlsList.topLevelItemCount()): urlItem = self.projectUrlsList.topLevelItem(row) projectURLs[urlItem.text(0)] = urlItem.text(1) metadata["project_urls"] = SetupCfgUtilities.toString(projectURLs) - + classifiers = [] if not self.licenseClassifierCheckBox.isChecked(): metadata["license"] = self.licenseEdit.text() else: classifiers.append( self.licenseClassifierComboBox.itemData( - self.licenseClassifierComboBox.currentIndex())) - + self.licenseClassifierComboBox.currentIndex() + ) + ) + platforms = self.platformsEdit.toPlainText().splitlines() if platforms: metadata["platforms"] = SetupCfgUtilities.toString(platforms) - + if self.developmentStatusComboBox.currentIndex() != 0: classifiers.append(self.developmentStatusComboBox.currentData()) - + itm = self.classifiersList.topLevelItem(0) while itm: itm.setExpanded(True) if itm.checkState(0) == Qt.CheckState.Checked: classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole)) itm = self.classifiersList.itemBelow(itm) - + # cleanup classifiers list - remove all invalid entries classifiers = [c for c in classifiers if bool(c)] if classifiers: metadata["classifiers"] = SetupCfgUtilities.toString(classifiers) - + if self.keywordsEdit.text(): metadata["keywords"] = SetupCfgUtilities.toString( - self.keywordsEdit.text().split()) - - options = { - "packages": "find:" - } - + self.keywordsEdit.text().split() + ) + + options = {"packages": "find:"} + if self.pyVersionEdit.text(): options["python_requires"] = self.pyVersionEdit.text() - + findOptions = {} src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text()) excludePatterns = [] for row in range(self.excludePatternList.count()): - excludePatterns.append( - self.excludePatternList.item(row).text()) + excludePatterns.append(self.excludePatternList.item(row).text()) if src: options["package_dir"] = SetupCfgUtilities.toString({"": src}) findOptions["where"] = src if excludePatterns: findOptions["exclude"] = SetupCfgUtilities.toString(excludePatterns) - + if self.includePackageDataCheckBox.isChecked(): options["include_package_data"] = SetupCfgUtilities.toString(True) - packageData = {} # placeholder section + packageData = {} # placeholder section else: packageData = None - + modules = [] for row in range(self.modulesList.count()): modules.append(self.modulesList.item(row).text()) if modules: options["py_modules"] = SetupCfgUtilities.toString(modules) - + if self.entryPointsList.topLevelItemCount(): entryPoints = { "console_scripts": {}, @@ -554,16 +587,18 @@ for row in range(self.entryPointsList.topLevelItemCount()): itm = self.entryPointsList.topLevelItem(row) entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)][ - itm.text(1)] = itm.text(2) + itm.text(1) + ] = itm.text(2) for epType in list(entryPoints.keys()): if entryPoints[epType]: entryPoints[epType] = SetupCfgUtilities.toString( - entryPoints[epType]) + entryPoints[epType] + ) else: del entryPoints[epType] else: entryPoints = {} - + configDict = { "metadata": metadata, "options": options, @@ -573,46 +608,46 @@ configDict["options.package_data"] = packageData if entryPoints: configDict["options.entry_points"] = entryPoints - + cparser = configparser.ConfigParser() cparser.read_dict(configDict) sio = io.StringIO() cparser.write(sio) sourceCode = sio.getvalue() return sourceCode - + def __getPyprojectCode(self): """ Private method to get the source code for a 'pyproject.toml' file. - + @return generated code @rtype str """ doc = tomlkit.document() - + buildSystem = tomlkit.table() buildSystem["requires"] = ["setuptools>=61.0.0", "wheel"] buildSystem["build-backend"] = "setuptools.build_meta" doc["build-system"] = buildSystem - + project = tomlkit.table() project["name"] = self.nameEdit.text() project["version"] = self.versionEdit.text() - + if self.summaryEdit.text(): project["description"] = self.summaryEdit.text() - + if self.descriptionEdit.toPlainText(): if self.descriptionFromFilesCheckBox.isChecked(): project["readme"] = self.descriptionEdit.toPlainText().splitlines()[0] else: readme = tomlkit.table() readme["text"] = self.descriptionEdit.toPlainText() - readme["content-type"] = ( - self.descriptionContentTypeComboBox.currentData() - ) + readme[ + "content-type" + ] = self.descriptionContentTypeComboBox.currentData() project["readme"] = readme - + if self.authorEdit.text(): authors = tomlkit.array() author = tomlkit.inline_table() @@ -620,7 +655,7 @@ author["email"] = self.authorEmailEdit.text() authors.append(author) project["authors"] = authors - + if self.maintainerEdit.text(): maintainers = tomlkit.array() maintainer = tomlkit.inline_table() @@ -628,18 +663,18 @@ maintainer["email"] = self.maintainerEmailEdit.text() maintainers.append(maintainer) project["maintainers"] = maintainers - + urls = tomlkit.table() urls["Homepage"] = self.homePageUrlEdit.text() if self.downloadUrlEdit.text(): urls["Download"] = self.downloadUrlEdit.text() - + if self.projectUrlsList.topLevelItemCount(): for row in range(self.projectUrlsList.topLevelItemCount()): urlItem = self.projectUrlsList.topLevelItem(row) urls[urlItem.text(0)] = urlItem.text(1) project["urls"] = urls - + classifiers = [] if not self.licenseClassifierCheckBox.isChecked(): licenseTbl = tomlkit.table() @@ -648,18 +683,20 @@ else: classifiers.append( self.licenseClassifierComboBox.itemData( - self.licenseClassifierComboBox.currentIndex())) - + self.licenseClassifierComboBox.currentIndex() + ) + ) + if self.developmentStatusComboBox.currentIndex() != 0: classifiers.append(self.developmentStatusComboBox.currentData()) - + itm = self.classifiersList.topLevelItem(0) while itm: itm.setExpanded(True) if itm.checkState(0) == Qt.CheckState.Checked: classifiers.append(itm.data(0, Qt.ItemDataRole.UserRole)) itm = self.classifiersList.itemBelow(itm) - + # cleanup classifiers list - remove all invalid entries classifiers = [c for c in classifiers if bool(c)] if classifiers: @@ -668,17 +705,17 @@ classifiersArray.add_line(classifier) classifiersArray.append(tomlkit.nl()) project["classifiers"] = classifiersArray - + if self.keywordsEdit.text(): keywords = tomlkit.array() for kw in self.keywordsEdit.text().split(): keywords.add_line(kw) keywords.append(tomlkit.nl()) project["keywords"] = keywords - + if self.pyVersionEdit.text(): project["requires-python"] = self.pyVersionEdit.text() - + if self.entryPointsList.topLevelItemCount(): entryPoints = { "console_scripts": {}, @@ -687,31 +724,32 @@ for row in range(self.entryPointsList.topLevelItemCount()): itm = self.entryPointsList.topLevelItem(row) entryPoints[itm.data(0, Qt.ItemDataRole.UserRole)][ - itm.text(1)] = itm.text(2) - + itm.text(1) + ] = itm.text(2) + if entryPoints["console_scripts"]: scripts = tomlkit.table() for name, function in entryPoints["console_scripts"].items(): scripts[name] = function project["scripts"] = scripts - + if entryPoints["gui_scripts"]: guiScripts = tomlkit.table() for name, function in entryPoints["gui_scripts"].items(): guiScripts[name] = function project["gui-scripts"] = guiScripts - + # placeholder dependencies = tomlkit.array() - dependencies.append(tomlkit.comment( - "TODO: enter project dependencies " # __NO-TASK__ - )) + dependencies.append( + tomlkit.comment("TODO: enter project dependencies ") # __NO-TASK__ + ) project["dependencies"] = dependencies - + doc["project"] = project - + setuptools = tomlkit.table() - + platforms = self.platformsEdit.toPlainText().splitlines() if platforms: platformsArray = tomlkit.array() @@ -719,28 +757,27 @@ platformsArray.add_line(plt) platformsArray.append(tomlkit.nl()) setuptools["platforms"] = platformsArray - + setuptools["include-package-data"] = self.includePackageDataCheckBox.isChecked() if self.includePackageDataCheckBox.isChecked(): # placeholder setuptools["package-data"] = tomlkit.table() - setuptools["package-data"].add(tomlkit.comment( - "TODO: enter package data patterns" # __NO-TASK__ - )) - + setuptools["package-data"].add( + tomlkit.comment("TODO: enter package data patterns") # __NO-TASK__ + ) + if self.modulesList.count(): modulesArray = tomlkit.array() for row in range(self.modulesList.count()): modulesArray.add_line(self.modulesList.item(row).text()) modulesArray.append(tomlkit.nl()) setuptools["py-modules"] = modulesArray - + findspec = tomlkit.table() src = Utilities.fromNativeSeparators(self.sourceDirectoryPicker.text()) excludePatterns = [] for row in range(self.excludePatternList.count()): - excludePatterns.append( - self.excludePatternList.item(row).text()) + excludePatterns.append(self.excludePatternList.item(row).text()) if src: findspec["where"] = [ericApp().getObject("Project").getRelativePath(src)] if excludePatterns: @@ -749,17 +786,17 @@ excludePatternsArray.add_line(pattern) excludePatternsArray.append(tomlkit.nl()) findspec["exclude"] = excludePatternsArray - + if bool(findspec): setuptools["packages"] = tomlkit.table(is_super_table=True) setuptools["packages"]["find"] = findspec - + doc["tool"] = tomlkit.table(is_super_table=True) doc["tool"]["setuptools"] = setuptools - + sourceCode = tomlkit.dumps(doc) return sourceCode - + @pyqtSlot() def accept(self): """ @@ -768,11 +805,11 @@ line, index = self.__editor.getCursorPosition() indLevel = self.__editor.indentation(line) // self.__editor.indentationWidth() indString = ( - '\t' - if self.__editor.indentationsUseTabs() else - self.__editor.indentationWidth() * ' ' + "\t" + if self.__editor.indentationsUseTabs() + else self.__editor.indentationWidth() * " " ) - + if self.__category == "setup.py": sourceCode = self.__getSetupPyCode(indLevel, indString) elif self.__category == "setup.cfg": @@ -782,16 +819,16 @@ else: # should not happen, but play it safe sourceCode = "" - + if sourceCode: line, index = self.__editor.getCursorPosition() # It should be done this way to allow undo self.__editor.beginUndoAction() self.__editor.insertAt(sourceCode, line, index) self.__editor.endUndoAction() - + super().accept() - + @pyqtSlot() def on_projectButton_clicked(self): """ @@ -799,7 +836,7 @@ current project. """ project = ericApp().getObject("Project") - + self.nameEdit.setText(project.getProjectName()) try: self.versionEdit.setText(project.getProjectVersion()) @@ -811,29 +848,25 @@ self.authorEdit.setText(project.pdata["AUTHOR"][0]) self.authorEmailEdit.setText(project.pdata["EMAIL"][0]) description = project.pdata["DESCRIPTION"][0] - - summary = ( - description.split(".", 1)[0].replace("\r", "").replace("\n", "") + - "." - ) + + summary = description.split(".", 1)[0].replace("\r", "").replace("\n", "") + "." self.summaryEdit.setText(summary) self.descriptionEdit.setPlainText(description) - + self.packageRootPicker.setText(project.getProjectPath()) - + # prevent overwriting of entries by disabling the button self.projectButton.setEnabled(False) - + def __getStartDir(self): """ Private method to get the start directory for selection dialogs. - + @return start directory @rtype str """ - return (Preferences.getMultiProject("Workspace") or - Utilities.getHomeDir()) - + return Preferences.getMultiProject("Workspace") or Utilities.getHomeDir() + @pyqtSlot() def on_entryPointsList_itemSelectionChanged(self): """ @@ -841,10 +874,12 @@ entry points list. """ self.deleteEntryPointButton.setEnabled( - bool(self.entryPointsList.selectedItems())) + bool(self.entryPointsList.selectedItems()) + ) self.editEntryPointButton.setEnabled( - len(self.entryPointsList.selectedItems()) == 1) - + len(self.entryPointsList.selectedItems()) == 1 + ) + @pyqtSlot() def on_deleteEntryPointButton_clicked(self): """ @@ -853,54 +888,50 @@ for itm in self.entryPointsList.selectedItems(): self.entryPointsList.takeTopLevelItem(self.entryPointsList.row(itm)) del itm - + @pyqtSlot() def on_addEntryPointButton_clicked(self): """ Private slot to add an entry point to the list. """ project = ericApp().getObject("Project") - rootDir = ( - project.getProjectPath() - if project.isOpen() else - "" - ) + rootDir = project.getProjectPath() if project.isOpen() else "" dlg = AddEntryPointDialog(rootDir, parent=self) if dlg.exec() == QDialog.DialogCode.Accepted: epType, epCategory, name, script = dlg.getEntryPoint() itm = QTreeWidgetItem(self.entryPointsList, [epType, name, script]) itm.setData(0, Qt.ItemDataRole.UserRole, epCategory) - + @pyqtSlot() def on_editEntryPointButton_clicked(self): """ Private slot to edit the selected entry point. """ project = ericApp().getObject("Project") - rootDir = ( - project.getProjectPath() - if project.isOpen() else - "" + rootDir = project.getProjectPath() if project.isOpen() else "" + itm = self.entryPointsList.selectedItems()[0] + dlg = AddEntryPointDialog( + rootDir, + epType=itm.text(0), + name=itm.text(1), + script=itm.text(2), + parent=self, ) - itm = self.entryPointsList.selectedItems()[0] - dlg = AddEntryPointDialog(rootDir, epType=itm.text(0), name=itm.text(1), - script=itm.text(2), parent=self) if dlg.exec() == QDialog.DialogCode.Accepted: epType, epCategory, name, script = dlg.getEntryPoint() itm.setText(0, epType) itm.setText(1, name) itm.setText(2, script) itm.setData(0, Qt.ItemDataRole.UserRole, epCategory) - + @pyqtSlot() def on_modulesList_itemSelectionChanged(self): """ Private slot to handle a change of selected items of the modules list. """ - self.deleteModuleButton.setEnabled( - bool(self.modulesList.selectedItems())) - + self.deleteModuleButton.setEnabled(bool(self.modulesList.selectedItems())) + @pyqtSlot() def on_deleteModuleButton_clicked(self): """ @@ -909,7 +940,7 @@ for itm in self.modulesList.selectedItems(): self.modulesList.takeItem(self.modulesList.row(itm)) del itm - + @pyqtSlot() def on_addModuleButton_clicked(self): """ @@ -920,10 +951,10 @@ self, self.tr("Add Python Modules"), startDir, - self.tr("Python Files (*.py)")) + self.tr("Python Files (*.py)"), + ) for module in modulesList: - module = module.replace( - Utilities.toNativeSeparators(startDir), "") + module = module.replace(Utilities.toNativeSeparators(startDir), "") if module.startswith(("\\", "/")): module = module[1:] if module: @@ -931,9 +962,9 @@ str(pathlib.Path(module).with_suffix("")) .replace("\\", ".") .replace("/", "."), - self.modulesList + self.modulesList, ) - + @pyqtSlot() def on_excludePatternList_itemSelectionChanged(self): """ @@ -941,42 +972,39 @@ exclude pattern list. """ self.deleteExcludePatternButton.setEnabled( - bool(self.excludePatternList.selectedItems())) - + bool(self.excludePatternList.selectedItems()) + ) + @pyqtSlot() def on_deleteExcludePatternButton_clicked(self): """ Private slot to delete the selected exclude pattern items. """ for itm in self.excludePatternList.selectedItems(): - self.excludePatternList.takeItem( - self.excludePatternList.row(itm)) + self.excludePatternList.takeItem(self.excludePatternList.row(itm)) del itm - + @pyqtSlot() def on_addExludePatternButton_clicked(self): """ Private slot to add an exclude pattern to the list. """ - pattern = ( - self.excludePatternEdit.text().replace("\\", ".").replace("/", ".") - ) + pattern = self.excludePatternEdit.text().replace("\\", ".").replace("/", ".") if not self.excludePatternList.findItems( - pattern, - Qt.MatchFlag.MatchExactly | Qt.MatchFlag.MatchCaseSensitive + pattern, Qt.MatchFlag.MatchExactly | Qt.MatchFlag.MatchCaseSensitive ): QListWidgetItem(pattern, self.excludePatternList) - + @pyqtSlot(str) def on_excludePatternEdit_textChanged(self, txt): """ Private slot to handle a change of the exclude pattern text. - + @param txt text of the line edit @type str """ self.addExludePatternButton.setEnabled(bool(txt)) - + @pyqtSlot() def on_excludePatternEdit_returnPressed(self): """ @@ -984,7 +1012,7 @@ exclude pattern edit. """ self.on_addExludePatternButton_clicked() - + @pyqtSlot() def on_urlDeleteButton_clicked(self): """ @@ -993,7 +1021,7 @@ for itm in self.projectUrlsList.selectedItems(): self.projectUrlsList.takeTopLevelItem(self.projectUrlsList.row(itm)) del itm - + @pyqtSlot() def on_urlAddButton_clicked(self): """ @@ -1003,7 +1031,7 @@ if dlg.exec() == QDialog.DialogCode.Accepted: name, url = dlg.getUrl() QTreeWidgetItem(self.projectUrlsList, [name, url]) - + @pyqtSlot() def on_urlEditButton_clicked(self): """ @@ -1015,7 +1043,7 @@ name, url = dlg.getUrl() itm.setText(0, name) itm.setText(1, url) - + @pyqtSlot() def on_projectUrlsList_itemSelectionChanged(self): """