diff --git a/src/Mod/AddonManager/AddonManagerOptions.py b/src/Mod/AddonManager/AddonManagerOptions.py index 909a46dc1c..4b1d7e2300 100644 --- a/src/Mod/AddonManager/AddonManagerOptions.py +++ b/src/Mod/AddonManager/AddonManagerOptions.py @@ -63,9 +63,7 @@ class AddonManagerOptions: QIcon.fromTheme("remove", QIcon(":/icons/list-remove.svg")) ) - self.form.customRepositoriesTableView.horizontalHeader().setStretchLastSection( - False - ) + self.form.customRepositoriesTableView.horizontalHeader().setStretchLastSection(False) self.form.customRepositoriesTableView.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch ) @@ -73,15 +71,9 @@ class AddonManagerOptions: 1, QHeaderView.ResizeToContents ) - self.form.addCustomRepositoryButton.clicked.connect( - self._add_custom_repo_clicked - ) - self.form.removeCustomRepositoryButton.clicked.connect( - self._remove_custom_repo_clicked - ) - self.form.customRepositoriesTableView.doubleClicked.connect( - self._row_double_clicked - ) + self.form.addCustomRepositoryButton.clicked.connect(self._add_custom_repo_clicked) + self.form.removeCustomRepositoryButton.clicked.connect(self._remove_custom_repo_clicked) + self.form.customRepositoriesTableView.doubleClicked.connect(self._row_double_clicked) def saveSettings(self): """Required function: called by the preferences dialog when Apply or Save is clicked, @@ -99,9 +91,7 @@ class AddonManagerOptions: if pref_path and pref_entry: pref_path = pref_path.data() pref_entry = pref_entry.data() - pref_access_string = ( - f"User parameter:BaseApp/Preferences/{str(pref_path,'utf-8')}" - ) + pref_access_string = f"User parameter:BaseApp/Preferences/{str(pref_path,'utf-8')}" pref = FreeCAD.ParamGet(pref_access_string) if isinstance(widget, QCheckBox): checked = widget.isChecked() @@ -143,9 +133,7 @@ class AddonManagerOptions: if pref_path and pref_entry: pref_path = pref_path.data() pref_entry = pref_entry.data() - pref_access_string = ( - f"User parameter:BaseApp/Preferences/{str(pref_path,'utf-8')}" - ) + pref_access_string = f"User parameter:BaseApp/Preferences/{str(pref_path,'utf-8')}" pref = FreeCAD.ParamGet(pref_access_string) if isinstance(widget, QCheckBox): widget.setChecked(pref.GetBool(str(pref_entry, "utf-8"))) @@ -313,9 +301,7 @@ class CustomRepositoryDialog: def __init__(self): self.dialog = FreeCADGui.PySideUic.loadUi( - os.path.join( - os.path.dirname(__file__), "AddonManagerOptions_AddCustomRepository.ui" - ) + os.path.join(os.path.dirname(__file__), "AddonManagerOptions_AddCustomRepository.ui") ) def exec(self): diff --git a/src/Mod/AddonManager/AddonManagerTest/app/mocks.py b/src/Mod/AddonManager/AddonManagerTest/app/mocks.py index 470a2393b4..695e6e0b56 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/mocks.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/mocks.py @@ -148,9 +148,7 @@ class MockMacro: with open(os.path.join(location, self.icon), "wb") as f: f.write(b"Fake icon data - nothing to see here\n") if self.xpm: - with open( - os.path.join(location, "MockMacro_icon.xpm"), "w", encoding="utf-8" - ) as f: + with open(os.path.join(location, "MockMacro_icon.xpm"), "w", encoding="utf-8") as f: f.write(self.xpm) for name in self.other_files: if "/" in name: @@ -233,12 +231,8 @@ class MockGitManager: self.current_branch_response = "main" self.get_remote_response = "No remote set" self.get_branches_response = ["main"] - self.get_last_committers_response = { - "John Doe": {"email": "jdoe@freecad.org", "count": 1} - } - self.get_last_authors_response = { - "Jane Doe": {"email": "jdoe@freecad.org", "count": 1} - } + self.get_last_committers_response = {"John Doe": {"email": "jdoe@freecad.org", "count": 1}} + self.get_last_authors_response = {"Jane Doe": {"email": "jdoe@freecad.org", "count": 1}} self.should_fail = False self.fail_once = False # Switch back to success after the simulated failure @@ -252,9 +246,7 @@ class MockGitManager: self.called_methods.append("clone") self._check_for_failure() - def async_clone( - self, _remote, _local_path, _progress_monitor, _args: List[str] = None - ): + def async_clone(self, _remote, _local_path, _progress_monitor, _args: List[str] = None): self.called_methods.append("async_clone") self._check_for_failure() diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_addon.py b/src/Mod/AddonManager/AddonManagerTest/app/test_addon.py index 9f30521637..5f7c06c621 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/test_addon.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_addon.py @@ -89,9 +89,7 @@ class TestAddon(unittest.TestCase): Addon.Status.NOT_INSTALLED, "master", ) - addon_with_workbench.load_metadata_file( - os.path.join(self.test_dir, "workbench_only.xml") - ) + addon_with_workbench.load_metadata_file(os.path.join(self.test_dir, "workbench_only.xml")) self.assertTrue(addon_with_workbench.contains_workbench()) self.assertFalse(addon_with_workbench.contains_macro()) self.assertFalse(addon_with_workbench.contains_preference_pack()) @@ -103,9 +101,7 @@ class TestAddon(unittest.TestCase): Addon.Status.NOT_INSTALLED, "master", ) - addon_with_macro.load_metadata_file( - os.path.join(self.test_dir, "macro_only.xml") - ) + addon_with_macro.load_metadata_file(os.path.join(self.test_dir, "macro_only.xml")) self.assertFalse(addon_with_macro.contains_workbench()) self.assertTrue(addon_with_macro.contains_macro()) self.assertFalse(addon_with_macro.contains_preference_pack()) @@ -117,9 +113,7 @@ class TestAddon(unittest.TestCase): Addon.Status.NOT_INSTALLED, "master", ) - addon_with_prefpack.load_metadata_file( - os.path.join(self.test_dir, "prefpack_only.xml") - ) + addon_with_prefpack.load_metadata_file(os.path.join(self.test_dir, "prefpack_only.xml")) self.assertFalse(addon_with_prefpack.contains_workbench()) self.assertFalse(addon_with_prefpack.contains_macro()) self.assertTrue(addon_with_prefpack.contains_preference_pack()) @@ -131,9 +125,7 @@ class TestAddon(unittest.TestCase): Addon.Status.NOT_INSTALLED, "master", ) - addon_with_all.load_metadata_file( - os.path.join(self.test_dir, "combination.xml") - ) + addon_with_all.load_metadata_file(os.path.join(self.test_dir, "combination.xml")) self.assertTrue(addon_with_all.contains_workbench()) self.assertTrue(addon_with_all.contains_macro()) self.assertTrue(addon_with_all.contains_preference_pack()) @@ -263,9 +255,7 @@ class TestAddon(unittest.TestCase): Addon.Status.NOT_INSTALLED, "master", ) - addon.load_metadata_file( - os.path.join(self.test_dir, "depends_on_all_workbenches.xml") - ) + addon.load_metadata_file(os.path.join(self.test_dir, "depends_on_all_workbenches.xml")) deps = Addon.Dependencies() addon.walk_dependency_tree({}, deps) self.assertEqual(len(deps.internal_workbenches), len(INTERNAL_WORKBENCHES)) @@ -277,9 +267,7 @@ class TestAddon(unittest.TestCase): Addon.Status.NOT_INSTALLED, "master", ) - addon.load_metadata_file( - os.path.join(self.test_dir, "test_version_detection.xml") - ) + addon.load_metadata_file(os.path.join(self.test_dir, "test_version_detection.xml")) self.assertEqual( len(addon.tags), diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_dependency_installer.py b/src/Mod/AddonManager/AddonManagerTest/app/test_dependency_installer.py index 098409acbb..e0ba09cad1 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/test_dependency_installer.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_dependency_installer.py @@ -74,19 +74,11 @@ class TestDependencyInstaller(unittest.TestCase): def setUp(self): self.subprocess_mock = SubprocessMock() - self.test_object = DependencyInstaller( - [], ["required_py_package"], ["optional_py_package"] - ) - self.test_object._subprocess_wrapper = ( - self.subprocess_mock.subprocess_interceptor - ) + self.test_object = DependencyInstaller([], ["required_py_package"], ["optional_py_package"]) + self.test_object._subprocess_wrapper = self.subprocess_mock.subprocess_interceptor self.signals_caught = [] - self.test_object.failure.connect( - functools.partial(self.catch_signal, "failure") - ) - self.test_object.finished.connect( - functools.partial(self.catch_signal, "finished") - ) + self.test_object.failure.connect(functools.partial(self.catch_signal, "failure")) + self.test_object.finished.connect(functools.partial(self.catch_signal, "finished")) self.test_object.no_pip.connect(functools.partial(self.catch_signal, "no_pip")) self.test_object.no_python_exe.connect( functools.partial(self.catch_signal, "no_python_exe") diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_freecad_interface.py b/src/Mod/AddonManager/AddonManagerTest/app/test_freecad_interface.py index 123bb3c80d..07da9f5301 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/test_freecad_interface.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_freecad_interface.py @@ -64,9 +64,7 @@ class TestConsole(unittest.TestCase): """Test that if the FreeCAD import fails, the logger is set up correctly, and implements PrintLog""" sys.modules["FreeCAD"] = None - with patch( - "addonmanager_freecad_interface.logging", new=MagicMock() - ) as mock_logging: + with patch("addonmanager_freecad_interface.logging", new=MagicMock()) as mock_logging: import addonmanager_freecad_interface as fc fc.Console.PrintLog("Test output") @@ -76,9 +74,7 @@ class TestConsole(unittest.TestCase): def test_message_no_freecad(self): """Test that if the FreeCAD import fails the logger implements PrintMessage""" sys.modules["FreeCAD"] = None - with patch( - "addonmanager_freecad_interface.logging", new=MagicMock() - ) as mock_logging: + with patch("addonmanager_freecad_interface.logging", new=MagicMock()) as mock_logging: import addonmanager_freecad_interface as fc fc.Console.PrintMessage("Test output") @@ -87,9 +83,7 @@ class TestConsole(unittest.TestCase): def test_warning_no_freecad(self): """Test that if the FreeCAD import fails the logger implements PrintWarning""" sys.modules["FreeCAD"] = None - with patch( - "addonmanager_freecad_interface.logging", new=MagicMock() - ) as mock_logging: + with patch("addonmanager_freecad_interface.logging", new=MagicMock()) as mock_logging: import addonmanager_freecad_interface as fc fc.Console.PrintWarning("Test output") @@ -98,9 +92,7 @@ class TestConsole(unittest.TestCase): def test_error_no_freecad(self): """Test that if the FreeCAD import fails the logger implements PrintError""" sys.modules["FreeCAD"] = None - with patch( - "addonmanager_freecad_interface.logging", new=MagicMock() - ) as mock_logging: + with patch("addonmanager_freecad_interface.logging", new=MagicMock()) as mock_logging: import addonmanager_freecad_interface as fc fc.Console.PrintError("Test output") diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_git.py b/src/Mod/AddonManager/AddonManagerTest/app/test_git.py index 5117747cdf..c7625ea447 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/test_git.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_git.py @@ -78,9 +78,7 @@ class TestGit(unittest.TestCase): checkout_dir = self._clone_test_repo() self.assertTrue(os.path.exists(checkout_dir)) self.assertTrue(os.path.exists(os.path.join(checkout_dir, ".git"))) - self.assertEqual( - os.getcwd(), self.cwd, "We should be left in the same CWD we started" - ) + self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started") def test_checkout(self): """Test git checkout""" @@ -91,9 +89,7 @@ class TestGit(unittest.TestCase): expected_status = "## HEAD (no branch)" self.assertEqual(status, expected_status) - self.assertEqual( - os.getcwd(), self.cwd, "We should be left in the same CWD we started" - ) + self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started") def test_update(self): """Test using git to update the local repo""" @@ -103,9 +99,7 @@ class TestGit(unittest.TestCase): self.assertTrue(self.git.update_available(checkout_dir)) self.git.update(checkout_dir) self.assertFalse(self.git.update_available(checkout_dir)) - self.assertEqual( - os.getcwd(), self.cwd, "We should be left in the same CWD we started" - ) + self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started") def test_tag_and_branch(self): """Test checking the currently checked-out tag""" @@ -129,9 +123,7 @@ class TestGit(unittest.TestCase): self.assertEqual(found_branch, expected_branch) self.assertFalse(self.git.update_available(checkout_dir)) - self.assertEqual( - os.getcwd(), self.cwd, "We should be left in the same CWD we started" - ) + self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started") def test_get_remote(self): """Test getting the remote location""" @@ -139,9 +131,7 @@ class TestGit(unittest.TestCase): expected_remote = self.test_repo_remote returned_remote = self.git.get_remote(checkout_dir) self.assertEqual(expected_remote, returned_remote) - self.assertEqual( - os.getcwd(), self.cwd, "We should be left in the same CWD we started" - ) + self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started") def test_repair(self): """Test the repair feature (and some exception throwing)""" @@ -158,9 +148,7 @@ class TestGit(unittest.TestCase): self.git.repair(remote, checkout_dir) status = self.git.status(checkout_dir) self.assertEqual(status, "## main...origin/main\n") - self.assertEqual( - os.getcwd(), self.cwd, "We should be left in the same CWD we started" - ) + self.assertEqual(os.getcwd(), self.cwd, "We should be left in the same CWD we started") def _rmdir(self, path): try: diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_installer.py b/src/Mod/AddonManager/AddonManagerTest/app/test_installer.py index 1c13c13f8e..0229f05186 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/test_installer.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_installer.py @@ -116,9 +116,7 @@ class TestAddonInstaller(unittest.TestCase): os.path.join(self.test_data_dir, "good_package.xml"), os.path.join(addon_dir, "package.xml"), ) - good_metadata = MetadataReader.from_file( - os.path.join(addon_dir, "package.xml") - ) + good_metadata = MetadataReader.from_file(os.path.join(addon_dir, "package.xml")) installer._update_metadata() self.assertEqual(self.real_addon.installed_version, good_metadata.version) @@ -133,34 +131,24 @@ class TestAddonInstaller(unittest.TestCase): installer.installation_path = temp_dir installer._finalize_zip_installation(test_simple_repo) expected_location = os.path.join(temp_dir, non_gh_mock.name, "README") - self.assertTrue( - os.path.isfile(expected_location), "Non-GitHub zip extraction failed" - ) + self.assertTrue(os.path.isfile(expected_location), "Non-GitHub zip extraction failed") def test_finalize_zip_installation_github(self): with tempfile.TemporaryDirectory() as temp_dir: - test_github_style_repo = os.path.join( - self.test_data_dir, "test_github_style_repo.zip" - ) + test_github_style_repo = os.path.join(self.test_data_dir, "test_github_style_repo.zip") self.mock_addon.url = test_github_style_repo self.mock_addon.branch = "master" installer = AddonInstaller(self.mock_addon, []) installer.installation_path = temp_dir installer._finalize_zip_installation(test_github_style_repo) expected_location = os.path.join(temp_dir, self.mock_addon.name, "README") - self.assertTrue( - os.path.isfile(expected_location), "GitHub zip extraction failed" - ) + self.assertTrue(os.path.isfile(expected_location), "GitHub zip extraction failed") def test_code_in_branch_subdirectory_true(self): """When there is a subdirectory with the branch name in it, find it""" installer = AddonInstaller(self.mock_addon, []) with tempfile.TemporaryDirectory() as temp_dir: - os.mkdir( - os.path.join( - temp_dir, f"{self.mock_addon.name}-{self.mock_addon.branch}" - ) - ) + os.mkdir(os.path.join(temp_dir, f"{self.mock_addon.name}-{self.mock_addon.branch}")) result = installer._code_in_branch_subdirectory(temp_dir) self.assertTrue(result, "Failed to find ZIP subdirectory") @@ -176,30 +164,20 @@ class TestAddonInstaller(unittest.TestCase): """When there are multiple subdirectories, never find a branch subdirectory""" installer = AddonInstaller(self.mock_addon, []) with tempfile.TemporaryDirectory() as temp_dir: - os.mkdir( - os.path.join( - temp_dir, f"{self.mock_addon.name}-{self.mock_addon.branch}" - ) - ) + os.mkdir(os.path.join(temp_dir, f"{self.mock_addon.name}-{self.mock_addon.branch}")) os.mkdir(os.path.join(temp_dir, "AnotherSubdir")) result = installer._code_in_branch_subdirectory(temp_dir) - self.assertFalse( - result, "Found ZIP subdirectory when there were multiple subdirs" - ) + self.assertFalse(result, "Found ZIP subdirectory when there were multiple subdirs") def test_move_code_out_of_subdirectory(self): """All files are moved out and the subdirectory is deleted""" installer = AddonInstaller(self.mock_addon, []) with tempfile.TemporaryDirectory() as temp_dir: - subdir = os.path.join( - temp_dir, f"{self.mock_addon.name}-{self.mock_addon.branch}" - ) + subdir = os.path.join(temp_dir, f"{self.mock_addon.name}-{self.mock_addon.branch}") os.mkdir(subdir) with open(os.path.join(subdir, "README.txt"), "w", encoding="utf-8") as f: f.write("# Test file for unit testing") - with open( - os.path.join(subdir, "AnotherFile.txt"), "w", encoding="utf-8" - ) as f: + with open(os.path.join(subdir, "AnotherFile.txt"), "w", encoding="utf-8") as f: f.write("# Test file for unit testing") installer._move_code_out_of_subdirectory(temp_dir) self.assertTrue(os.path.isfile(os.path.join(temp_dir, "README.txt"))) @@ -260,23 +238,15 @@ class TestAddonInstaller(unittest.TestCase): with tempfile.TemporaryDirectory() as temp_dir: installer = AddonInstaller(self.mock_addon, []) - method = installer._determine_install_method( - temp_dir, InstallationMethod.COPY - ) + method = installer._determine_install_method(temp_dir, InstallationMethod.COPY) self.assertEqual(method, InstallationMethod.COPY) git_manager = initialize_git() if git_manager: - method = installer._determine_install_method( - temp_dir, InstallationMethod.GIT - ) + method = installer._determine_install_method(temp_dir, InstallationMethod.GIT) self.assertEqual(method, InstallationMethod.GIT) - method = installer._determine_install_method( - temp_dir, InstallationMethod.ZIP - ) + method = installer._determine_install_method(temp_dir, InstallationMethod.ZIP) self.assertIsNone(method) - method = installer._determine_install_method( - temp_dir, InstallationMethod.ANY - ) + method = installer._determine_install_method(temp_dir, InstallationMethod.ANY) self.assertEqual(method, InstallationMethod.COPY) def test_determine_install_method_file_url(self): @@ -285,23 +255,15 @@ class TestAddonInstaller(unittest.TestCase): with tempfile.TemporaryDirectory() as temp_dir: installer = AddonInstaller(self.mock_addon, []) temp_dir = "file://" + temp_dir.replace(os.path.sep, "/") - method = installer._determine_install_method( - temp_dir, InstallationMethod.COPY - ) + method = installer._determine_install_method(temp_dir, InstallationMethod.COPY) self.assertEqual(method, InstallationMethod.COPY) git_manager = initialize_git() if git_manager: - method = installer._determine_install_method( - temp_dir, InstallationMethod.GIT - ) + method = installer._determine_install_method(temp_dir, InstallationMethod.GIT) self.assertEqual(method, InstallationMethod.GIT) - method = installer._determine_install_method( - temp_dir, InstallationMethod.ZIP - ) + method = installer._determine_install_method(temp_dir, InstallationMethod.ZIP) self.assertIsNone(method) - method = installer._determine_install_method( - temp_dir, InstallationMethod.ANY - ) + method = installer._determine_install_method(temp_dir, InstallationMethod.ANY) self.assertEqual(method, InstallationMethod.COPY) def test_determine_install_method_local_zip(self): @@ -310,21 +272,13 @@ class TestAddonInstaller(unittest.TestCase): with tempfile.TemporaryDirectory() as temp_dir: installer = AddonInstaller(self.mock_addon, []) temp_file = os.path.join(temp_dir, "dummy.zip") - method = installer._determine_install_method( - temp_file, InstallationMethod.COPY - ) + method = installer._determine_install_method(temp_file, InstallationMethod.COPY) self.assertEqual(method, InstallationMethod.ZIP) - method = installer._determine_install_method( - temp_file, InstallationMethod.GIT - ) + method = installer._determine_install_method(temp_file, InstallationMethod.GIT) self.assertIsNone(method) - method = installer._determine_install_method( - temp_file, InstallationMethod.ZIP - ) + method = installer._determine_install_method(temp_file, InstallationMethod.ZIP) self.assertEqual(method, InstallationMethod.ZIP) - method = installer._determine_install_method( - temp_file, InstallationMethod.ANY - ) + method = installer._determine_install_method(temp_file, InstallationMethod.ANY) self.assertEqual(method, InstallationMethod.ZIP) def test_determine_install_method_remote_zip(self): @@ -351,12 +305,8 @@ class TestAddonInstaller(unittest.TestCase): for site in ["github.org", "gitlab.org", "framagit.org", "salsa.debian.org"]: with self.subTest(site=site): - temp_file = ( - f"https://{site}/dummy/dummy" # Doesn't have to actually exist! - ) - method = installer._determine_install_method( - temp_file, InstallationMethod.COPY - ) + temp_file = f"https://{site}/dummy/dummy" # Doesn't have to actually exist! + method = installer._determine_install_method(temp_file, InstallationMethod.COPY) self.assertIsNone(method, f"Allowed copying from {site} URL") def test_determine_install_method_https_known_sites_git(self): @@ -367,12 +317,8 @@ class TestAddonInstaller(unittest.TestCase): for site in ["github.org", "gitlab.org", "framagit.org", "salsa.debian.org"]: with self.subTest(site=site): - temp_file = ( - f"https://{site}/dummy/dummy" # Doesn't have to actually exist! - ) - method = installer._determine_install_method( - temp_file, InstallationMethod.GIT - ) + temp_file = f"https://{site}/dummy/dummy" # Doesn't have to actually exist! + method = installer._determine_install_method(temp_file, InstallationMethod.GIT) self.assertEqual( method, InstallationMethod.GIT, @@ -387,12 +333,8 @@ class TestAddonInstaller(unittest.TestCase): for site in ["github.org", "gitlab.org", "framagit.org", "salsa.debian.org"]: with self.subTest(site=site): - temp_file = ( - f"https://{site}/dummy/dummy" # Doesn't have to actually exist! - ) - method = installer._determine_install_method( - temp_file, InstallationMethod.ZIP - ) + temp_file = f"https://{site}/dummy/dummy" # Doesn't have to actually exist! + method = installer._determine_install_method(temp_file, InstallationMethod.ZIP) self.assertEqual( method, InstallationMethod.ZIP, @@ -407,12 +349,8 @@ class TestAddonInstaller(unittest.TestCase): for site in ["github.org", "gitlab.org", "framagit.org", "salsa.debian.org"]: with self.subTest(site=site): - temp_file = ( - f"https://{site}/dummy/dummy" # Doesn't have to actually exist! - ) - method = installer._determine_install_method( - temp_file, InstallationMethod.ANY - ) + temp_file = f"https://{site}/dummy/dummy" # Doesn't have to actually exist! + method = installer._determine_install_method(temp_file, InstallationMethod.ANY) self.assertEqual( method, InstallationMethod.GIT, @@ -427,12 +365,8 @@ class TestAddonInstaller(unittest.TestCase): for site in ["github.org", "gitlab.org", "framagit.org", "salsa.debian.org"]: with self.subTest(site=site): - temp_file = ( - f"https://{site}/dummy/dummy" # Doesn't have to actually exist! - ) - method = installer._determine_install_method( - temp_file, InstallationMethod.ANY - ) + temp_file = f"https://{site}/dummy/dummy" # Doesn't have to actually exist! + method = installer._determine_install_method(temp_file, InstallationMethod.ANY) self.assertEqual( method, InstallationMethod.ZIP, @@ -442,9 +376,7 @@ class TestAddonInstaller(unittest.TestCase): def test_fcmacro_copying(self): with tempfile.TemporaryDirectory() as temp_dir: mock_addon = MockAddon() - mock_addon.url = os.path.join( - self.test_data_dir, "test_addon_with_fcmacro.zip" - ) + mock_addon.url = os.path.join(self.test_data_dir, "test_addon_with_fcmacro.zip") installer = AddonInstaller(mock_addon, []) installer.installation_path = temp_dir installer.macro_installation_path = os.path.join(temp_dir, "Macros") @@ -475,6 +407,4 @@ class TestMacroInstaller(unittest.TestCase): installer.installation_path = temp_dir installation_succeeded = installer.run() self.assertTrue(installation_succeeded) - self.assertTrue( - os.path.exists(os.path.join(temp_dir, self.mock.macro.filename)) - ) + self.assertTrue(os.path.exists(os.path.join(temp_dir, self.mock.macro.filename))) diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_macro_parser.py b/src/Mod/AddonManager/AddonManagerTest/app/test_macro_parser.py index 1307a3b556..5e89bc0945 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/test_macro_parser.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_macro_parser.py @@ -100,9 +100,7 @@ class TestMacroParser(unittest.TestCase): catcher = CallCatcher() self.test_object._process_key = catcher.catch_call self.test_object._process_line(read_in_line, content_lines) - self.assertTrue( - catcher.called, "_process_key was not called for a known key" - ) + self.assertTrue(catcher.called, "_process_key was not called for a known key") def test_process_line_unknown_lines(self): """Lines starting with non-keys are not processed""" @@ -123,9 +121,7 @@ class TestMacroParser(unittest.TestCase): catcher = CallCatcher() self.test_object._process_key = catcher.catch_call self.test_object._process_line(read_in_line, content_lines) - self.assertFalse( - catcher.called, "_process_key was called for an unknown key" - ) + self.assertFalse(catcher.called, "_process_key was called for an unknown key") def test_process_key_standard(self): """Normal expected data is processed""" diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_uninstaller.py b/src/Mod/AddonManager/AddonManagerTest/app/test_uninstaller.py index 57b5f95de3..8c82c28421 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/test_uninstaller.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_uninstaller.py @@ -51,15 +51,9 @@ class TestAddonUninstaller(unittest.TestCase): self.signals_caught = [] self.test_object = AddonUninstaller(self.mock_addon) - self.test_object.finished.connect( - functools.partial(self.catch_signal, "finished") - ) - self.test_object.success.connect( - functools.partial(self.catch_signal, "success") - ) - self.test_object.failure.connect( - functools.partial(self.catch_signal, "failure") - ) + self.test_object.finished.connect(functools.partial(self.catch_signal, "finished")) + self.test_object.success.connect(functools.partial(self.catch_signal, "success")) + self.test_object.failure.connect(functools.partial(self.catch_signal, "failure")) def tearDown(self): """Finalize the test.""" @@ -149,9 +143,7 @@ class TestAddonUninstaller(unittest.TestCase): self.assertNotIn("failure", self.signals_caught) self.assertIn("success", self.signals_caught) self.assertIn("finished", self.signals_caught) - self.assertFalse( - os.path.exists(os.path.join(macro_directory, "FakeMacro.FCMacro")) - ) + self.assertFalse(os.path.exists(os.path.join(macro_directory, "FakeMacro.FCMacro"))) self.assertTrue(os.path.exists(macro_directory)) def test_uninstall_calls_script(self): @@ -218,9 +210,7 @@ class TestAddonUninstaller(unittest.TestCase): os.path.join(toplevel_path, "AM_INSTALLATION_DIGEST.txt"), ) self.test_object.remove_extra_files(toplevel_path) # Shouldn't throw - self.assertFalse( - os.path.exists(os.path.join(macro_directory, "FakeMacro.FCMacro")) - ) + self.assertFalse(os.path.exists(os.path.join(macro_directory, "FakeMacro.FCMacro"))) def test_remove_extra_files_normal_case(self): """Test that a digest that is a "normal" case removes the requested files""" @@ -244,35 +234,21 @@ class TestAddonUninstaller(unittest.TestCase): ) # Make sure the setup worked as expected, otherwise the test is meaningless - self.assertTrue( - os.path.exists(os.path.join(macro_directory, "FakeMacro1.FCMacro")) - ) - self.assertTrue( - os.path.exists(os.path.join(macro_directory, "FakeMacro2.FCMacro")) - ) - self.assertTrue( - os.path.exists(os.path.join(macro_directory, "FakeMacro3.FCMacro")) - ) + self.assertTrue(os.path.exists(os.path.join(macro_directory, "FakeMacro1.FCMacro"))) + self.assertTrue(os.path.exists(os.path.join(macro_directory, "FakeMacro2.FCMacro"))) + self.assertTrue(os.path.exists(os.path.join(macro_directory, "FakeMacro3.FCMacro"))) self.test_object.remove_extra_files(toplevel_path) # Shouldn't throw - self.assertFalse( - os.path.exists(os.path.join(macro_directory, "FakeMacro1.FCMacro")) - ) - self.assertFalse( - os.path.exists(os.path.join(macro_directory, "FakeMacro2.FCMacro")) - ) - self.assertFalse( - os.path.exists(os.path.join(macro_directory, "FakeMacro3.FCMacro")) - ) + self.assertFalse(os.path.exists(os.path.join(macro_directory, "FakeMacro1.FCMacro"))) + self.assertFalse(os.path.exists(os.path.join(macro_directory, "FakeMacro2.FCMacro"))) + self.assertFalse(os.path.exists(os.path.join(macro_directory, "FakeMacro3.FCMacro"))) def test_runs_uninstaller_script_successful(self): """Tests that the uninstall.py script is called""" with tempfile.TemporaryDirectory() as temp_dir: toplevel_path = self.setup_dummy_installation(temp_dir) - with open( - os.path.join(toplevel_path, "uninstall.py"), "w", encoding="utf-8" - ) as f: + with open(os.path.join(toplevel_path, "uninstall.py"), "w", encoding="utf-8") as f: double_escaped = temp_dir.replace("\\", "\\\\") f.write( f"""# Mock uninstaller script @@ -282,28 +258,20 @@ with open(os.path.join(path,"RAN_UNINSTALLER.txt"),"w",encoding="utf-8") as f: f.write("File created by uninstall.py from unit tests") """ ) - self.test_object.run_uninstall_script( - toplevel_path - ) # The exception does not leak out - self.assertTrue( - os.path.exists(os.path.join(temp_dir, "RAN_UNINSTALLER.txt")) - ) + self.test_object.run_uninstall_script(toplevel_path) # The exception does not leak out + self.assertTrue(os.path.exists(os.path.join(temp_dir, "RAN_UNINSTALLER.txt"))) def test_runs_uninstaller_script_failure(self): """Tests that exceptions in the uninstall.py script do not leak out""" with tempfile.TemporaryDirectory() as temp_dir: toplevel_path = self.setup_dummy_installation(temp_dir) - with open( - os.path.join(toplevel_path, "uninstall.py"), "w", encoding="utf-8" - ) as f: + with open(os.path.join(toplevel_path, "uninstall.py"), "w", encoding="utf-8") as f: f.write( f"""# Mock uninstaller script raise RuntimeError("Fake exception for unit testing") """ ) - self.test_object.run_uninstall_script( - toplevel_path - ) # The exception does not leak out + self.test_object.run_uninstall_script(toplevel_path) # The exception does not leak out class TestMacroUninstaller(unittest.TestCase): @@ -317,15 +285,9 @@ class TestMacroUninstaller(unittest.TestCase): self.test_object = MacroUninstaller(self.mock_addon) self.signals_caught = [] - self.test_object.finished.connect( - functools.partial(self.catch_signal, "finished") - ) - self.test_object.success.connect( - functools.partial(self.catch_signal, "success") - ) - self.test_object.failure.connect( - functools.partial(self.catch_signal, "failure") - ) + self.test_object.finished.connect(functools.partial(self.catch_signal, "finished")) + self.test_object.success.connect(functools.partial(self.catch_signal, "success")) + self.test_object.failure.connect(functools.partial(self.catch_signal, "failure")) def tearDown(self): pass @@ -339,13 +301,9 @@ class TestMacroUninstaller(unittest.TestCase): self.test_object.installation_location = temp_dir self.mock_addon.macro.install(temp_dir) # Make sure the setup worked, otherwise the test is meaningless - self.assertTrue( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename)) - ) + self.assertTrue(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename))) self.test_object.run() - self.assertFalse( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename)) - ) + self.assertFalse(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename))) self.assertNotIn("failure", self.signals_caught) self.assertIn("success", self.signals_caught) self.assertIn("finished", self.signals_caught) @@ -356,19 +314,11 @@ class TestMacroUninstaller(unittest.TestCase): self.mock_addon.macro.icon = "mock_icon_test.svg" self.mock_addon.macro.install(temp_dir) # Make sure the setup worked, otherwise the test is meaningless - self.assertTrue( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename)) - ) - self.assertTrue( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.icon)) - ) + self.assertTrue(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename))) + self.assertTrue(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.icon))) self.test_object.run() - self.assertFalse( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename)) - ) - self.assertFalse( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.icon)) - ) + self.assertFalse(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename))) + self.assertFalse(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.icon))) self.assertNotIn("failure", self.signals_caught) self.assertIn("success", self.signals_caught) self.assertIn("finished", self.signals_caught) @@ -379,19 +329,11 @@ class TestMacroUninstaller(unittest.TestCase): self.mock_addon.macro.xpm = "/*Fake XPM data*/" self.mock_addon.macro.install(temp_dir) # Make sure the setup worked, otherwise the test is meaningless - self.assertTrue( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename)) - ) - self.assertTrue( - os.path.exists(os.path.join(temp_dir, "MockMacro_icon.xpm")) - ) + self.assertTrue(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename))) + self.assertTrue(os.path.exists(os.path.join(temp_dir, "MockMacro_icon.xpm"))) self.test_object.run() - self.assertFalse( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename)) - ) - self.assertFalse( - os.path.exists(os.path.join(temp_dir, "MockMacro_icon.xpm")) - ) + self.assertFalse(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename))) + self.assertFalse(os.path.exists(os.path.join(temp_dir, "MockMacro_icon.xpm"))) self.assertNotIn("failure", self.signals_caught) self.assertIn("success", self.signals_caught) self.assertIn("finished", self.signals_caught) @@ -430,13 +372,9 @@ class TestMacroUninstaller(unittest.TestCase): self.test_object.installation_location = temp_dir # Don't run the installer: - self.assertFalse( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename)) - ) + self.assertFalse(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename))) self.test_object.run() # Should not raise an exception - self.assertFalse( - os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename)) - ) + self.assertFalse(os.path.exists(os.path.join(temp_dir, self.mock_addon.macro.filename))) self.assertNotIn("failure", self.signals_caught) self.assertIn("success", self.signals_caught) self.assertIn("finished", self.signals_caught) @@ -489,9 +427,7 @@ class TestMacroUninstaller(unittest.TestCase): full_path = os.path.join(temp_dir, directory) os.mkdir(full_path) full_paths.add(full_path) - with open( - os.path.join(full_path, "test.txt"), "w", encoding="utf-8" - ) as f: + with open(os.path.join(full_path, "test.txt"), "w", encoding="utf-8") as f: f.write("Unit test dummy data\n") for directory in full_paths: diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_utilities.py b/src/Mod/AddonManager/AddonManagerTest/app/test_utilities.py index 2c2eba8921..1e7a4fd504 100644 --- a/src/Mod/AddonManager/AddonManagerTest/app/test_utilities.py +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_utilities.py @@ -53,9 +53,7 @@ class TestUtilities(unittest.TestCase): ] for url in recognized_urls: repo = Addon("Test Repo", url, Addon.Status.NOT_INSTALLED, "branch") - self.assertTrue( - recognized_git_location(repo), f"{url} was unexpectedly not recognized" - ) + self.assertTrue(recognized_git_location(repo), f"{url} was unexpectedly not recognized") unrecognized_urls = [ "https://google.com", @@ -65,9 +63,7 @@ class TestUtilities(unittest.TestCase): ] for url in unrecognized_urls: repo = Addon("Test Repo", url, Addon.Status.NOT_INSTALLED, "branch") - self.assertFalse( - recognized_git_location(repo), f"{url} was unexpectedly recognized" - ) + self.assertFalse(recognized_git_location(repo), f"{url} was unexpectedly recognized") def test_get_readme_url(self): github_urls = [ diff --git a/src/Mod/AddonManager/AddonManagerTest/data/DoNothing.FCMacro b/src/Mod/AddonManager/AddonManagerTest/data/DoNothing.FCMacro index 4ccec1e450..b20265d396 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/DoNothing.FCMacro +++ b/src/Mod/AddonManager/AddonManagerTest/data/DoNothing.FCMacro @@ -27,4 +27,4 @@ static char * blarg_xpm[] = { ".............**." };""" -print("Well, not quite *nothing*... it does print this line out.") \ No newline at end of file +print("Well, not quite *nothing*... it does print this line out.") diff --git a/src/Mod/AddonManager/AddonManagerTest/data/addon_update_stats.json b/src/Mod/AddonManager/AddonManagerTest/data/addon_update_stats.json index 837e9f0d59..f9f5206b30 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/addon_update_stats.json +++ b/src/Mod/AddonManager/AddonManagerTest/data/addon_update_stats.json @@ -1 +1,156 @@ -{"3DfindIT": {"refs/remotes/origin/HEAD": ["2022-09-08T13:58:17+02:00", "dc99f8f1bdb17c1e55c00ac0dffa3ec15caf5b9d"], "refs/remotes/origin/master": ["2022-09-08T13:58:17+02:00", "dc99f8f1bdb17c1e55c00ac0dffa3ec15caf5b9d"], "refs/tags/v1.0": ["2020-11-09T10:11:44+01:00", "e97b6caf5eaed0b709dfeabecedac14c9bc2cc2b"], "refs/tags/v1.1": ["2021-06-21T13:33:58+02:00", "b9ab38ae93fcb8c1f69516ea563494bca63ebf49"], "refs/tags/v1.2": ["2021-08-31T07:42:11+02:00", "d8553961a43dd450681f6df6e8ce5bce72da1b0a"]}, "3D_Printing_Tools": {"refs/remotes/origin/HEAD": ["2019-06-30T23:01:34+01:00", "e7ea9cd05dc11d5503115522b87cac7704eafc0e"], "refs/remotes/origin/master": ["2019-06-30T23:01:34+01:00", "e7ea9cd05dc11d5503115522b87cac7704eafc0e"]}, "A2plus": {"refs/remotes/origin/HEAD": ["2022-10-02T22:20:41+02:00", "3392d72ded45918ea28cd46ed4de778571488639"], "refs/remotes/origin/devel": ["2022-01-27T19:10:27+01:00", "dcc6193f36d4c7c8c43c4f3384e2bc03d27debd3"], "refs/remotes/origin/master": ["2022-10-02T22:20:41+02:00", "3392d72ded45918ea28cd46ed4de778571488639"], "refs/tags/V0.1.4.1": ["2018-10-28T16:38:46+01:00", "6f6ff0a892efca602ec916faac11b041be792fe2"], "refs/tags/V0.1.5": ["2018-11-01T19:03:15+01:00", "db6cdde71d4a2e9a53f2b14694e2ba2b42ac58c0"], "refs/tags/V0.1.6": ["2018-11-11T16:04:51+01:00", "46d4039c1fd08b3e5604d4fad3e955bca5855338"], "refs/tags/V0.4.6": ["2019-03-19T15:19:32+01:00", "42d5ed3846f24c7a7f0f6db655513e9038c3f651"]},"AirPlaneDesign": {"refs/remotes/origin/HEAD": ["2022-07-03T19:21:44+02:00", "34a5c5a827a378d4b6c9c16c54a1f2238b8e3b6b"], "refs/remotes/origin/dev-v0.4": ["2021-01-23T16:15:58+01:00", "f21bb8fca55b7d34fe920f0b823a7722ff977e43"], "refs/remotes/origin/dev-v03bis": ["2021-08-03T18:28:22+02:00", "5e2b4ebafaaed6ca87b99f480ae2fecd3722a83b"], "refs/remotes/origin/master": ["2022-07-03T19:21:44+02:00", "34a5c5a827a378d4b6c9c16c54a1f2238b8e3b6b"], "refs/remotes/origin/refactoring": ["2021-10-18T18:41:10+02:00", "2f22aa7faa049b0e8ec7dd43a39554b597c7e772"], "refs/tags/V0.1": ["2018-08-18T20:27:30+02:00", "c5bf85c552b31c0abdca7cadf428099c0b38e97e"], "refs/tags/V0.2": ["2019-07-30T08:36:55+02:00", "39a7c90ac53148c3317d50e07584c96f54db549e"], "refs/tags/V0.3": ["2019-10-25T08:44:43+02:00", "8e11fb6a5c33479570e0f572e6319f220e3cf6fd"]}, "Curves": {"refs/remotes/origin/HEAD": ["2022-10-06T19:18:14+02:00", "b43970d71ccfed6a85d6e547993863520db9920c"], "refs/remotes/origin/blendcurve": ["2020-02-26T18:55:13+01:00", "41dff49edfadc7b3085d4afff3c32b598fcd3ed0"], "refs/remotes/origin/blending": ["2022-06-24T17:52:22+02:00", "687b38faad85187e486fe68ccf072adb7d06be11"], "refs/remotes/origin/decimate_edges": ["2021-05-18T18:40:44+02:00", "b299597f3817cfb29fd45a8c5710706ae01261fe"], "refs/remotes/origin/facemap": ["2021-12-21T19:06:20+01:00", "7f315ab0e72d61fb6d04a2da631c66f8f3a30c82"], "refs/remotes/origin/flatten": ["2022-05-09T15:18:05+02:00", "436b135ff1c2d93686911c2e81ef4fa379e5b001"], "refs/remotes/origin/master": ["2022-10-06T19:18:14+02:00", "b43970d71ccfed6a85d6e547993863520db9920c"], "refs/remotes/origin/reflect2": ["2021-04-10T13:42:07+02:00", "6245d86e18f0e5c0a1e724ac614a369da18590e3"], "refs/remotes/origin/rotsweep": ["2022-10-05T17:50:39+02:00", "99b5e2619481257636d864921d22f60ca0af24d8"], "refs/remotes/origin/seamcheck": ["2022-03-18T17:53:05+01:00", "2703f93074a94ecdf09c4bb445bef347c206f00f"], "refs/remotes/origin/solid": ["2021-03-01T22:16:08+01:00", "4f4cc7ec6672b48660601b566777366fd0685a5d"], "refs/tags/v0.1": ["2019-02-17T08:57:09+01:00", "74ea77f091cf3a62e1dee3b64b49e9ab9fcdb560"], "refs/tags/v0.2": ["2020-06-16T15:02:23+02:00", "521037588be1aa28320ce6c9b9f77b40f4c8aeb6"], "refs/tags/v0.3": ["2021-01-08T19:06:59+01:00", "a1fa4857b1de95da1062acc63919acdee59f045c"]}} \ No newline at end of file +{ + "3DfindIT": { + "refs/remotes/origin/HEAD": [ + "2022-09-08T13:58:17+02:00", + "dc99f8f1bdb17c1e55c00ac0dffa3ec15caf5b9d" + ], + "refs/remotes/origin/master": [ + "2022-09-08T13:58:17+02:00", + "dc99f8f1bdb17c1e55c00ac0dffa3ec15caf5b9d" + ], + "refs/tags/v1.0": [ + "2020-11-09T10:11:44+01:00", + "e97b6caf5eaed0b709dfeabecedac14c9bc2cc2b" + ], + "refs/tags/v1.1": [ + "2021-06-21T13:33:58+02:00", + "b9ab38ae93fcb8c1f69516ea563494bca63ebf49" + ], + "refs/tags/v1.2": [ + "2021-08-31T07:42:11+02:00", + "d8553961a43dd450681f6df6e8ce5bce72da1b0a" + ] + }, + "3D_Printing_Tools": { + "refs/remotes/origin/HEAD": [ + "2019-06-30T23:01:34+01:00", + "e7ea9cd05dc11d5503115522b87cac7704eafc0e" + ], + "refs/remotes/origin/master": [ + "2019-06-30T23:01:34+01:00", + "e7ea9cd05dc11d5503115522b87cac7704eafc0e" + ] + }, + "A2plus": { + "refs/remotes/origin/HEAD": [ + "2022-10-02T22:20:41+02:00", + "3392d72ded45918ea28cd46ed4de778571488639" + ], + "refs/remotes/origin/devel": [ + "2022-01-27T19:10:27+01:00", + "dcc6193f36d4c7c8c43c4f3384e2bc03d27debd3" + ], + "refs/remotes/origin/master": [ + "2022-10-02T22:20:41+02:00", + "3392d72ded45918ea28cd46ed4de778571488639" + ], + "refs/tags/V0.1.4.1": [ + "2018-10-28T16:38:46+01:00", + "6f6ff0a892efca602ec916faac11b041be792fe2" + ], + "refs/tags/V0.1.5": [ + "2018-11-01T19:03:15+01:00", + "db6cdde71d4a2e9a53f2b14694e2ba2b42ac58c0" + ], + "refs/tags/V0.1.6": [ + "2018-11-11T16:04:51+01:00", + "46d4039c1fd08b3e5604d4fad3e955bca5855338" + ], + "refs/tags/V0.4.6": [ + "2019-03-19T15:19:32+01:00", + "42d5ed3846f24c7a7f0f6db655513e9038c3f651" + ] + }, + "AirPlaneDesign": { + "refs/remotes/origin/HEAD": [ + "2022-07-03T19:21:44+02:00", + "34a5c5a827a378d4b6c9c16c54a1f2238b8e3b6b" + ], + "refs/remotes/origin/dev-v0.4": [ + "2021-01-23T16:15:58+01:00", + "f21bb8fca55b7d34fe920f0b823a7722ff977e43" + ], + "refs/remotes/origin/dev-v03bis": [ + "2021-08-03T18:28:22+02:00", + "5e2b4ebafaaed6ca87b99f480ae2fecd3722a83b" + ], + "refs/remotes/origin/master": [ + "2022-07-03T19:21:44+02:00", + "34a5c5a827a378d4b6c9c16c54a1f2238b8e3b6b" + ], + "refs/remotes/origin/refactoring": [ + "2021-10-18T18:41:10+02:00", + "2f22aa7faa049b0e8ec7dd43a39554b597c7e772" + ], + "refs/tags/V0.1": [ + "2018-08-18T20:27:30+02:00", + "c5bf85c552b31c0abdca7cadf428099c0b38e97e" + ], + "refs/tags/V0.2": [ + "2019-07-30T08:36:55+02:00", + "39a7c90ac53148c3317d50e07584c96f54db549e" + ], + "refs/tags/V0.3": [ + "2019-10-25T08:44:43+02:00", + "8e11fb6a5c33479570e0f572e6319f220e3cf6fd" + ] + }, + "Curves": { + "refs/remotes/origin/HEAD": [ + "2022-10-06T19:18:14+02:00", + "b43970d71ccfed6a85d6e547993863520db9920c" + ], + "refs/remotes/origin/blendcurve": [ + "2020-02-26T18:55:13+01:00", + "41dff49edfadc7b3085d4afff3c32b598fcd3ed0" + ], + "refs/remotes/origin/blending": [ + "2022-06-24T17:52:22+02:00", + "687b38faad85187e486fe68ccf072adb7d06be11" + ], + "refs/remotes/origin/decimate_edges": [ + "2021-05-18T18:40:44+02:00", + "b299597f3817cfb29fd45a8c5710706ae01261fe" + ], + "refs/remotes/origin/facemap": [ + "2021-12-21T19:06:20+01:00", + "7f315ab0e72d61fb6d04a2da631c66f8f3a30c82" + ], + "refs/remotes/origin/flatten": [ + "2022-05-09T15:18:05+02:00", + "436b135ff1c2d93686911c2e81ef4fa379e5b001" + ], + "refs/remotes/origin/master": [ + "2022-10-06T19:18:14+02:00", + "b43970d71ccfed6a85d6e547993863520db9920c" + ], + "refs/remotes/origin/reflect2": [ + "2021-04-10T13:42:07+02:00", + "6245d86e18f0e5c0a1e724ac614a369da18590e3" + ], + "refs/remotes/origin/rotsweep": [ + "2022-10-05T17:50:39+02:00", + "99b5e2619481257636d864921d22f60ca0af24d8" + ], + "refs/remotes/origin/seamcheck": [ + "2022-03-18T17:53:05+01:00", + "2703f93074a94ecdf09c4bb445bef347c206f00f" + ], + "refs/remotes/origin/solid": [ + "2021-03-01T22:16:08+01:00", + "4f4cc7ec6672b48660601b566777366fd0685a5d" + ], + "refs/tags/v0.1": [ + "2019-02-17T08:57:09+01:00", + "74ea77f091cf3a62e1dee3b64b49e9ab9fcdb560" + ], + "refs/tags/v0.2": [ + "2020-06-16T15:02:23+02:00", + "521037588be1aa28320ce6c9b9f77b40f4c8aeb6" + ], + "refs/tags/v0.3": [ + "2021-01-08T19:06:59+01:00", + "a1fa4857b1de95da1062acc63919acdee59f045c" + ] + } +} diff --git a/src/Mod/AddonManager/AddonManagerTest/data/bad_macro_metadata.FCStd b/src/Mod/AddonManager/AddonManagerTest/data/bad_macro_metadata.FCStd index 12b1562194..f3932bbfe3 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/bad_macro_metadata.FCStd +++ b/src/Mod/AddonManager/AddonManagerTest/data/bad_macro_metadata.FCStd @@ -34,4 +34,4 @@ __Help__ = "" __Status__ = "" __Requires__ = "" __Communication__ = "" -__Files__ = "" \ No newline at end of file +__Files__ = "" diff --git a/src/Mod/AddonManager/AddonManagerTest/data/combination.xml b/src/Mod/AddonManager/AddonManagerTest/data/combination.xml index 8b214a0f17..3b75db30b7 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/combination.xml +++ b/src/Mod/AddonManager/AddonManagerTest/data/combination.xml @@ -25,4 +25,4 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/AddonManagerTest/data/git_submodules.txt b/src/Mod/AddonManager/AddonManagerTest/data/git_submodules.txt index 3e99986017..2a447c61b6 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/git_submodules.txt +++ b/src/Mod/AddonManager/AddonManagerTest/data/git_submodules.txt @@ -20,4 +20,4 @@ url = https://github.com/tomate44/CurvesWB.git [submodule "Defeaturing"] path = Defeaturing - url = https://github.com/easyw/Defeaturing_WB.git \ No newline at end of file + url = https://github.com/easyw/Defeaturing_WB.git diff --git a/src/Mod/AddonManager/AddonManagerTest/data/good_macro_metadata.FCStd b/src/Mod/AddonManager/AddonManagerTest/data/good_macro_metadata.FCStd index aa2955c197..2968bb5917 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/good_macro_metadata.FCStd +++ b/src/Mod/AddonManager/AddonManagerTest/data/good_macro_metadata.FCStd @@ -34,4 +34,4 @@ __Help__ = "" __Status__ = "" __Requires__ = "" __Communication__ = "" -__Files__ = "" \ No newline at end of file +__Files__ = "" diff --git a/src/Mod/AddonManager/AddonManagerTest/data/good_package.xml b/src/Mod/AddonManager/AddonManagerTest/data/good_package.xml index 1fede2a1c4..e484aa2ced 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/good_package.xml +++ b/src/Mod/AddonManager/AddonManagerTest/data/good_package.xml @@ -22,4 +22,4 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/AddonManagerTest/data/macro_only.xml b/src/Mod/AddonManager/AddonManagerTest/data/macro_only.xml index f28e004041..c8e47fa224 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/macro_only.xml +++ b/src/Mod/AddonManager/AddonManagerTest/data/macro_only.xml @@ -19,4 +19,4 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/AddonManagerTest/data/macro_template.FCStd b/src/Mod/AddonManager/AddonManagerTest/data/macro_template.FCStd index 74778e67a4..9cc885bd8d 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/macro_template.FCStd +++ b/src/Mod/AddonManager/AddonManagerTest/data/macro_template.FCStd @@ -34,4 +34,4 @@ __Help__ = "HELP" __Status__ = "STATUS" __Requires__ = "REQUIRES" __Communication__ = "COMMUNICATION" -__Files__ = "FILES" \ No newline at end of file +__Files__ = "FILES" diff --git a/src/Mod/AddonManager/AddonManagerTest/data/missing_macro_metadata.FCStd b/src/Mod/AddonManager/AddonManagerTest/data/missing_macro_metadata.FCStd index e6a77399bb..1dc58af652 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/missing_macro_metadata.FCStd +++ b/src/Mod/AddonManager/AddonManagerTest/data/missing_macro_metadata.FCStd @@ -22,4 +22,4 @@ # * * # *************************************************************************** -# This file contains no metadata \ No newline at end of file +# This file contains no metadata diff --git a/src/Mod/AddonManager/AddonManagerTest/data/prefpack_only.xml b/src/Mod/AddonManager/AddonManagerTest/data/prefpack_only.xml index 22731a7792..5affea4837 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/prefpack_only.xml +++ b/src/Mod/AddonManager/AddonManagerTest/data/prefpack_only.xml @@ -21,4 +21,4 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/AddonManagerTest/data/test_version_detection.xml b/src/Mod/AddonManager/AddonManagerTest/data/test_version_detection.xml index 66f90d9295..dfd578e0b2 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/test_version_detection.xml +++ b/src/Mod/AddonManager/AddonManagerTest/data/test_version_detection.xml @@ -30,4 +30,4 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/AddonManagerTest/data/workbench_only.xml b/src/Mod/AddonManager/AddonManagerTest/data/workbench_only.xml index 38cde82623..26ac759665 100644 --- a/src/Mod/AddonManager/AddonManagerTest/data/workbench_only.xml +++ b/src/Mod/AddonManager/AddonManagerTest/data/workbench_only.xml @@ -24,4 +24,4 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/AddonManagerTest/gui/test_installer_gui.py b/src/Mod/AddonManager/AddonManagerTest/gui/test_installer_gui.py index 56b766b5d8..6523f2ccdc 100644 --- a/src/Mod/AddonManager/AddonManagerTest/gui/test_installer_gui.py +++ b/src/Mod/AddonManager/AddonManagerTest/gui/test_installer_gui.py @@ -55,12 +55,8 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.Ok, ) self.installer_gui._installation_succeeded() - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_failure_dialog(self): # Pop the modal dialog and verify that it opens, and responds to a Cancel click @@ -71,12 +67,8 @@ class TestInstallerGui(unittest.TestCase): self.installer_gui._installation_failed( self.addon_to_install, "Test of installation failure" ) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_no_python_dialog(self): # Pop the modal dialog and verify that it opens, and responds to a No click @@ -85,12 +77,8 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.No, ) self.installer_gui._report_no_python_exe() - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_no_pip_dialog(self): # Pop the modal dialog and verify that it opens, and responds to a No click @@ -99,12 +87,8 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.No, ) self.installer_gui._report_no_pip("pip not actually run, this was a test") - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_dependency_failure_dialog(self): # Pop the modal dialog and verify that it opens, and responds to a No click @@ -115,12 +99,8 @@ class TestInstallerGui(unittest.TestCase): self.installer_gui._report_dependency_failure( "Unit test", "Nothing really failed, this is a test of the dialog box" ) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_install(self): # Run the installation code and make sure it puts the directory in place @@ -130,9 +110,7 @@ class TestInstallerGui(unittest.TestCase): self.installer_gui.installer.success.disconnect( self.installer_gui._installation_succeeded ) - self.installer_gui.installer.failure.disconnect( - self.installer_gui._installation_failed - ) + self.installer_gui.installer.failure.disconnect(self.installer_gui._installation_failed) while not self.installer_gui.worker_thread.isFinished(): QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents, 100) self.assertTrue( @@ -147,12 +125,8 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.Cancel, ) self.installer_gui._handle_disallowed_python(disallowed_packages) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_handle_disallowed_python_long_list(self): """A separate test for when there are MANY packages, which takes a separate code path.""" @@ -164,12 +138,8 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.Cancel, ) self.installer_gui._handle_disallowed_python(disallowed_packages) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_report_missing_workbenches_single(self): """Test only missing one workbench""" @@ -179,12 +149,8 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.Cancel, ) self.installer_gui._report_missing_workbenches(wbs) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_report_missing_workbenches_multiple(self): """Test only missing one workbench""" @@ -194,12 +160,8 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.Cancel, ) self.installer_gui._report_missing_workbenches(wbs) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_resolve_dependencies_then_install(self): class MissingDependenciesMock: @@ -214,12 +176,8 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.Cancel, ) self.installer_gui._resolve_dependencies_then_install(missing) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_check_python_version_bad(self): class MissingDependenciesMock: @@ -232,15 +190,9 @@ class TestInstallerGui(unittest.TestCase): QtWidgets.QDialogButtonBox.Cancel, ) stop_installing = self.installer_gui._check_python_version(missing) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) - self.assertTrue( - stop_installing, "Failed to halt installation on bad Python version" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") + self.assertTrue(stop_installing, "Failed to halt installation on bad Python version") def test_check_python_version_good(self): class MissingDependenciesMock: @@ -249,9 +201,7 @@ class TestInstallerGui(unittest.TestCase): missing = MissingDependenciesMock() stop_installing = self.installer_gui._check_python_version(missing) - self.assertFalse( - stop_installing, "Failed to continue installation on good Python version" - ) + self.assertFalse(stop_installing, "Failed to continue installation on good Python version") def test_clean_up_optional(self): class MissingDependenciesMock: @@ -270,9 +220,7 @@ class TestInstallerGui(unittest.TestCase): self.assertTrue("allowed_packages_2" in missing.python_optional) self.assertFalse("disallowed_package" in missing.python_optional) - def intercept_run_dependency_installer( - self, addons, python_requires, python_optional - ): + def intercept_run_dependency_installer(self, addons, python_requires, python_optional): self.assertEqual(python_requires, ["py_req_1", "py_req_2"]) self.assertEqual(python_optional, ["py_opt_1", "py_opt_2"]) self.assertEqual(addons[0].name, "addon_1") @@ -294,9 +242,7 @@ class TestInstallerGui(unittest.TestCase): def __init__(self, items): self.list = [] for item in items: - self.list.append( - DialogMock.ListWidgetMock.ListWidgetItemMock(item) - ) + self.list.append(DialogMock.ListWidgetMock.ListWidgetItemMock(item)) def count(self): return len(self.list) @@ -305,15 +251,9 @@ class TestInstallerGui(unittest.TestCase): return self.list[i] def __init__(self): - self.listWidgetAddons = DialogMock.ListWidgetMock( - ["addon_1", "addon_2"] - ) - self.listWidgetPythonRequired = DialogMock.ListWidgetMock( - ["py_req_1", "py_req_2"] - ) - self.listWidgetPythonOptional = DialogMock.ListWidgetMock( - ["py_opt_1", "py_opt_2"] - ) + self.listWidgetAddons = DialogMock.ListWidgetMock(["addon_1", "addon_2"]) + self.listWidgetPythonRequired = DialogMock.ListWidgetMock(["py_req_1", "py_req_2"]) + self.listWidgetPythonOptional = DialogMock.ListWidgetMock(["py_opt_1", "py_opt_2"]) class AddonMock: def __init__(self, name): @@ -321,9 +261,7 @@ class TestInstallerGui(unittest.TestCase): self.installer_gui.dependency_dialog = DialogMock() self.installer_gui.addons = [AddonMock("addon_1"), AddonMock("addon_2")] - self.installer_gui._run_dependency_installer = ( - self.intercept_run_dependency_installer - ) + self.installer_gui._run_dependency_installer = self.intercept_run_dependency_installer self.installer_gui._dependency_dialog_yes_clicked() @@ -481,9 +419,7 @@ class TestMacroInstallerGui(unittest.TestCase): self.assertEqual(name, "UnitTestCustomToolbar") self.assertIn("alwaysAskForToolbar", self.installer.addon_params.params) self.assertFalse(self.installer.addon_params.get("alwaysAskForToolbar", True)) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_ask_for_toolbar_with_dialog_selection(self): @@ -530,9 +466,7 @@ class TestMacroInstallerGui(unittest.TestCase): def test_macro_button_exists_true(self): # Test 2: Macro is in the list of buttons ut_tb_1 = self.installer.toolbar_params.GetGroup("UnitTestCommand") - ut_tb_1.set( - "UnitTestCommand", "FreeCAD" - ) # This is what the real thing looks like... + ut_tb_1.set("UnitTestCommand", "FreeCAD") # This is what the real thing looks like... self.installer._find_custom_command = lambda _: "UnitTestCommand" self.assertTrue(self.installer._macro_button_exists()) diff --git a/src/Mod/AddonManager/AddonManagerTest/gui/test_uninstaller_gui.py b/src/Mod/AddonManager/AddonManagerTest/gui/test_uninstaller_gui.py index a665a8e6b9..538c8daac9 100644 --- a/src/Mod/AddonManager/AddonManagerTest/gui/test_uninstaller_gui.py +++ b/src/Mod/AddonManager/AddonManagerTest/gui/test_uninstaller_gui.py @@ -62,12 +62,8 @@ class TestUninstallerGUI(unittest.TestCase): QtWidgets.QDialogButtonBox.Yes, ) answer = self.uninstaller_gui._confirm_uninstallation() - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") self.assertTrue(answer, "Expected a 'Yes' click to return True, but got False") def test_confirmation_dialog_cancel(self): @@ -76,15 +72,9 @@ class TestUninstallerGUI(unittest.TestCase): QtWidgets.QDialogButtonBox.Cancel, ) answer = self.uninstaller_gui._confirm_uninstallation() - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) - self.assertFalse( - answer, "Expected a 'Cancel' click to return False, but got True" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") + self.assertFalse(answer, "Expected a 'Cancel' click to return False, but got True") def test_progress_dialog(self): dialog_watcher = DialogWatcher( @@ -95,12 +85,8 @@ class TestUninstallerGUI(unittest.TestCase): # That call isn't modal, so spin our own event loop: while self.uninstaller_gui.progress_dialog.isVisible(): QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents, 100) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_timer_launches_progress_dialog(self): worker = FakeWorker() @@ -108,22 +94,14 @@ class TestUninstallerGUI(unittest.TestCase): translate("AddonsInstaller", "Removing Addon"), QtWidgets.QDialogButtonBox.Cancel, ) - QtCore.QTimer.singleShot( - 1000, worker.stop - ) # If the test fails, this kills the "worker" + QtCore.QTimer.singleShot(1000, worker.stop) # If the test fails, this kills the "worker" self.uninstaller_gui._confirm_uninstallation = lambda: True self.uninstaller_gui._run_uninstaller = worker.work self.uninstaller_gui._finalize = lambda: None - self.uninstaller_gui.dialog_timer.setInterval( - 1 - ) # To speed up the test, only wait 1ms + self.uninstaller_gui.dialog_timer.setInterval(1) # To speed up the test, only wait 1ms self.uninstaller_gui.run() # Blocks once it hits the fake worker - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") worker.stop() def test_success_dialog(self): @@ -132,12 +110,8 @@ class TestUninstallerGUI(unittest.TestCase): QtWidgets.QDialogButtonBox.Ok, ) self.uninstaller_gui._succeeded(self.addon_to_remove) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_failure_dialog(self): dialog_watcher = DialogWatcher( @@ -147,17 +121,11 @@ class TestUninstallerGUI(unittest.TestCase): self.uninstaller_gui._failed( self.addon_to_remove, "Some failure message\nAnother failure message" ) - self.assertTrue( - dialog_watcher.dialog_found, "Failed to find the expected dialog box" - ) - self.assertTrue( - dialog_watcher.button_found, "Failed to find the expected button" - ) + self.assertTrue(dialog_watcher.dialog_found, "Failed to find the expected dialog box") + self.assertTrue(dialog_watcher.button_found, "Failed to find the expected button") def test_finalize(self): - self.uninstaller_gui.finished.connect( - functools.partial(self.catch_signal, "finished") - ) + self.uninstaller_gui.finished.connect(functools.partial(self.catch_signal, "finished")) self.uninstaller_gui.worker_thread = MockThread() self.uninstaller_gui._finalize() self.assertIn("finished", self.signals_caught) diff --git a/src/Mod/AddonManager/AddonManagerTest/gui/test_update_all_gui.py b/src/Mod/AddonManager/AddonManagerTest/gui/test_update_all_gui.py index 6740495fbe..c45d382d20 100644 --- a/src/Mod/AddonManager/AddonManagerTest/gui/test_update_all_gui.py +++ b/src/Mod/AddonManager/AddonManagerTest/gui/test_update_all_gui.py @@ -43,9 +43,7 @@ class MockUpdater(QtCore.QObject): self.addons = addons self.has_run = False self.emit_success = True - self.work_function = ( - None # Set to some kind of callable to make this function take time - ) + self.work_function = None # Set to some kind of callable to make this function take time def run(self): self.has_run = True @@ -136,9 +134,7 @@ class TestUpdateAllGui(unittest.TestCase): self.test_object.run() cancel_timer = QtCore.QTimer() cancel_timer.timeout.connect( - self.test_object.dialog.buttonBox.button( - QtWidgets.QDialogButtonBox.Cancel - ).click + self.test_object.dialog.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel).click ) cancel_timer.start(90) while self.test_object.is_running(): diff --git a/src/Mod/AddonManager/AddonManagerTest/gui/test_workers_startup.py b/src/Mod/AddonManager/AddonManagerTest/gui/test_workers_startup.py index 1a3a2c0a25..c3dda4b72a 100644 --- a/src/Mod/AddonManager/AddonManagerTest/gui/test_workers_startup.py +++ b/src/Mod/AddonManager/AddonManagerTest/gui/test_workers_startup.py @@ -45,9 +45,7 @@ class TestWorkersStartup(unittest.TestCase): MODULE = "test_workers_startup" # file name without extension - @unittest.skipUnless( - run_slow_tests, "This integration test is slow and uses the network" - ) + @unittest.skipUnless(run_slow_tests, "This integration test is slow and uses the network") def setUp(self): """Set up the test""" self.test_dir = os.path.join( @@ -56,12 +54,8 @@ class TestWorkersStartup(unittest.TestCase): self.saved_mod_directory = Addon.mod_directory self.saved_cache_directory = Addon.cache_directory - Addon.mod_directory = os.path.join( - tempfile.gettempdir(), "FreeCADTesting", "Mod" - ) - Addon.cache_directory = os.path.join( - tempfile.gettempdir(), "FreeCADTesting", "Cache" - ) + Addon.mod_directory = os.path.join(tempfile.gettempdir(), "FreeCADTesting", "Mod") + Addon.cache_directory = os.path.join(tempfile.gettempdir(), "FreeCADTesting", "Cache") os.makedirs(Addon.mod_directory, mode=0o777, exist_ok=True) os.makedirs(Addon.cache_directory, mode=0o777, exist_ok=True) @@ -82,9 +76,7 @@ class TestWorkersStartup(unittest.TestCase): self.package_cache = {} self.macro_cache = [] - self.package_cache_filename = os.path.join( - Addon.cache_directory, "packages.json" - ) + self.package_cache_filename = os.path.join(Addon.cache_directory, "packages.json") self.macro_cache_filename = os.path.join(Addon.cache_directory, "macros.json") # Store the user's preference for whether git is enabled or disabled @@ -135,9 +127,7 @@ class TestWorkersStartup(unittest.TestCase): # Now try loading the same data from the cache we just created worker = LoadPackagesFromCacheWorker(self.package_cache_filename) - worker.override_metadata_cache_path( - os.path.join(Addon.cache_directory, "PackageMetadata") - ) + worker.override_metadata_cache_path(os.path.join(Addon.cache_directory, "PackageMetadata")) worker.addon_repo.connect(self._addon_added) worker.start() diff --git a/src/Mod/AddonManager/AddonManagerTest/gui/test_workers_utility.py b/src/Mod/AddonManager/AddonManagerTest/gui/test_workers_utility.py index 7f0478ff5a..cea77491aa 100644 --- a/src/Mod/AddonManager/AddonManagerTest/gui/test_workers_utility.py +++ b/src/Mod/AddonManager/AddonManagerTest/gui/test_workers_utility.py @@ -69,9 +69,7 @@ class TestWorkersUtility(unittest.TestCase): while worker.isRunning(): QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents, 50) QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents) - self.assertIsNone( - self.last_result, "Requesting interruption of thread failed to interrupt" - ) + self.assertIsNone(self.last_result, "Requesting interruption of thread failed to interrupt") def connection_succeeded(self): self.last_result = "SUCCESS" diff --git a/src/Mod/AddonManager/AddonManagerTest/test_information.md b/src/Mod/AddonManager/AddonManagerTest/test_information.md index 5baf0049cf..5df8cbc554 100644 --- a/src/Mod/AddonManager/AddonManagerTest/test_information.md +++ b/src/Mod/AddonManager/AddonManagerTest/test_information.md @@ -1,3 +1,3 @@ ## Unit tests for the Addon Manager -Data files are located in the `data/` subdirectory. \ No newline at end of file +Data files are located in the `data/` subdirectory. diff --git a/src/Mod/AddonManager/NetworkManager.py b/src/Mod/AddonManager/NetworkManager.py index 7848e952d6..c869f73d64 100644 --- a/src/Mod/AddonManager/NetworkManager.py +++ b/src/Mod/AddonManager/NetworkManager.py @@ -105,9 +105,7 @@ if HAVE_QTNETWORK: class QueueItem: """A container for information about an item in the network queue.""" - def __init__( - self, index: int, request: QtNetwork.QNetworkRequest, track_progress: bool - ): + def __init__(self, index: int, request: QtNetwork.QNetworkRequest, track_progress: bool): self.index = index self.request = request self.original_url = request.url() @@ -126,9 +124,7 @@ if HAVE_QTNETWORK: # Connect to progress_made and progress_complete for large amounts of data, which get buffered into a temp file # That temp file should be deleted when your code is done with it - progress_made = QtCore.Signal( - int, int, int - ) # Index, bytes read, total bytes (may be None) + progress_made = QtCore.Signal(int, int, int) # Index, bytes read, total bytes (may be None) progress_complete = QtCore.Signal( int, int, os.PathLike @@ -153,18 +149,14 @@ if HAVE_QTNETWORK: # Make sure we exit nicely on quit if QtCore.QCoreApplication.instance() is not None: - QtCore.QCoreApplication.instance().aboutToQuit.connect( - self.__aboutToQuit - ) + QtCore.QCoreApplication.instance().aboutToQuit.connect(self.__aboutToQuit) # Create the QNAM on this thread: self.QNAM = QtNetwork.QNetworkAccessManager() self.QNAM.proxyAuthenticationRequired.connect(self.__authenticate_proxy) self.QNAM.authenticationRequired.connect(self.__authenticate_resource) - qnam_cache = QtCore.QStandardPaths.writableLocation( - QtCore.QStandardPaths.CacheLocation - ) + qnam_cache = QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.CacheLocation) os.makedirs(qnam_cache, exist_ok=True) self.diskCache = QtNetwork.QNetworkDiskCache() self.diskCache.setCacheDirectory(qnam_cache) @@ -206,9 +198,7 @@ if HAVE_QTNETWORK: ) proxy = QtNetwork.QNetworkProxyFactory.systemProxyForQuery(query) if proxy and proxy[0]: - self.QNAM.setProxy( - proxy[0] - ) # This may still be QNetworkProxy.NoProxy + self.QNAM.setProxy(proxy[0]) # This may still be QNetworkProxy.NoProxy elif userProxyCheck: host, _, port_string = proxy_string.rpartition(":") try: @@ -223,9 +213,7 @@ if HAVE_QTNETWORK: ) port = 0 # For now assume an HttpProxy, but eventually this should be a parameter - proxy = QtNetwork.QNetworkProxy( - QtNetwork.QNetworkProxy.HttpProxy, host, port - ) + proxy = QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.HttpProxy, host, port) self.QNAM.setProxy(proxy) def _setup_proxy_freecad(self): @@ -314,9 +302,7 @@ if HAVE_QTNETWORK: except queue.Empty: pass - def __launch_request( - self, index: int, request: QtNetwork.QNetworkRequest - ) -> None: + def __launch_request(self, index: int, request: QtNetwork.QNetworkRequest) -> None: """Given a network request, ask the QNetworkAccessManager to begin processing it.""" reply = self.QNAM.get(request) self.replies[index] = reply @@ -338,9 +324,7 @@ if HAVE_QTNETWORK: current_index = next(self.counting_iterator) # A thread-safe counter # Use a queue because we can only put things on the QNAM from the main event loop thread self.queue.put( - QueueItem( - current_index, self.__create_get_request(url), track_progress=False - ) + QueueItem(current_index, self.__create_get_request(url), track_progress=False) ) self.__request_queued.emit() return current_index @@ -356,9 +340,7 @@ if HAVE_QTNETWORK: current_index = next(self.counting_iterator) # A thread-safe counter # Use a queue because we can only put things on the QNAM from the main event loop thread self.queue.put( - QueueItem( - current_index, self.__create_get_request(url), track_progress=True - ) + QueueItem(current_index, self.__create_get_request(url), track_progress=True) ) self.__request_queued.emit() return current_index @@ -371,9 +353,7 @@ if HAVE_QTNETWORK: self.synchronous_complete[current_index] = False self.queue.put( - QueueItem( - current_index, self.__create_get_request(url), track_progress=False - ) + QueueItem(current_index, self.__create_get_request(url), track_progress=False) ) self.__request_queued.emit() while True: @@ -415,9 +395,7 @@ if HAVE_QTNETWORK: QtNetwork.QNetworkRequest.RedirectPolicyAttribute, QtNetwork.QNetworkRequest.UserVerifiedRedirectPolicy, ) - request.setAttribute( - QtNetwork.QNetworkRequest.CacheSaveControlAttribute, True - ) + request.setAttribute(QtNetwork.QNetworkRequest.CacheSaveControlAttribute, True) request.setAttribute( QtNetwork.QNetworkRequest.CacheLoadControlAttribute, QtNetwork.QNetworkRequest.PreferNetwork, @@ -457,9 +435,7 @@ if HAVE_QTNETWORK: ) proxy_authentication.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint, True) # Show the right labels, etc. - proxy_authentication.labelProxyAddress.setText( - f"{reply.hostName()}:{reply.port()}" - ) + proxy_authentication.labelProxyAddress.setText(f"{reply.hostName()}:{reply.port()}") if authenticator.realm(): proxy_authentication.labelProxyRealm.setText(authenticator.realm()) else: @@ -468,9 +444,7 @@ if HAVE_QTNETWORK: result = proxy_authentication.exec() if result == QtWidgets.QDialogButtonBox.Ok: authenticator.setUser(proxy_authentication.lineEditUsername.text()) - authenticator.setPassword( - proxy_authentication.lineEditPassword.text() - ) + authenticator.setPassword(proxy_authentication.lineEditPassword.text()) else: username = input("Proxy username: ") import getpass @@ -502,8 +476,7 @@ if HAVE_QTNETWORK: """Called when an SSL error occurs: prints the error information.""" if HAVE_FREECAD: FreeCAD.Console.PrintWarning( - translate("AddonsInstaller", "Error with encrypted connection") - + "\n:" + translate("AddonsInstaller", "Error with encrypted connection") + "\n:" ) FreeCAD.Console.PrintWarning(reply) for error in errors: @@ -549,9 +522,7 @@ if HAVE_QTNETWORK: f.write(buffer.data()) except OSError as e: if HAVE_FREECAD: - FreeCAD.Console.PrintError( - f"Network Manager internal error: {str(e)}" - ) + FreeCAD.Console.PrintError(f"Network Manager internal error: {str(e)}") else: print(f"Network Manager internal error: {str(e)}") @@ -560,15 +531,10 @@ if HAVE_QTNETWORK: any notifications have been called.""" reply = self.sender() if not reply: - print( - "Network Manager Error: __reply_finished not called by a Qt signal" - ) + print("Network Manager Error: __reply_finished not called by a Qt signal") return - if ( - reply.error() - == QtNetwork.QNetworkReply.NetworkError.OperationCanceledError - ): + if reply.error() == QtNetwork.QNetworkReply.NetworkError.OperationCanceledError: # Silently do nothing return @@ -581,9 +547,7 @@ if HAVE_QTNETWORK: print(f"Lost net request for {reply.url()}") return - response_code = reply.attribute( - QtNetwork.QNetworkRequest.HttpStatusCodeAttribute - ) + response_code = reply.attribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute) self.queue.task_done() if reply.error() == QtNetwork.QNetworkReply.NetworkError.NoError: if index in self.monitored_connections: @@ -611,9 +575,7 @@ else: # HAVE_QTNETWORK is false: completed = QtCore.Signal( int, int, bytes ) # Emitted as soon as the request is made, with a connection failed error - progress_made = QtCore.Signal( - int, int, int - ) # Never emitted, no progress is made here + progress_made = QtCore.Signal(int, int, int) # Never emitted, no progress is made here progress_complete = QtCore.Signal( int, int, os.PathLike ) # Emitted as soon as the request is made, with a connection failed error @@ -675,9 +637,7 @@ if __name__ == "__main__": """Attached to the completion signal, prints diagnostic information about the network access""" global count if code == 200: - print( - f"For request {index+1}, response was {data.size()} bytes.", flush=True - ) + print(f"For request {index+1}, response was {data.size()} bytes.", flush=True) else: print( f"For request {index+1}, request failed with HTTP result code {code}", diff --git a/src/Mod/AddonManager/Resources/icons/BCFPlugin_workbench_icon.svg b/src/Mod/AddonManager/Resources/icons/BCFPlugin_workbench_icon.svg index 804c7fa1df..ccf9f03b06 100644 --- a/src/Mod/AddonManager/Resources/icons/BCFPlugin_workbench_icon.svg +++ b/src/Mod/AddonManager/Resources/icons/BCFPlugin_workbench_icon.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/Resources/icons/Geomatics_workbench_icon.svg b/src/Mod/AddonManager/Resources/icons/Geomatics_workbench_icon.svg index 3cecf6615d..e39563c820 100644 --- a/src/Mod/AddonManager/Resources/icons/Geomatics_workbench_icon.svg +++ b/src/Mod/AddonManager/Resources/icons/Geomatics_workbench_icon.svg @@ -1 +1 @@ -Layer 1 \ No newline at end of file +Layer 1 diff --git a/src/Mod/AddonManager/Resources/icons/TaackPLM_workbench_icon.svg b/src/Mod/AddonManager/Resources/icons/TaackPLM_workbench_icon.svg index 110009594d..39e96c180d 100644 --- a/src/Mod/AddonManager/Resources/icons/TaackPLM_workbench_icon.svg +++ b/src/Mod/AddonManager/Resources/icons/TaackPLM_workbench_icon.svg @@ -4,7 +4,7 @@ .st0{fill:none;} - + @@ -12,15 +12,15 @@ - + - + - + - - + + diff --git a/src/Mod/AddonManager/Resources/icons/dodo_workbench_icon.svg b/src/Mod/AddonManager/Resources/icons/dodo_workbench_icon.svg index 0d2cd46e84..fff4d48dce 100644 --- a/src/Mod/AddonManager/Resources/icons/dodo_workbench_icon.svg +++ b/src/Mod/AddonManager/Resources/icons/dodo_workbench_icon.svg @@ -209,4 +209,4 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/Resources/icons/fasteners_workbench_icon.svg b/src/Mod/AddonManager/Resources/icons/fasteners_workbench_icon.svg index 3a91a7b287..9a0e574186 100644 --- a/src/Mod/AddonManager/Resources/icons/fasteners_workbench_icon.svg +++ b/src/Mod/AddonManager/Resources/icons/fasteners_workbench_icon.svg @@ -1062,4 +1062,4 @@ id="path7525" d="M 10.394317,26.928236 C 6.0245941,22.283194 6.0765809,17.114547 10.538806,12.562787 16.543902,6.4372003 29.103274,3.5349553 40.872882,5.5531278 c 1.244209,0.2133484 3.085054,0.6218847 4.090769,0.9078584 l 1.828571,0.5199524 -1.260833,0.1285101 c -5.827548,0.5939709 -13.018922,3.5878883 -19.489477,8.1138723 -4.131135,2.88962 -8.415065,6.667234 -12.013782,10.593878 -1.20896,1.319123 -2.248653,2.398408 -2.310428,2.398408 -0.06178,0 -0.657299,-0.579317 -1.323385,-1.287371 z" style="opacity:1;fill:url(#linearGradient7541);fill-opacity:1;stroke:#000000;stroke-width:0.75590551;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - inkscape:connector-curvature="0" /> \ No newline at end of file + inkscape:connector-curvature="0" /> diff --git a/src/Mod/AddonManager/Resources/icons/flamingo_workbench_icon.svg b/src/Mod/AddonManager/Resources/icons/flamingo_workbench_icon.svg index 7ade88f6c5..a709f5b55f 100644 --- a/src/Mod/AddonManager/Resources/icons/flamingo_workbench_icon.svg +++ b/src/Mod/AddonManager/Resources/icons/flamingo_workbench_icon.svg @@ -142,4 +142,4 @@ - \ No newline at end of file + diff --git a/src/Mod/AddonManager/Resources/icons/sheetmetal_workbench_icon.svg b/src/Mod/AddonManager/Resources/icons/sheetmetal_workbench_icon.svg index 0de9d9d024..653cddf314 100644 --- a/src/Mod/AddonManager/Resources/icons/sheetmetal_workbench_icon.svg +++ b/src/Mod/AddonManager/Resources/icons/sheetmetal_workbench_icon.svg @@ -748,4 +748,4 @@ id="path7555" d="M 1.1006857,295.7803 15.528592,281.35239 v 7.21396 l -7.2139532,7.21395 z" style="fill:url(#linearGradient4474);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - inkscape:connector-curvature="0" /> \ No newline at end of file + inkscape:connector-curvature="0" /> diff --git a/src/Mod/AddonManager/Resources/licenses/BSD-2-Clause.txt b/src/Mod/AddonManager/Resources/licenses/BSD-2-Clause.txt index 702c09ea1c..b6e0e031a3 100644 --- a/src/Mod/AddonManager/Resources/licenses/BSD-2-Clause.txt +++ b/src/Mod/AddonManager/Resources/licenses/BSD-2-Clause.txt @@ -1,20 +1,20 @@ Copyright <%%YEAR%%> <%%COPYRIGHT HOLDER%%> -Redistribution and use in source and binary forms, with or without modification, are permitted +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this list of conditions +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of -conditions and the following disclaimer in the documentation and/or other materials provided with +2. Redistributions in binary form must reproduce the above copyright notice, this list of +conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/Mod/AddonManager/Resources/licenses/BSD-3-Clause.txt b/src/Mod/AddonManager/Resources/licenses/BSD-3-Clause.txt index 7ae7687aaf..fe112b08ea 100644 --- a/src/Mod/AddonManager/Resources/licenses/BSD-3-Clause.txt +++ b/src/Mod/AddonManager/Resources/licenses/BSD-3-Clause.txt @@ -1,23 +1,23 @@ Copyright <%%YEAR%%> <%%COPYRIGHT HOLDER%%> -Redistribution and use in source and binary forms, with or without modification, are permitted +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this list of conditions +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of -conditions and the following disclaimer in the documentation and/or other materials provided with +2. Redistributions in binary form must reproduce the above copyright notice, this list of +conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/Mod/AddonManager/Resources/licenses/CC0v1.txt b/src/Mod/AddonManager/Resources/licenses/CC0v1.txt index cb097a491b..ae39b2e3cd 100644 --- a/src/Mod/AddonManager/Resources/licenses/CC0v1.txt +++ b/src/Mod/AddonManager/Resources/licenses/CC0v1.txt @@ -1,97 +1,97 @@ CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF -THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS +THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose -The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and -Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") +The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and +Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of -contributing to a commons of creative, cultural and scientific works ("Commons") that the public -can reliably and without fear of later claims of infringement build upon, modify, incorporate in -other works, reuse and redistribute as freely as possible in any form whatsoever and for any -purposes, including without limitation commercial purposes. These owners may contribute to the -Commons to promote the ideal of a free culture and the further production of creative, cultural -and scientific works, or to gain reputation or greater distribution for their Work in part through +contributing to a commons of creative, cultural and scientific works ("Commons") that the public +can reliably and without fear of later claims of infringement build upon, modify, incorporate in +other works, reuse and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may contribute to the +Commons to promote the ideal of a free culture and the further production of creative, cultural +and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. -For these and/or other purposes and motivations, and without any expectation of additional -consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the -extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects +For these and/or other purposes and motivations, and without any expectation of additional +consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the +extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or -her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on +her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. -1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and -related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights +1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and +related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; moral rights retained by the original author(s) and/or performer(s); publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; -rights protecting against unfair competition in regards to a Work, subject to the limitations in +rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; rights protecting the extraction, dissemination, use and reuse of data in a Work; -database rights (such as those arising under Directive 96/9/EC of the European Parliament and of -the Council of 11 March 1996 on the legal protection of databases, and under any national +database rights (such as those arising under Directive 96/9/EC of the European Parliament and of +the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and -other similar, equivalent or corresponding rights throughout the world based on applicable +other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. -2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, -Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, -and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as future claims and causes -of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided -by applicable law or treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the -Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's -heirs and successors, fully intending that such Waiver shall not be subject to revocation, -rescission, cancellation, termination, or any other legal or equitable action to disrupt the -quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of +2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, +Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, +and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as future claims and causes +of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided +by applicable law or treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the +Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's +heirs and successors, fully intending that such Waiver shall not be subject to revocation, +rescission, cancellation, termination, or any other legal or equitable action to disrupt the +quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. -3. Public License Fallback. Should any part of the Waiver for any reason be judged legally -invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum +3. Public License Fallback. Should any part of the Waiver for any reason be judged legally +invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, -non-transferable, non sublicensable, non exclusive, irrevocable and unconditional license to -exercise Affirmer's Copyright and Related Rights in the Work -(i) in all territories worldwide, -(ii) for the maximum duration provided by applicable law or treaty (including future time -extensions), -(iii) in any current or future medium and for any number of copies, and -(iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional +extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, +non-transferable, non sublicensable, non exclusive, irrevocable and unconditional license to +exercise Affirmer's Copyright and Related Rights in the Work +(i) in all territories worldwide, +(ii) for the maximum duration provided by applicable law or treaty (including future time +extensions), +(iii) in any current or future medium and for any number of copies, and +(iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by -Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or -ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate -the remainder of the License, and in such case Affirmer hereby affirms that he or she will not -(i) exercise any of his or her remaining Copyright and Related Rights in the Work or -(ii) assert any associated claims and causes of action with respect to the Work, in either case +Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or +ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate +the remainder of the License, and in such case Affirmer hereby affirms that he or she will not +(i) exercise any of his or her remaining Copyright and Related Rights in the Work or +(ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. -No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or +No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. -Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning -the Work, express, implied, statutory or otherwise, including without limitation warranties of -title, merchantability, fitness for a particular purpose, non infringement, or the absence of -latent or other defects, accuracy, or the present or absence of errors, whether or not +Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning +the Work, express, implied, statutory or otherwise, including without limitation warranties of +title, merchantability, fitness for a particular purpose, non infringement, or the absence of +latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work -or any use thereof, including without limitation any person's Copyright and Related Rights in the -Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions +or any use thereof, including without limitation any person's Copyright and Related Rights in the +Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. -Affirmer understands and acknowledges that Creative Commons is not a party to this document and has +Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. diff --git a/src/Mod/AddonManager/Resources/licenses/LGPLv2.1.txt b/src/Mod/AddonManager/Resources/licenses/LGPLv2.1.txt index 745d96744f..e5ab03e123 100644 --- a/src/Mod/AddonManager/Resources/licenses/LGPLv2.1.txt +++ b/src/Mod/AddonManager/Resources/licenses/LGPLv2.1.txt @@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. - + Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a @@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. - + GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @@ -158,7 +158,7 @@ Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - + 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 @@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. - + Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. @@ -267,7 +267,7 @@ Library will still fall under Section 6.) distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. - + 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work @@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. - + 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined @@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. - + 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or @@ -422,7 +422,7 @@ conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. - + 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is diff --git a/src/Mod/AddonManager/addonmanager_connection_checker.py b/src/Mod/AddonManager/addonmanager_connection_checker.py index ecfb05b57a..76cf14a574 100644 --- a/src/Mod/AddonManager/addonmanager_connection_checker.py +++ b/src/Mod/AddonManager/addonmanager_connection_checker.py @@ -69,9 +69,7 @@ class ConnectionCheckerGUI(QtCore.QObject): translate("AddonsInstaller", "Checking for connection to GitHub..."), QtWidgets.QMessageBox.Cancel, ) - self.connection_check_message.buttonClicked.connect( - self.cancel_network_check - ) + self.connection_check_message.buttonClicked.connect(self.cancel_network_check) self.connection_check_message.show() def cancel_network_check(self, _): diff --git a/src/Mod/AddonManager/addonmanager_dependency_installer.py b/src/Mod/AddonManager/addonmanager_dependency_installer.py index f066d527f4..ccff230cf1 100644 --- a/src/Mod/AddonManager/addonmanager_dependency_installer.py +++ b/src/Mod/AddonManager/addonmanager_dependency_installer.py @@ -151,9 +151,7 @@ class DependencyInstaller(QObject): fci.Console.PrintMessage(proc.stdout + "\n") except subprocess.CalledProcessError as e: fci.Console.PrintError( - translate( - "AddonsInstaller", "Installation of optional package failed" - ) + translate("AddonsInstaller", "Installation of optional package failed") + ":\n" + str(e) + "\n" @@ -182,23 +180,19 @@ class DependencyInstaller(QObject): if is_interruption_requested(): return fci.Console.PrintMessage( - translate( - "AddonsInstaller", "Installing required dependency {}" - ).format(addon.name) + translate("AddonsInstaller", "Installing required dependency {}").format(addon.name) + "\n" ) if addon.macro is None: installer = AddonInstaller(addon) else: installer = MacroInstaller(addon) - result = ( - installer.run() - ) # Run in this thread, which should be off the GUI thread + result = installer.run() # Run in this thread, which should be off the GUI thread if not result: self.failure.emit( - translate( - "AddonsInstaller", "Installation of Addon {} failed" - ).format(addon.name), + translate("AddonsInstaller", "Installation of Addon {} failed").format( + addon.name + ), "", ) return diff --git a/src/Mod/AddonManager/addonmanager_devmode.py b/src/Mod/AddonManager/addonmanager_devmode.py index f57cc2efb0..87aae2d00b 100644 --- a/src/Mod/AddonManager/addonmanager_devmode.py +++ b/src/Mod/AddonManager/addonmanager_devmode.py @@ -70,9 +70,7 @@ class AddonGitInterface: try: AddonGitInterface.git_manager = GitManager() except NoGitFound: - FreeCAD.Console.PrintLog( - "No git found, Addon Manager Developer Mode disabled." - ) + FreeCAD.Console.PrintLog("No git found, Addon Manager Developer Mode disabled.") return self.path = path @@ -127,12 +125,8 @@ class DeveloperMode: small_size_policy.setHorizontalStretch(1) self.people_table.widget.setSizePolicy(large_size_policy) self.licenses_table.widget.setSizePolicy(small_size_policy) - self.dialog.peopleAndLicenseshorizontalLayout.addWidget( - self.people_table.widget - ) - self.dialog.peopleAndLicenseshorizontalLayout.addWidget( - self.licenses_table.widget - ) + self.dialog.peopleAndLicenseshorizontalLayout.addWidget(self.people_table.widget) + self.dialog.peopleAndLicenseshorizontalLayout.addWidget(self.licenses_table.widget) self.pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons") self.current_mod: str = "" self.git_interface = None @@ -267,27 +261,17 @@ class DeveloperMode: if item.Name: info.append(translate("AddonsInstaller", "Name") + ": " + item.Name) if item.Classname: - info.append( - translate("AddonsInstaller", "Class") + ": " + item.Classname - ) + info.append(translate("AddonsInstaller", "Class") + ": " + item.Classname) if item.Description: info.append( - translate("AddonsInstaller", "Description") - + ": " - + item.Description + translate("AddonsInstaller", "Description") + ": " + item.Description ) if item.Subdirectory: info.append( - translate("AddonsInstaller", "Subdirectory") - + ": " - + item.Subdirectory + translate("AddonsInstaller", "Subdirectory") + ": " + item.Subdirectory ) if item.File: - info.append( - translate("AddonsInstaller", "Files") - + ": " - + ", ".join(item.File) - ) + info.append(translate("AddonsInstaller", "Files") + ": " + ", ".join(item.File)) contents_string += ", ".join(info) item = QListWidgetItem(contents_string) @@ -357,24 +341,14 @@ class DeveloperMode: def _setup_dialog_signals(self): """Set up the signal and slot connections for the main dialog.""" - self.dialog.addonPathBrowseButton.clicked.connect( - self._addon_browse_button_clicked - ) - self.dialog.pathToAddonComboBox.editTextChanged.connect( - self._addon_combo_text_changed - ) - self.dialog.detectMinPythonButton.clicked.connect( - self._detect_min_python_clicked - ) + self.dialog.addonPathBrowseButton.clicked.connect(self._addon_browse_button_clicked) + self.dialog.pathToAddonComboBox.editTextChanged.connect(self._addon_combo_text_changed) + self.dialog.detectMinPythonButton.clicked.connect(self._detect_min_python_clicked) self.dialog.iconBrowseButton.clicked.connect(self._browse_for_icon_clicked) self.dialog.addContentItemToolButton.clicked.connect(self._add_content_clicked) - self.dialog.removeContentItemToolButton.clicked.connect( - self._remove_content_clicked - ) - self.dialog.contentsListWidget.itemSelectionChanged.connect( - self._content_selection_changed - ) + self.dialog.removeContentItemToolButton.clicked.connect(self._remove_content_clicked) + self.dialog.contentsListWidget.itemSelectionChanged.connect(self._content_selection_changed) self.dialog.contentsListWidget.itemDoubleClicked.connect(self._edit_content) self.dialog.versionToTodayButton.clicked.connect(self._set_to_today_clicked) @@ -393,17 +367,13 @@ class DeveloperMode: self.metadata = FreeCAD.Metadata() self.metadata.Name = self.dialog.displayNameLineEdit.text() - self.metadata.Description = ( - self.dialog.descriptionTextEdit.document().toPlainText() - ) + self.metadata.Description = self.dialog.descriptionTextEdit.document().toPlainText() self.metadata.Version = self.dialog.versionLineEdit.text() self.metadata.Icon = self.dialog.iconPathLineEdit.text() urls = [] if self.dialog.websiteURLLineEdit.text(): - urls.append( - {"location": self.dialog.websiteURLLineEdit.text(), "type": "website"} - ) + urls.append({"location": self.dialog.websiteURLLineEdit.text(), "type": "website"}) if self.dialog.repositoryURLLineEdit.text(): urls.append( { @@ -420,9 +390,7 @@ class DeveloperMode: } ) if self.dialog.readmeURLLineEdit.text(): - urls.append( - {"location": self.dialog.readmeURLLineEdit.text(), "type": "readme"} - ) + urls.append({"location": self.dialog.readmeURLLineEdit.text(), "type": "readme"}) if self.dialog.documentationURLLineEdit.text(): urls.append( { @@ -594,9 +562,7 @@ class DeveloperMode: ) return FreeCAD.Console.PrintMessage( - translate( - "AddonsInstaller", "Scanning Addon for Python version compatibility" - ) + translate("AddonsInstaller", "Scanning Addon for Python version compatibility") + "...\n" ) # pylint: disable=import-outside-toplevel @@ -608,9 +574,7 @@ class DeveloperMode: if filename.endswith(".py"): with open(os.path.join(dir_path, filename), encoding="utf-8") as f: contents = f.read() - version_strings = vermin.version_strings( - vermin.detect(contents) - ) + version_strings = vermin.version_strings(vermin.detect(contents)) version = version_strings.split(",") if len(version) >= 2: # Only care about Py3, and only if there is a dot in the version: @@ -622,9 +586,7 @@ class DeveloperMode: FreeCAD.Console.PrintLog( f"Detected Python 3.{minor} required by {filename}\n" ) - required_minor_version = max( - required_minor_version, minor - ) + required_minor_version = max(required_minor_version, minor) self.dialog.minPythonLineEdit.setText(f"3.{required_minor_version}") QMessageBox.information( self.dialog, @@ -654,13 +616,10 @@ class DeveloperMode: if response == QMessageBox.Cancel: return False FreeCAD.Console.PrintMessage( - translate("AddonsInstaller", "Attempting to install Vermin from PyPi") - + "...\n" + translate("AddonsInstaller", "Attempting to install Vermin from PyPi") + "...\n" ) python_exe = utils.get_python_exe() - vendor_path = os.path.join( - FreeCAD.getUserAppDataDir(), "AdditionalPythonPackages" - ) + vendor_path = os.path.join(FreeCAD.getUserAppDataDir(), "AdditionalPythonPackages") if not os.path.exists(vendor_path): os.makedirs(vendor_path) diff --git a/src/Mod/AddonManager/addonmanager_devmode_add_content.py b/src/Mod/AddonManager/addonmanager_devmode_add_content.py index 2d74b7a6e5..c5994ccbab 100644 --- a/src/Mod/AddonManager/addonmanager_devmode_add_content.py +++ b/src/Mod/AddonManager/addonmanager_devmode_add_content.py @@ -80,32 +80,22 @@ class AddContent: small_size_policy.setHorizontalStretch(1) self.people_table.widget.setSizePolicy(large_size_policy) self.licenses_table.widget.setSizePolicy(small_size_policy) - self.dialog.peopleAndLicenseshorizontalLayout.addWidget( - self.people_table.widget - ) - self.dialog.peopleAndLicenseshorizontalLayout.addWidget( - self.licenses_table.widget - ) + self.dialog.peopleAndLicenseshorizontalLayout.addWidget(self.people_table.widget) + self.dialog.peopleAndLicenseshorizontalLayout.addWidget(self.licenses_table.widget) self.toplevel_metadata = toplevel_metadata self.metadata = None self.path_to_addon = path_to_addon.replace("/", os.path.sep) if self.path_to_addon[-1] != os.path.sep: - self.path_to_addon += ( - os.path.sep - ) # Make sure the path ends with a separator + self.path_to_addon += os.path.sep # Make sure the path ends with a separator self.dialog.iconLabel.hide() # Until we have an icon to display self.dialog.iconBrowseButton.clicked.connect(self._browse_for_icon_clicked) - self.dialog.subdirectoryBrowseButton.clicked.connect( - self._browse_for_subdirectory_clicked - ) + self.dialog.subdirectoryBrowseButton.clicked.connect(self._browse_for_subdirectory_clicked) self.dialog.tagsButton.clicked.connect(self._tags_clicked) self.dialog.dependenciesButton.clicked.connect(self._dependencies_clicked) - self.dialog.freecadVersionsButton.clicked.connect( - self._freecad_versions_clicked - ) + self.dialog.freecadVersionsButton.clicked.connect(self._freecad_versions_clicked) self.dialog.versionLineEdit.setValidator(VersionValidator()) self.dialog.prefPackNameLineEdit.setValidator(NameValidator()) @@ -134,9 +124,7 @@ class AddContent: if index == -1: index = 2 # Workbench FreeCAD.Console.PrintWarning( - translate("AddonsInstaller", "Unrecognized content kind '{}'").format( - content_kind - ) + translate("AddonsInstaller", "Unrecognized content kind '{}'").format(content_kind) + "\n" ) self.dialog.addonKindComboBox.setCurrentIndex(index) @@ -189,9 +177,7 @@ class AddContent: def _set_icon(self, icon_relative_path): """Load the icon and display it, and its path, in the dialog.""" - icon_path = os.path.join( - self.path_to_addon, icon_relative_path.replace("/", os.path.sep) - ) + icon_path = os.path.join(self.path_to_addon, icon_relative_path.replace("/", os.path.sep)) if os.path.isfile(icon_path): icon_data = QIcon(icon_path) if not icon_data.isNull(): @@ -199,10 +185,7 @@ class AddContent: self.dialog.iconLabel.show() else: FreeCAD.Console.PrintError( - translate("AddonsInstaller", "Unable to locate icon at {}").format( - icon_path - ) - + "\n" + translate("AddonsInstaller", "Unable to locate icon at {}").format(icon_path) + "\n" ) self.dialog.iconLineEdit.setText(icon_relative_path) @@ -234,9 +217,7 @@ class AddContent: return current_data, self.metadata # Otherwise, process the rest of the metadata (display name is already done) - self.metadata.Description = ( - self.dialog.descriptionTextEdit.document().toPlainText() - ) + self.metadata.Description = self.dialog.descriptionTextEdit.document().toPlainText() self.metadata.Version = self.dialog.versionLineEdit.text() maintainers = [] @@ -407,16 +388,10 @@ class EditDependencies: self.dialog.removeDependencyToolButton.setIcon( QIcon.fromTheme("remove", QIcon(":/icons/list-remove.svg")) ) - self.dialog.addDependencyToolButton.clicked.connect( - self._add_dependency_clicked - ) - self.dialog.removeDependencyToolButton.clicked.connect( - self._remove_dependency_clicked - ) + self.dialog.addDependencyToolButton.clicked.connect(self._add_dependency_clicked) + self.dialog.removeDependencyToolButton.clicked.connect(self._remove_dependency_clicked) self.dialog.tableWidget.itemDoubleClicked.connect(self._edit_dependency) - self.dialog.tableWidget.itemSelectionChanged.connect( - self._current_index_changed - ) + self.dialog.tableWidget.itemSelectionChanged.connect(self._current_index_changed) self.dialog.removeDependencyToolButton.setDisabled(True) self.metadata = None @@ -485,9 +460,7 @@ class EditDependencies: dep_type = self.dialog.tableWidget.item(row, 0).data(Qt.UserRole) dep_name = self.dialog.tableWidget.item(row, 1).text() dep_optional = bool(self.dialog.tableWidget.item(row, 2)) - new_dep_type, new_dep_name, new_dep_optional = dlg.exec( - dep_type, dep_name, dep_optional - ) + new_dep_type, new_dep_name, new_dep_optional = dlg.exec(dep_type, dep_name, dep_optional) if dep_type and dep_name: self.metadata.removeDepend( {"package": dep_name, "type": dep_type, "optional": dep_optional} @@ -520,16 +493,10 @@ class EditDependency: self.dialog.typeComboBox.addItem( translate("AddonsInstaller", "Internal Workbench"), "workbench" ) - self.dialog.typeComboBox.addItem( - translate("AddonsInstaller", "External Addon"), "addon" - ) - self.dialog.typeComboBox.addItem( - translate("AddonsInstaller", "Python Package"), "python" - ) + self.dialog.typeComboBox.addItem(translate("AddonsInstaller", "External Addon"), "addon") + self.dialog.typeComboBox.addItem(translate("AddonsInstaller", "Python Package"), "python") - self.dialog.typeComboBox.currentIndexChanged.connect( - self._type_selection_changed - ) + self.dialog.typeComboBox.currentIndexChanged.connect(self._type_selection_changed) self.dialog.dependencyComboBox.currentIndexChanged.connect( self._dependency_selection_changed ) @@ -539,9 +506,7 @@ class EditDependency: self.dialog.layout().setSizeConstraint(QLayout.SetFixedSize) - def exec( - self, dep_type="", dep_name="", dep_optional=False - ) -> Tuple[str, str, bool]: + def exec(self, dep_type="", dep_name="", dep_optional=False) -> Tuple[str, str, bool]: """Execute the dialog, returning a tuple of the type of dependency (workbench, addon, or python), the name of the dependency, and a boolean indicating whether this is optional. """ @@ -590,12 +555,8 @@ class EditDependency: repo_dict[repo.display_name.lower()] = (repo.display_name, repo.name) sorted_keys = sorted(repo_dict) for item in sorted_keys: - self.dialog.dependencyComboBox.addItem( - repo_dict[item][0], repo_dict[item][1] - ) - self.dialog.dependencyComboBox.addItem( - translate("AddonsInstaller", "Other..."), "other" - ) + self.dialog.dependencyComboBox.addItem(repo_dict[item][0], repo_dict[item][1]) + self.dialog.dependencyComboBox.addItem(translate("AddonsInstaller", "Other..."), "other") def _populate_allowed_python_packages(self): """Add all allowed python packages to the list""" @@ -606,9 +567,7 @@ class EditDependency: packages = sorted(AM_INSTANCE.allowed_packages) for package in packages: self.dialog.dependencyComboBox.addItem(package, package) - self.dialog.dependencyComboBox.addItem( - translate("AddonsInstaller", "Other..."), "other" - ) + self.dialog.dependencyComboBox.addItem(translate("AddonsInstaller", "Other..."), "other") def _type_selection_changed(self, _): """Callback: The type of dependency has been changed""" @@ -637,9 +596,7 @@ class EditFreeCADVersions: def __init__(self): self.dialog = FreeCADGui.PySideUic.loadUi( - os.path.join( - os.path.dirname(__file__), "developer_mode_freecad_versions.ui" - ) + os.path.join(os.path.dirname(__file__), "developer_mode_freecad_versions.ui") ) def exec(self, metadata: FreeCAD.Metadata): @@ -666,9 +623,7 @@ class EditAdvancedVersions: def __init__(self): self.dialog = FreeCADGui.PySideUic.loadUi( - os.path.join( - os.path.dirname(__file__), "developer_mode_advanced_freecad_versions.ui" - ) + os.path.join(os.path.dirname(__file__), "developer_mode_advanced_freecad_versions.ui") ) def exec(self): diff --git a/src/Mod/AddonManager/addonmanager_devmode_license_selector.py b/src/Mod/AddonManager/addonmanager_devmode_license_selector.py index 7b20a4cdc8..3aa6da6973 100644 --- a/src/Mod/AddonManager/addonmanager_devmode_license_selector.py +++ b/src/Mod/AddonManager/addonmanager_devmode_license_selector.py @@ -117,9 +117,7 @@ class LicenseSelector: ) self.pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons") for short_code, details in LicenseSelector.licenses.items(): - self.dialog.comboBox.addItem( - f"{short_code}: {details[0]}", userData=short_code - ) + self.dialog.comboBox.addItem(f"{short_code}: {details[0]}", userData=short_code) self.dialog.comboBox.addItem(self.other_label) self.dialog.otherLineEdit.hide() self.dialog.otherLabel.hide() @@ -134,9 +132,7 @@ class LicenseSelector: short_code = self.pref.GetString("devModeLastSelectedLicense", "LGPLv2.1") self.set_license(short_code) - def exec( - self, short_code: str = None, license_path: str = "" - ) -> Optional[Tuple[str, str]]: + def exec(self, short_code: str = None, license_path: str = "") -> Optional[Tuple[str, str]]: """The main method for executing this dialog, as a modal that returns a tuple of the license's "short code" and optionally the path to the license file. Returns a tuple of None,None if the user cancels the operation.""" @@ -252,10 +248,7 @@ class LicenseSelector: string_data = str(byte_data, encoding="utf-8") - if ( - "<%%YEAR%%>" in string_data - or "<%%COPYRIGHT HOLDER%%>" in string_data - ): + if "<%%YEAR%%>" in string_data or "<%%COPYRIGHT HOLDER%%>" in string_data: info_dlg = FreeCADGui.PySideUic.loadUi( os.path.join( os.path.dirname(__file__), @@ -279,6 +272,4 @@ class LicenseSelector: with open(license_path, "w", encoding="utf-8") as f: f.write(string_data) else: - FreeCAD.Console.PrintError( - f"Cannot create license file of type {short_code}\n" - ) + FreeCAD.Console.PrintError(f"Cannot create license file of type {short_code}\n") diff --git a/src/Mod/AddonManager/addonmanager_devmode_licenses_table.py b/src/Mod/AddonManager/addonmanager_devmode_licenses_table.py index a30ee37028..1d52568471 100644 --- a/src/Mod/AddonManager/addonmanager_devmode_licenses_table.py +++ b/src/Mod/AddonManager/addonmanager_devmode_licenses_table.py @@ -46,9 +46,7 @@ class LicensesTable: os.path.join(os.path.dirname(__file__), "developer_mode_licenses_table.ui") ) - self.widget.addButton.setIcon( - QIcon.fromTheme("add", QIcon(":/icons/list-add.svg")) - ) + self.widget.addButton.setIcon(QIcon.fromTheme("add", QIcon(":/icons/list-add.svg"))) self.widget.removeButton.setIcon( QIcon.fromTheme("remove", QIcon(":/icons/list-remove.svg")) ) diff --git a/src/Mod/AddonManager/addonmanager_devmode_metadata_checker.py b/src/Mod/AddonManager/addonmanager_devmode_metadata_checker.py index 62fec3dabb..6f58721687 100644 --- a/src/Mod/AddonManager/addonmanager_devmode_metadata_checker.py +++ b/src/Mod/AddonManager/addonmanager_devmode_metadata_checker.py @@ -75,9 +75,7 @@ class MetadataValidators: errors.extend(self.validate_content(addon)) if len(errors) > 0: - FreeCAD.Console.PrintError( - f"Errors found in package.xml file for '{addon.name}'\n" - ) + FreeCAD.Console.PrintError(f"Errors found in package.xml file for '{addon.name}'\n") for error in errors: FreeCAD.Console.PrintError(f" * {error}\n") @@ -111,17 +109,12 @@ class MetadataValidators: """Check for the presence of the required top-level elements""" errors = [] if not addon.metadata.name or len(addon.metadata.name) == 0: - errors.append( - "No top-level element found, or element is empty" - ) + errors.append("No top-level element found, or element is empty") if not addon.metadata.version: - errors.append( - "No top-level element found, or element is invalid" - ) + errors.append("No top-level element found, or element is invalid") if not addon.metadata.description or len(addon.metadata.description) == 0: errors.append( - "No top-level element found, or element " - "is invalid" + "No top-level element found, or element " "is invalid" ) maintainers = addon.metadata.maintainer @@ -129,9 +122,7 @@ class MetadataValidators: errors.append("No top-level found, at least one is required") for maintainer in maintainers: if len(maintainer.email) == 0: - errors.append( - f"No email address specified for maintainer '{maintainer.name}'" - ) + errors.append(f"No email address specified for maintainer '{maintainer.name}'") licenses = addon.metadata.license if len(licenses) == 0: @@ -146,9 +137,7 @@ class MetadataValidators: """Check the URLs provided by the addon""" errors = [] if len(urls) == 0: - errors.append( - "No elements found, at least a repo url must be provided" - ) + errors.append("No elements found, at least a repo url must be provided") else: found_repo = False found_readme = False @@ -156,17 +145,13 @@ class MetadataValidators: if url["type"] == "repository": found_repo = True if len(url["branch"]) == 0: - errors.append( - " element is missing the 'branch' attribute" - ) + errors.append(" element is missing the 'branch' attribute") elif url["type"] == "readme": found_readme = True location = url["location"] p = NetworkManager.AM_NETWORK_MANAGER.blocking_get(location) if not p: - errors.append( - f"Could not access specified readme at {location}" - ) + errors.append(f"Could not access specified readme at {location}") else: p = p.data().decode("utf8") if "" in p: @@ -179,9 +164,7 @@ class MetadataValidators: if not found_repo: errors.append("No repo url specified") if not found_readme: - errors.append( - "No readme url specified (not required, but highly recommended)" - ) + errors.append("No readme url specified (not required, but highly recommended)") return errors @staticmethod diff --git a/src/Mod/AddonManager/addonmanager_devmode_people_table.py b/src/Mod/AddonManager/addonmanager_devmode_people_table.py index cdd661362f..e6caca269a 100644 --- a/src/Mod/AddonManager/addonmanager_devmode_people_table.py +++ b/src/Mod/AddonManager/addonmanager_devmode_people_table.py @@ -47,9 +47,7 @@ class PeopleTable: os.path.join(os.path.dirname(__file__), "developer_mode_people_table.ui") ) - self.widget.addButton.setIcon( - QIcon.fromTheme("add", QIcon(":/icons/list-add.svg")) - ) + self.widget.addButton.setIcon(QIcon.fromTheme("add", QIcon(":/icons/list-add.svg"))) self.widget.removeButton.setIcon( QIcon.fromTheme("remove", QIcon(":/icons/list-remove.svg")) ) diff --git a/src/Mod/AddonManager/addonmanager_devmode_person_editor.py b/src/Mod/AddonManager/addonmanager_devmode_person_editor.py index 1086a7767f..4c1fbda24c 100644 --- a/src/Mod/AddonManager/addonmanager_devmode_person_editor.py +++ b/src/Mod/AddonManager/addonmanager_devmode_person_editor.py @@ -46,9 +46,7 @@ class PersonEditor: self.dialog.comboBox.addItem( translate("AddonsInstaller", "Maintainer"), userData="maintainer" ) - self.dialog.comboBox.addItem( - translate("AddonsInstaller", "Author"), userData="author" - ) + self.dialog.comboBox.addItem(translate("AddonsInstaller", "Author"), userData="author") def exec(self) -> Tuple[str, str, str]: """Run the dialog, and return a tuple of the person's record type, their name, and their @@ -63,15 +61,11 @@ class PersonEditor: ) return "", "", "" - def setup( - self, person_type: str = "maintainer", name: str = "", email: str = "" - ) -> None: + def setup(self, person_type: str = "maintainer", name: str = "", email: str = "") -> None: """Configure the dialog""" index = self.dialog.comboBox.findData(person_type) if index == -1: - FreeCAD.Console.PrintWarning( - f"Internal Error: unrecognized person type {person_type}" - ) + FreeCAD.Console.PrintWarning(f"Internal Error: unrecognized person type {person_type}") index = 0 self.dialog.comboBox.setCurrentIndex(index) self.dialog.nameLineEdit.setText(name) diff --git a/src/Mod/AddonManager/addonmanager_devmode_validators.py b/src/Mod/AddonManager/addonmanager_devmode_validators.py index baa5168944..000f2aaefc 100644 --- a/src/Mod/AddonManager/addonmanager_devmode_validators.py +++ b/src/Mod/AddonManager/addonmanager_devmode_validators.py @@ -87,9 +87,7 @@ class PythonIdentifierValidator(QValidator): return QValidator.Invalid # Includes an illegal character of some sort if keyword.iskeyword(value): - return ( - QValidator.Intermediate - ) # They can keep typing and it might become valid + return QValidator.Intermediate # They can keep typing and it might become valid return QValidator.Acceptable diff --git a/src/Mod/AddonManager/addonmanager_firstrun.py b/src/Mod/AddonManager/addonmanager_firstrun.py index 858ed90751..eeaa4bc6c6 100644 --- a/src/Mod/AddonManager/addonmanager_firstrun.py +++ b/src/Mod/AddonManager/addonmanager_firstrun.py @@ -84,9 +84,7 @@ class FirstRunDialog: if warning_dialog.exec() == QtWidgets.QDialog.Accepted: self.readWarning = True self.pref.SetBool("readWarning2022", True) - self.pref.SetBool( - "AutoCheck", warning_dialog.checkBoxAutoCheck.isChecked() - ) + self.pref.SetBool("AutoCheck", warning_dialog.checkBoxAutoCheck.isChecked()) self.pref.SetBool( "DownloadMacros", warning_dialog.checkBoxDownloadMacroMetadata.isChecked(), diff --git a/src/Mod/AddonManager/addonmanager_git.py b/src/Mod/AddonManager/addonmanager_git.py index bd89f9f292..9d44388948 100644 --- a/src/Mod/AddonManager/addonmanager_git.py +++ b/src/Mod/AddonManager/addonmanager_git.py @@ -107,9 +107,7 @@ class GitManager: + "...\n" ) remote = self.get_remote(local_path) - with open( - os.path.join(local_path, "ADDON_DISABLED"), "w", encoding="utf-8" - ) as f: + with open(os.path.join(local_path, "ADDON_DISABLED"), "w", encoding="utf-8") as f: f.write( "This is a backup of an addon that failed to update cleanly so " "was re-cloned. It was disabled by the Addon Manager's git update " @@ -185,9 +183,7 @@ class GitManager: # branch = self._synchronous_call_git(["branch", "--show-current"]).strip() # This is more universal (albeit more opaque to the reader): - branch = self._synchronous_call_git( - ["rev-parse", "--abbrev-ref", "HEAD"] - ).strip() + branch = self._synchronous_call_git(["rev-parse", "--abbrev-ref", "HEAD"]).strip() except GitFailed as e: os.chdir(old_dir) raise e @@ -213,9 +209,9 @@ class GitManager: self.clone(remote, local_path) except GitFailed as e: fci.Console.PrintError( - translate( - "AddonsInstaller", "Failed to clone {} into {} using git" - ).format(remote, local_path) + translate("AddonsInstaller", "Failed to clone {} into {} using git").format( + remote, local_path + ) ) os.chdir(original_cwd) raise e @@ -242,9 +238,7 @@ class GitManager: if len(segments) == 3: result = segments[1] break - fci.Console.PrintWarning( - "Error parsing the results from git remote -v show:\n" - ) + fci.Console.PrintWarning("Error parsing the results from git remote -v show:\n") fci.Console.PrintWarning(line + "\n") os.chdir(old_dir) return result @@ -254,9 +248,7 @@ class GitManager: old_dir = os.getcwd() os.chdir(local_path) try: - stdout = self._synchronous_call_git( - ["branch", "-a", "--format=%(refname:lstrip=2)"] - ) + stdout = self._synchronous_call_git(["branch", "-a", "--format=%(refname:lstrip=2)"]) except GitFailed as e: os.chdir(old_dir) raise e @@ -273,12 +265,8 @@ class GitManager: """ old_dir = os.getcwd() os.chdir(local_path) - authors = self._synchronous_call_git(["log", f"-{n}", "--format=%cN"]).split( - "\n" - ) - emails = self._synchronous_call_git(["log", f"-{n}", "--format=%cE"]).split( - "\n" - ) + authors = self._synchronous_call_git(["log", f"-{n}", "--format=%cN"]).split("\n") + emails = self._synchronous_call_git(["log", f"-{n}", "--format=%cE"]).split("\n") os.chdir(old_dir) result_dict = {} diff --git a/src/Mod/AddonManager/addonmanager_macro.py b/src/Mod/AddonManager/addonmanager_macro.py index d7bdbdc20d..c133a0a9b3 100644 --- a/src/Mod/AddonManager/addonmanager_macro.py +++ b/src/Mod/AddonManager/addonmanager_macro.py @@ -116,9 +116,7 @@ class Macro: return False return os.path.exists( os.path.join(fci.DataPaths().macro_dir, self.filename) - ) or os.path.exists( - os.path.join(fci.DataPaths().macro_dir, "Macro_" + self.filename) - ) + ) or os.path.exists(os.path.join(fci.DataPaths().macro_dir, "Macro_" + self.filename)) def fill_details_from_file(self, filename: str) -> None: """Opens the given Macro file and parses it for its metadata""" @@ -160,8 +158,7 @@ class Macro: code = self._read_code_from_wiki(p) if not code: self._console.PrintWarning( - translate("AddonsInstaller", "Unable to fetch the code of this macro.") - + "\n" + translate("AddonsInstaller", "Unable to fetch the code of this macro.") + "\n" ) return @@ -312,9 +309,7 @@ class Macro: f.write(self.xpm) if self.icon: if os.path.isabs(self.icon): - dst_file = os.path.normpath( - os.path.join(macro_dir, os.path.basename(self.icon)) - ) + dst_file = os.path.normpath(os.path.join(macro_dir, os.path.basename(self.icon))) try: shutil.copy(self.icon, dst_file) except OSError: @@ -340,9 +335,7 @@ class Macro: return False if os.path.isabs(other_file): src_file = other_file - dst_file = os.path.normpath( - os.path.join(macro_dir, os.path.basename(other_file)) - ) + dst_file = os.path.normpath(os.path.join(macro_dir, os.path.basename(other_file))) else: src_file = os.path.normpath(os.path.join(base_dir, other_file)) dst_file = os.path.normpath(os.path.join(macro_dir, other_file)) @@ -409,9 +402,7 @@ class Macro: icon_regex = re.compile(r'.*img.*?src="(.*?)"', re.IGNORECASE) if wiki_icon.startswith("http"): # It's a File: wiki link. We can load THAT page and get the image from it... - self._console.PrintLog( - f"Found a File: link for macro {self.name} -- {wiki_icon}\n" - ) + self._console.PrintLog(f"Found a File: link for macro {self.name} -- {wiki_icon}\n") p = Macro.blocking_get(wiki_icon) if p: p = p.decode("utf8") diff --git a/src/Mod/AddonManager/addonmanager_macro_parser.py b/src/Mod/AddonManager/addonmanager_macro_parser.py index 947fe2644f..86d829bbe7 100644 --- a/src/Mod/AddonManager/addonmanager_macro_parser.py +++ b/src/Mod/AddonManager/addonmanager_macro_parser.py @@ -68,9 +68,7 @@ class MacroParser: } self.remaining_item_map = {} self.console = None if FreeCAD is None else FreeCAD.Console - self.current_thread = ( - DummyThread() if QtCore is None else QtCore.QThread.currentThread() - ) + self.current_thread = DummyThread() if QtCore is None else QtCore.QThread.currentThread() if code: self.fill_details_from_code(code) @@ -177,9 +175,7 @@ class MacroParser: stripped_of_quotes = None if line.startswith('"""') and line.endswith('"""'): stripped_of_quotes = line[3:-3] - elif (line[0] == '"' and line[-1] == '"') or ( - line[0] == "'" and line[-1] == "'" - ): + elif (line[0] == '"' and line[-1] == '"') or (line[0] == "'" and line[-1] == "'"): stripped_of_quotes = line[1:-1] return stripped_of_quotes @@ -197,9 +193,7 @@ class MacroParser: def _cleanup_comment(self): """Remove HTML from the comment line, and truncate it at 512 characters.""" - self.parse_results["comment"] = re.sub( - "<.*?>", "", self.parse_results["comment"] - ) + self.parse_results["comment"] = re.sub("<.*?>", "", self.parse_results["comment"]) if len(self.parse_results["comment"]) > 512: self.parse_results["comment"] = self.parse_results["comment"][:511] + "…" diff --git a/src/Mod/AddonManager/addonmanager_uninstaller.py b/src/Mod/AddonManager/addonmanager_uninstaller.py index 94082753a5..b83c8085f2 100644 --- a/src/Mod/AddonManager/addonmanager_uninstaller.py +++ b/src/Mod/AddonManager/addonmanager_uninstaller.py @@ -163,17 +163,13 @@ class AddonUninstaller(QObject): lines = f.readlines() for line in lines: stripped = line.strip() - if ( - len(stripped) > 0 - and stripped[0] != "#" - and os.path.exists(stripped) - ): + if len(stripped) > 0 and stripped[0] != "#" and os.path.exists(stripped): try: os.unlink(stripped) fci.Console.PrintMessage( - translate( - "AddonsInstaller", "Removed extra installed file {}" - ).format(stripped) + translate("AddonsInstaller", "Removed extra installed file {}").format( + stripped + ) + "\n" ) except FileNotFoundError: @@ -266,9 +262,7 @@ class MacroUninstaller(QObject): if self.addon_to_remove.macro.icon: files_to_remove.append(self.addon_to_remove.macro.icon) if self.addon_to_remove.macro.xpm: - files_to_remove.append( - self.addon_to_remove.macro.name.replace(" ", "_") + "_icon.xpm" - ) + files_to_remove.append(self.addon_to_remove.macro.name.replace(" ", "_") + "_icon.xpm") for f in self.addon_to_remove.macro.other_files: files_to_remove.append(f) return files_to_remove diff --git a/src/Mod/AddonManager/addonmanager_uninstaller_gui.py b/src/Mod/AddonManager/addonmanager_uninstaller_gui.py index aea3fc6b4c..86f6b9a942 100644 --- a/src/Mod/AddonManager/addonmanager_uninstaller_gui.py +++ b/src/Mod/AddonManager/addonmanager_uninstaller_gui.py @@ -44,10 +44,7 @@ class AddonUninstallerGUI(QtCore.QObject): def __init__(self, addon_to_remove): super().__init__() self.addon_to_remove = addon_to_remove - if ( - hasattr(self.addon_to_remove, "macro") - and self.addon_to_remove.macro is not None - ): + if hasattr(self.addon_to_remove, "macro") and self.addon_to_remove.macro is not None: self.uninstaller = MacroUninstaller(self.addon_to_remove) else: self.uninstaller = AddonUninstaller(self.addon_to_remove) @@ -61,9 +58,7 @@ class AddonUninstallerGUI(QtCore.QObject): self.dialog_timer = QtCore.QTimer() self.dialog_timer.timeout.connect(self._show_progress_dialog) self.dialog_timer.setSingleShot(True) - self.dialog_timer.setInterval( - 1000 - ) # Can override from external (e.g. testing) code + self.dialog_timer.setInterval(1000) # Can override from external (e.g. testing) code def run(self): """Begin the user interaction: asynchronous, only blocks while showing the initial modal @@ -82,9 +77,9 @@ class AddonUninstallerGUI(QtCore.QObject): confirm = QtWidgets.QMessageBox.question( utils.get_main_am_window(), translate("AddonsInstaller", "Confirm remove"), - translate( - "AddonsInstaller", "Are you sure you want to uninstall {}?" - ).format(self.addon_to_remove.display_name), + translate("AddonsInstaller", "Are you sure you want to uninstall {}?").format( + self.addon_to_remove.display_name + ), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel, ) return confirm == QtWidgets.QMessageBox.Yes @@ -93,9 +88,7 @@ class AddonUninstallerGUI(QtCore.QObject): self.progress_dialog = QtWidgets.QMessageBox( QtWidgets.QMessageBox.NoIcon, translate("AddonsInstaller", "Removing Addon"), - translate("AddonsInstaller", "Removing {}").format( - self.addon_to_remove.display_name - ) + translate("AddonsInstaller", "Removing {}").format(self.addon_to_remove.display_name) + "...", QtWidgets.QMessageBox.Cancel, parent=utils.get_main_am_window(), @@ -119,9 +112,7 @@ class AddonUninstallerGUI(QtCore.QObject): QtWidgets.QMessageBox.information( utils.get_main_am_window(), translate("AddonsInstaller", "Uninstall complete"), - translate("AddonInstaller", "Finished removing {}").format( - addon.display_name - ), + translate("AddonInstaller", "Finished removing {}").format(addon.display_name), ) self._finalize() @@ -133,9 +124,7 @@ class AddonUninstallerGUI(QtCore.QObject): QtWidgets.QMessageBox.critical( utils.get_main_am_window(), translate("AddonsInstaller", "Uninstall failed"), - translate("AddonInstaller", "Failed to remove some files") - + ":\n" - + message, + translate("AddonInstaller", "Failed to remove some files") + ":\n" + message, ) self._finalize() diff --git a/src/Mod/AddonManager/addonmanager_update_all_gui.py b/src/Mod/AddonManager/addonmanager_update_all_gui.py index 3c2b09ffc8..49f06a7159 100644 --- a/src/Mod/AddonManager/addonmanager_update_all_gui.py +++ b/src/Mod/AddonManager/addonmanager_update_all_gui.py @@ -130,9 +130,7 @@ class UpdateAllGUI(QtCore.QObject): new_row = self.dialog.tableWidget.rowCount() self.dialog.tableWidget.setColumnCount(2) self.dialog.tableWidget.setRowCount(new_row + 1) - self.dialog.tableWidget.setItem( - new_row, 0, QtWidgets.QTableWidgetItem(addon.display_name) - ) + self.dialog.tableWidget.setItem(new_row, 0, QtWidgets.QTableWidgetItem(addon.display_name)) self.dialog.tableWidget.setItem(new_row, 1, QtWidgets.QTableWidgetItem("")) self.row_map[addon.name] = new_row @@ -144,9 +142,7 @@ class UpdateAllGUI(QtCore.QObject): """Grab the next addon in the list and start its updater.""" if self.addons_with_update: addon = self.addons_with_update.pop(0) - self.in_process_row = ( - self.row_map[addon.name] if addon.name in self.row_map else None - ) + self.in_process_row = self.row_map[addon.name] if addon.name in self.row_map else None self._update_addon_status(self.in_process_row, AddonStatus.INSTALLING) self.dialog.tableWidget.scrollToItem( self.dialog.tableWidget.item(self.in_process_row, 0) diff --git a/src/Mod/AddonManager/addonmanager_workers_installation.py b/src/Mod/AddonManager/addonmanager_workers_installation.py index 86ef41a30d..e1bcf1c226 100644 --- a/src/Mod/AddonManager/addonmanager_workers_installation.py +++ b/src/Mod/AddonManager/addonmanager_workers_installation.py @@ -76,9 +76,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread): NetworkManager.AM_NETWORK_MANAGER.completed.connect(self.download_completed) self.requests_completed = 0 self.total_requests = 0 - self.store = os.path.join( - FreeCAD.getUserCachePath(), "AddonManager", "PackageMetadata" - ) + self.store = os.path.join(FreeCAD.getUserCachePath(), "AddonManager", "PackageMetadata") FreeCAD.Console.PrintLog(f"Storing Addon Manager cache data in {self.store}\n") self.updated_repos = set() @@ -122,9 +120,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread): while self.requests: if current_thread.isInterruptionRequested(): - NetworkManager.AM_NETWORK_MANAGER.completed.disconnect( - self.download_completed - ) + NetworkManager.AM_NETWORK_MANAGER.completed.disconnect(self.download_completed) for request in self.requests: NetworkManager.AM_NETWORK_MANAGER.abort(request) return @@ -137,9 +133,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread): for repo in self.updated_repos: self.package_updated.emit(repo) - def download_completed( - self, index: int, code: int, data: QtCore.QByteArray - ) -> None: + def download_completed(self, index: int, code: int, data: QtCore.QByteArray) -> None: """Callback for handling a completed metadata file download.""" if index in self.requests: self.requests_completed += 1 @@ -151,9 +145,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread): self.process_package_xml(request[0], data) elif request[1] == UpdateMetadataCacheWorker.RequestType.METADATA_TXT: self.process_metadata_txt(request[0], data) - elif ( - request[1] == UpdateMetadataCacheWorker.RequestType.REQUIREMENTS_TXT - ): + elif request[1] == UpdateMetadataCacheWorker.RequestType.REQUIREMENTS_TXT: self.process_requirements_txt(request[0], data) elif request[1] == UpdateMetadataCacheWorker.RequestType.ICON: self.process_icon(request[0], data) @@ -171,9 +163,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread): repo.set_metadata(metadata) FreeCAD.Console.PrintLog(f"Downloaded package.xml for {repo.name}\n") self.status_message.emit( - translate("AddonsInstaller", "Downloaded package.xml for {}").format( - repo.name - ) + translate("AddonsInstaller", "Downloaded package.xml for {}").format(repo.name) ) # Grab a new copy of the icon as well: we couldn't enqueue this earlier because @@ -220,9 +210,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread): def process_metadata_txt(self, repo: Addon, data: QtCore.QByteArray): """Process the metadata.txt metadata file""" self.status_message.emit( - translate("AddonsInstaller", "Downloaded metadata.txt for {}").format( - repo.display_name - ) + translate("AddonsInstaller", "Downloaded metadata.txt for {}").format(repo.display_name) ) f = self._decode_data(data.data(), repo.name, "metadata.txt") @@ -283,9 +271,7 @@ class UpdateMetadataCacheWorker(QtCore.QThread): def process_icon(self, repo: Addon, data: QtCore.QByteArray): """Convert icon data into a valid icon file and store it""" self.status_message.emit( - translate("AddonsInstaller", "Downloaded icon for {}").format( - repo.display_name - ) + translate("AddonsInstaller", "Downloaded icon for {}").format(repo.display_name) ) cache_file = repo.get_cached_icon_filename() with open(cache_file, "wb") as icon_file: diff --git a/src/Mod/AddonManager/addonmanager_workers_startup.py b/src/Mod/AddonManager/addonmanager_workers_startup.py index d7b7cac30b..a6a8e986b1 100644 --- a/src/Mod/AddonManager/addonmanager_workers_startup.py +++ b/src/Mod/AddonManager/addonmanager_workers_startup.py @@ -162,9 +162,7 @@ class CreateAddonListWorker(QtCore.QThread): for addon in addon_list: if " " in addon: addon_and_branch = addon.split(" ") - custom_addons.append( - {"url": addon_and_branch[0], "branch": addon_and_branch[1]} - ) + custom_addons.append({"url": addon_and_branch[0], "branch": addon_and_branch[1]}) else: custom_addons.append({"url": addon, "branch": "master"}) for addon in custom_addons: @@ -178,9 +176,9 @@ class CreateAddonListWorker(QtCore.QThread): if name in self.package_names: # We already have something with this name, skip this one FreeCAD.Console.PrintWarning( - translate( - "AddonsInstaller", "WARNING: Duplicate addon {} ignored" - ).format(name) + translate("AddonsInstaller", "WARNING: Duplicate addon {} ignored").format( + name + ) ) continue FreeCAD.Console.PrintLog( @@ -251,9 +249,7 @@ class CreateAddonListWorker(QtCore.QThread): repo.obsolete = True self.addon_repo.emit(repo) - self.status_message.emit( - translate("AddonsInstaller", "Workbenches list was updated.") - ) + self.status_message.emit(translate("AddonsInstaller", "Workbenches list was updated.")) def _retrieve_macros_from_git(self): """Retrieve macros from FreeCAD-macros.git @@ -338,8 +334,7 @@ class CreateAddonListWorker(QtCore.QThread): ) FreeCAD.Console.PrintMessage(f"{macro_cache_location}\n") FreeCAD.Console.PrintMessage( - translate("AddonsInstaller", "Attempting to do a clean checkout...") - + "\n" + translate("AddonsInstaller", "Attempting to do a clean checkout...") + "\n" ) try: os.chdir( @@ -459,13 +454,9 @@ class LoadPackagesFromCacheWorker(QtCore.QThread): try: repo.load_metadata_file(repo_metadata_cache_path) repo.installed_version = repo.metadata.version - repo.updated_timestamp = os.path.getmtime( - repo_metadata_cache_path - ) + repo.updated_timestamp = os.path.getmtime(repo_metadata_cache_path) except Exception as e: - FreeCAD.Console.PrintLog( - f"Failed loading {repo_metadata_cache_path}\n" - ) + FreeCAD.Console.PrintLog(f"Failed loading {repo_metadata_cache_path}\n") FreeCAD.Console.PrintLog(str(e) + "\n") self.addon_repo.emit(repo) @@ -612,9 +603,7 @@ class UpdateChecker: wb.set_status(Addon.Status.NO_UPDATE_AVAILABLE) except GitFailed: FreeCAD.Console.PrintWarning( - translate( - "AddonsInstaller", "git status failed for {}" - ).format(wb.name) + translate("AddonsInstaller", "git status failed for {}").format(wb.name) + "\n" ) wb.set_status(Addon.Status.CANNOT_CHECK) @@ -670,9 +659,7 @@ class UpdateChecker: # Make sure this macro has its code downloaded: try: if not macro_wrapper.macro.parsed and macro_wrapper.macro.on_git: - macro_wrapper.macro.fill_details_from_file( - macro_wrapper.macro.src_filename - ) + macro_wrapper.macro.fill_details_from_file(macro_wrapper.macro.src_filename) elif not macro_wrapper.macro.parsed and macro_wrapper.macro.on_wiki: mac = macro_wrapper.macro.name.replace(" ", "_") mac = mac.replace("&", "%26") @@ -694,9 +681,7 @@ class UpdateChecker: hasher2 = hashlib.sha1() hasher1.update(macro_wrapper.macro.code.encode("utf-8")) new_sha1 = hasher1.hexdigest() - test_file_one = os.path.join( - FreeCAD.getUserMacroDir(True), macro_wrapper.macro.filename - ) + test_file_one = os.path.join(FreeCAD.getUserMacroDir(True), macro_wrapper.macro.filename) test_file_two = os.path.join( FreeCAD.getUserMacroDir(True), "Macro_" + macro_wrapper.macro.filename ) @@ -823,9 +808,7 @@ class CacheMacroCodeWorker(QtCore.QThread): if QtCore.QThread.currentThread().isInterruptionRequested(): return - self.progress_made.emit( - len(self.repos) - self.repo_queue.qsize(), len(self.repos) - ) + self.progress_made.emit(len(self.repos) - self.repo_queue.qsize(), len(self.repos)) try: next_repo = self.repo_queue.get_nowait() @@ -886,18 +869,12 @@ class GetMacroDetailsWorker(QtCore.QThread): """Rarely called directly: create an instance and call start() on it instead to launch in a new thread""" - self.status_message.emit( - translate("AddonsInstaller", "Retrieving macro description...") - ) + self.status_message.emit(translate("AddonsInstaller", "Retrieving macro description...")) if not self.macro.parsed and self.macro.on_git: - self.status_message.emit( - translate("AddonsInstaller", "Retrieving info from git") - ) + self.status_message.emit(translate("AddonsInstaller", "Retrieving info from git")) self.macro.fill_details_from_file(self.macro.src_filename) if not self.macro.parsed and self.macro.on_wiki: - self.status_message.emit( - translate("AddonsInstaller", "Retrieving info from wiki") - ) + self.status_message.emit(translate("AddonsInstaller", "Retrieving info from wiki")) mac = self.macro.name.replace(" ", "_") mac = mac.replace("&", "%26") mac = mac.replace("+", "%2B") diff --git a/src/Mod/AddonManager/change_branch.py b/src/Mod/AddonManager/change_branch.py index c31af0915f..332795a22a 100644 --- a/src/Mod/AddonManager/change_branch.py +++ b/src/Mod/AddonManager/change_branch.py @@ -67,18 +67,10 @@ class ChangeBranchDialog(QtWidgets.QWidget): if ref == current_ref: index = self.item_filter.mapFromSource(self.item_model.index(row, 0)) selection_model.select(index, QtCore.QItemSelectionModel.ClearAndSelect) - selection_model.select( - index.siblingAtColumn(1), QtCore.QItemSelectionModel.Select - ) - selection_model.select( - index.siblingAtColumn(2), QtCore.QItemSelectionModel.Select - ) - selection_model.select( - index.siblingAtColumn(3), QtCore.QItemSelectionModel.Select - ) - selection_model.select( - index.siblingAtColumn(4), QtCore.QItemSelectionModel.Select - ) + selection_model.select(index.siblingAtColumn(1), QtCore.QItemSelectionModel.Select) + selection_model.select(index.siblingAtColumn(2), QtCore.QItemSelectionModel.Select) + selection_model.select(index.siblingAtColumn(3), QtCore.QItemSelectionModel.Select) + selection_model.select(index.siblingAtColumn(4), QtCore.QItemSelectionModel.Select) break row += 1 @@ -260,9 +252,7 @@ class ChangeBranchDialogModel(QtCore.QAbstractTableModel): "Table header for git ref type (e.g. either Tag or Branch)", ) elif section == 1: - return translate( - "AddonsInstaller", "Local name", "Table header for git ref name" - ) + return translate("AddonsInstaller", "Local name", "Table header for git ref name") elif section == 2: return translate( "AddonsInstaller", diff --git a/src/Mod/AddonManager/compact_view.py b/src/Mod/AddonManager/compact_view.py index 0548156b71..2f9d549910 100644 --- a/src/Mod/AddonManager/compact_view.py +++ b/src/Mod/AddonManager/compact_view.py @@ -74,7 +74,7 @@ class Ui_CompactView(object): # setupUi def retranslateUi(self, CompactView): -# CompactView.setWindowTitle(QCoreApplication.translate("CompactView", "Form", None)) + # CompactView.setWindowTitle(QCoreApplication.translate("CompactView", "Form", None)) self.labelIcon.setText(QCoreApplication.translate("CompactView", "Icon", None)) self.labelPackageName.setText( QCoreApplication.translate("CompactView", "Package Name", None) diff --git a/src/Mod/AddonManager/expanded_view.py b/src/Mod/AddonManager/expanded_view.py index 79648015e8..f0275c7696 100644 --- a/src/Mod/AddonManager/expanded_view.py +++ b/src/Mod/AddonManager/expanded_view.py @@ -113,7 +113,7 @@ class Ui_ExpandedView(object): # setupUi def retranslateUi(self, ExpandedView): -# ExpandedView.setWindowTitle(QCoreApplication.translate("ExpandedView", "Form", None)) + # ExpandedView.setWindowTitle(QCoreApplication.translate("ExpandedView", "Form", None)) self.labelIcon.setText(QCoreApplication.translate("ExpandedView", "Icon", None)) self.labelPackageName.setText( QCoreApplication.translate("ExpandedView", "

Package Name

", None) diff --git a/src/Mod/AddonManager/install_to_toolbar.py b/src/Mod/AddonManager/install_to_toolbar.py index cda5d07940..d0da236a6b 100644 --- a/src/Mod/AddonManager/install_to_toolbar.py +++ b/src/Mod/AddonManager/install_to_toolbar.py @@ -44,9 +44,7 @@ def ask_to_install_toolbar_button(repo: Addon) -> None: os.path.join(os.path.dirname(__file__), "add_toolbar_button_dialog.ui") ) add_toolbar_button_dialog.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint, True) - add_toolbar_button_dialog.buttonYes.clicked.connect( - lambda: install_toolbar_button(repo) - ) + add_toolbar_button_dialog.buttonYes.clicked.connect(lambda: install_toolbar_button(repo)) add_toolbar_button_dialog.buttonNever.clicked.connect( lambda: pref.SetBool("dontShowAddMacroButtonDialog", True) ) @@ -58,9 +56,7 @@ def check_for_button(repo: Addon) -> bool: command = FreeCADGui.Command.findCustomCommand(repo.macro.filename) if not command: return False - custom_toolbars = FreeCAD.ParamGet( - "User parameter:BaseApp/Workbench/Global/Toolbar" - ) + custom_toolbars = FreeCAD.ParamGet("User parameter:BaseApp/Workbench/Global/Toolbar") toolbar_groups = custom_toolbars.GetGroups() for group in toolbar_groups: toolbar = custom_toolbars.GetGroup(group) @@ -88,9 +84,7 @@ def ask_for_toolbar(repo: Addon, custom_toolbars) -> object: select_toolbar_dialog.comboBox.clear() for group in custom_toolbars: - ref = FreeCAD.ParamGet( - "User parameter:BaseApp/Workbench/Global/Toolbar/" + group - ) + ref = FreeCAD.ParamGet("User parameter:BaseApp/Workbench/Global/Toolbar/" + group) name = ref.GetString("Name", "") if name: select_toolbar_dialog.comboBox.addItem(name) @@ -114,9 +108,7 @@ def ask_for_toolbar(repo: Addon, custom_toolbars) -> object: return None # If none of the above code returned... - custom_toolbar_name = pref.GetString( - "CustomToolbarName", "Auto-Created Macro Toolbar" - ) + custom_toolbar_name = pref.GetString("CustomToolbarName", "Auto-Created Macro Toolbar") toolbar = get_toolbar_with_name(custom_toolbar_name) if not toolbar: # They told us not to ask, but then the toolbar got deleted... ask anyway! @@ -131,9 +123,7 @@ def get_toolbar_with_name(name: str) -> object: top_group = FreeCAD.ParamGet("User parameter:BaseApp/Workbench/Global/Toolbar") custom_toolbars = top_group.GetGroups() for toolbar in custom_toolbars: - group = FreeCAD.ParamGet( - "User parameter:BaseApp/Workbench/Global/Toolbar/" + toolbar - ) + group = FreeCAD.ParamGet("User parameter:BaseApp/Workbench/Global/Toolbar/" + toolbar) group_name = group.GetString("Name", "") if group_name == name: return group @@ -185,9 +175,7 @@ def install_toolbar_button(repo: Addon) -> None: """If the user has requested a toolbar button be installed, this function is called to continue the process and request any additional required information.""" pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons") - custom_toolbar_name = pref.GetString( - "CustomToolbarName", "Auto-Created Macro Toolbar" - ) + custom_toolbar_name = pref.GetString("CustomToolbarName", "Auto-Created Macro Toolbar") # Default to false here: if the variable hasn't been set, we don't assume # that we have to ask, because the simplest is to just create a new toolbar @@ -226,9 +214,7 @@ def install_toolbar_button(repo: Addon) -> None: if custom_toolbar: install_macro_to_toolbar(repo, custom_toolbar) else: - FreeCAD.Console.PrintMessage( - "In the end, no custom toolbar was set, bailing out\n" - ) + FreeCAD.Console.PrintMessage("In the end, no custom toolbar was set, bailing out\n") def install_macro_to_toolbar(repo: Addon, toolbar: object) -> None: @@ -255,9 +241,7 @@ def install_macro_to_toolbar(repo: Addon, toolbar: object) -> None: pixmapText = os.path.normpath(os.path.join(macro_repo_dir, repo.macro.icon)) elif repo.macro.xpm: macro_repo_dir = FreeCAD.getUserMacroDir(True) - icon_file = os.path.normpath( - os.path.join(macro_repo_dir, repo.macro.name + "_icon.xpm") - ) + icon_file = os.path.normpath(os.path.join(macro_repo_dir, repo.macro.name + "_icon.xpm")) with open(icon_file, "w", encoding="utf-8") as f: f.write(repo.macro.xpm) pixmapText = icon_file @@ -288,9 +272,7 @@ def remove_custom_toolbar_button(repo: Addon) -> None: command = FreeCADGui.Command.findCustomCommand(repo.macro.filename) if not command: return - custom_toolbars = FreeCAD.ParamGet( - "User parameter:BaseApp/Workbench/Global/Toolbar" - ) + custom_toolbars = FreeCAD.ParamGet("User parameter:BaseApp/Workbench/Global/Toolbar") toolbar_groups = custom_toolbars.GetGroups() for group in toolbar_groups: toolbar = custom_toolbars.GetGroup(group) diff --git a/src/Mod/AddonManager/manage_python_dependencies.py b/src/Mod/AddonManager/manage_python_dependencies.py index b6541ff681..24108d571a 100644 --- a/src/Mod/AddonManager/manage_python_dependencies.py +++ b/src/Mod/AddonManager/manage_python_dependencies.py @@ -134,12 +134,8 @@ class PythonPackageManager: def process(self): """Execute this object.""" try: - self.all_packages_stdout = call_pip( - ["list", "--path", self.vendor_path] - ) - self.outdated_packages_stdout = call_pip( - ["list", "-o", "--path", self.vendor_path] - ) + self.all_packages_stdout = call_pip(["list", "--path", self.vendor_path]) + self.outdated_packages_stdout = call_pip(["list", "-o", "--path", self.vendor_path]) except PipFailed as e: FreeCAD.Console.PrintError(str(e) + "\n") self.error.emit(str(e)) @@ -197,9 +193,7 @@ class PythonPackageManager: self.dlg.tableWidget.setItem( 0, 0, - QtWidgets.QTableWidgetItem( - translate("AddonsInstaller", "Processing, please wait...") - ), + QtWidgets.QTableWidgetItem(translate("AddonsInstaller", "Processing, please wait...")), ) self.dlg.tableWidget.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.ResizeToContents @@ -230,9 +224,7 @@ class PythonPackageManager: dependencies.append(addon["name"] + "*") else: dependencies.append(addon["name"]) - self.dlg.tableWidget.setItem( - counter, 0, QtWidgets.QTableWidgetItem(package_name) - ) + self.dlg.tableWidget.setItem(counter, 0, QtWidgets.QTableWidgetItem(package_name)) self.dlg.tableWidget.setItem( counter, 1, @@ -249,13 +241,9 @@ class PythonPackageManager: QtWidgets.QTableWidgetItem(", ".join(dependencies)), ) if len(package_details["available_version"]) > 0: - updateButtons.append( - QtWidgets.QPushButton(translate("AddonsInstaller", "Update")) - ) + updateButtons.append(QtWidgets.QPushButton(translate("AddonsInstaller", "Update"))) updateButtons[-1].setIcon(QtGui.QIcon(":/icons/button_up.svg")) - updateButtons[-1].clicked.connect( - partial(self._update_package, package_name) - ) + updateButtons[-1].clicked.connect(partial(self._update_package, package_name)) self.dlg.tableWidget.setCellWidget(counter, 4, updateButtons[-1]) update_counter += 1 else: @@ -292,9 +280,7 @@ class PythonPackageManager: dependent_addons.append({"name": addon.name, "optional": True}) return dependent_addons - def _parse_pip_list_output( - self, all_packages, outdated_packages - ) -> Dict[str, Dict[str, str]]: + def _parse_pip_list_output(self, all_packages, outdated_packages) -> Dict[str, Dict[str, str]]: """Parses the output from pip into a dictionary with update information in it. The pip output should be an array of lines of text.""" @@ -350,17 +336,13 @@ class PythonPackageManager: self.dlg.tableWidget.setItem( line, 2, - QtWidgets.QTableWidgetItem( - translate("AddonsInstaller", "Updating...") - ), + QtWidgets.QTableWidgetItem(translate("AddonsInstaller", "Updating...")), ) break QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents, 50) try: - call_pip( - ["install", "--upgrade", package_name, "--target", self.vendor_path] - ) + call_pip(["install", "--upgrade", package_name, "--target", self.vendor_path]) self._create_list_from_pip() except PipFailed as e: FreeCAD.Console.PrintError(str(e) + "\n") @@ -373,8 +355,7 @@ class PythonPackageManager: for package_name, package_details in package_list.items(): if ( len(package_details["available_version"]) > 0 - and package_details["available_version"] - != package_details["installed_version"] + and package_details["available_version"] != package_details["installed_version"] ): updates.append(package_name) @@ -389,9 +370,7 @@ class PythonPackageManager: migrated = False - old_directory = os.path.join( - FreeCAD.getUserAppDataDir(), "AdditionalPythonPackages" - ) + old_directory = os.path.join(FreeCAD.getUserAppDataDir(), "AdditionalPythonPackages") new_directory = utils.get_pip_target_directory() new_directory_name = new_directory.rsplit(os.path.sep, 1)[1] @@ -420,12 +399,8 @@ class PythonPackageManager: sys.path.append(new_directory) cls._add_current_python_version() - with open( - os.path.join(old_directory, "MIGRATION_COMPLETE"), "w", encoding="utf-8" - ) as f: - f.write( - "Files originally installed in this directory have been migrated to:\n" - ) + with open(os.path.join(old_directory, "MIGRATION_COMPLETE"), "w", encoding="utf-8") as f: + f.write("Files originally installed in this directory have been migrated to:\n") f.write(new_directory) f.write( "\nThe existence of this file prevents the Addon Manager from " diff --git a/src/Mod/AddonManager/package_details.py b/src/Mod/AddonManager/package_details.py index c9d1ae311a..36952b7bd3 100644 --- a/src/Mod/AddonManager/package_details.py +++ b/src/Mod/AddonManager/package_details.py @@ -91,9 +91,7 @@ class PackageDetails(QtWidgets.QWidget): self.ui.buttonInstall.clicked.connect(lambda: self.install.emit(self.repo)) self.ui.buttonUninstall.clicked.connect(lambda: self.uninstall.emit(self.repo)) self.ui.buttonUpdate.clicked.connect(lambda: self.update.emit(self.repo)) - self.ui.buttonCheckForUpdate.clicked.connect( - lambda: self.check_for_update.emit(self.repo) - ) + self.ui.buttonCheckForUpdate.clicked.connect(lambda: self.check_for_update.emit(self.repo)) self.ui.buttonChangeBranch.clicked.connect(self.change_branch_clicked) self.ui.buttonEnable.clicked.connect(self.enable_clicked) self.ui.buttonDisable.clicked.connect(self.disable_clicked) @@ -125,13 +123,9 @@ class PackageDetails(QtWidgets.QWidget): self.ui.webView.setHtml("Loading...") self.ui.webView.hide() self.ui.progressBar.show() - self.timeout = QtCore.QTimer.singleShot( - 6000, self.long_load_running - ) # Six seconds + self.timeout = QtCore.QTimer.singleShot(6000, self.long_load_running) # Six seconds else: - self.ui.missingWebViewLabel.setStyleSheet( - "color:" + utils.warning_color_string() - ) + self.ui.missingWebViewLabel.setStyleSheet("color:" + utils.warning_color_string()) if self.worker is not None: if not self.worker.isFinished(): @@ -157,9 +151,7 @@ class PackageDetails(QtWidgets.QWidget): self.status_create_addon_list_worker.deleteLater ) self.check_for_update.connect(self.status_create_addon_list_worker.do_work) - self.status_create_addon_list_worker.update_status.connect( - self.display_repo_status - ) + self.status_create_addon_list_worker.update_status.connect(self.display_repo_status) self.status_update_thread.start() self.check_for_update.emit(self.repo) @@ -182,9 +174,9 @@ class PackageDetails(QtWidgets.QWidget): ) if version and date: installed_version_string += ( - translate( - "AddonsInstaller", "Version {version} installed on {date}" - ).format(version=version, date=date) + translate("AddonsInstaller", "Version {version} installed on {date}").format( + version=version, date=date + ) + ". " ) elif version: @@ -196,9 +188,7 @@ class PackageDetails(QtWidgets.QWidget): translate("AddonsInstaller", "Installed on {date}") + ". " ).format(date=date) else: - installed_version_string += ( - translate("AddonsInstaller", "Installed") + ". " - ) + installed_version_string += translate("AddonsInstaller", "Installed") + ". " if status == Addon.Status.UPDATE_AVAILABLE: if repo.metadata: @@ -214,9 +204,7 @@ class PackageDetails(QtWidgets.QWidget): installed_version_string += "." elif repo.macro and repo.macro.version: installed_version_string += ( - "" - + translate("AddonsInstaller", "Update available to version") - + " " + "" + translate("AddonsInstaller", "Update available to version") + " " ) installed_version_string += repo.macro.version installed_version_string += "." @@ -258,10 +246,7 @@ class PackageDetails(QtWidgets.QWidget): ) elif status == Addon.Status.PENDING_RESTART: installed_version_string += ( - translate( - "AddonsInstaller", "Updated, please restart FreeCAD to use" - ) - + "." + translate("AddonsInstaller", "Updated, please restart FreeCAD to use") + "." ) elif status == Addon.Status.UNCHECKED: pref = fci.ParamGet("User parameter:BaseApp/Preferences/Addons") @@ -272,20 +257,15 @@ class PackageDetails(QtWidgets.QWidget): ) else: installed_version_string += ( - translate("AddonsInstaller", "Automatic update checks disabled") - + "." + translate("AddonsInstaller", "Automatic update checks disabled") + "." ) installed_version_string += "" self.ui.labelPackageDetails.setText(installed_version_string) if repo.status() == Addon.Status.UPDATE_AVAILABLE: - self.ui.labelPackageDetails.setStyleSheet( - "color:" + utils.attention_color_string() - ) + self.ui.labelPackageDetails.setStyleSheet("color:" + utils.attention_color_string()) else: - self.ui.labelPackageDetails.setStyleSheet( - "color:" + utils.bright_color_string() - ) + self.ui.labelPackageDetails.setStyleSheet("color:" + utils.bright_color_string()) self.ui.labelPackageDetails.show() if repo.macro is not None: @@ -340,13 +320,9 @@ class PackageDetails(QtWidgets.QWidget): if repo.obsolete: self.ui.labelWarningInfo.show() self.ui.labelWarningInfo.setText( - "

" - + translate("AddonsInstaller", "WARNING: This addon is obsolete") - + "

" - ) - self.ui.labelWarningInfo.setStyleSheet( - "color:" + utils.warning_color_string() + "

" + translate("AddonsInstaller", "WARNING: This addon is obsolete") + "

" ) + self.ui.labelWarningInfo.setStyleSheet("color:" + utils.warning_color_string()) elif repo.python2: self.ui.labelWarningInfo.show() self.ui.labelWarningInfo.setText( @@ -354,9 +330,7 @@ class PackageDetails(QtWidgets.QWidget): + translate("AddonsInstaller", "WARNING: This addon is Python 2 Only") + "" ) - self.ui.labelWarningInfo.setStyleSheet( - "color:" + utils.warning_color_string() - ) + self.ui.labelWarningInfo.setStyleSheet("color:" + utils.warning_color_string()) elif required_version: self.ui.labelWarningInfo.show() self.ui.labelWarningInfo.setText( @@ -365,9 +339,7 @@ class PackageDetails(QtWidgets.QWidget): + required_version + "" ) - self.ui.labelWarningInfo.setStyleSheet( - "color:" + utils.warning_color_string() - ) + self.ui.labelWarningInfo.setStyleSheet("color:" + utils.warning_color_string()) elif repo.is_disabled(): self.ui.labelWarningInfo.show() self.ui.labelWarningInfo.setText( @@ -378,9 +350,7 @@ class PackageDetails(QtWidgets.QWidget): ) + "" ) - self.ui.labelWarningInfo.setStyleSheet( - "color:" + utils.warning_color_string() - ) + self.ui.labelWarningInfo.setStyleSheet("color:" + utils.warning_color_string()) else: self.ui.labelWarningInfo.hide() @@ -396,9 +366,7 @@ class PackageDetails(QtWidgets.QWidget): # it's possible that this package actually provides versions of itself # for newer and older versions - first_supported_version = get_first_supported_freecad_version( - self.repo.metadata - ) + first_supported_version = get_first_supported_freecad_version(self.repo.metadata) if first_supported_version is not None: fc_version = Version(from_list=fci.Version()) if first_supported_version > fc_version: @@ -504,9 +472,7 @@ class PackageDetails(QtWidgets.QWidget): else: self.ui.urlBar.setText( "(" - + translate( - "AddonsInstaller", "No URL or wiki page provided by this macro" - ) + + translate("AddonsInstaller", "No URL or wiki page provided by this macro") + ")" ) else: @@ -517,9 +483,7 @@ class PackageDetails(QtWidgets.QWidget): else: self.ui.textBrowserReadMe.setHtml( "(" - + translate( - "AddonsInstaller", "No URL or wiki page provided by this macro" - ) + + translate("AddonsInstaller", "No URL or wiki page provided by this macro") + ")" ) @@ -622,9 +586,9 @@ class PackageDetails(QtWidgets.QWidget): def show_error_for(self, url: QtCore.QUrl) -> None: """Displays error information.""" - m = translate( - "AddonsInstaller", "Could not load README data from URL {}" - ).format(url.toString()) + m = translate("AddonsInstaller", "Could not load README data from URL {}").format( + url.toString() + ) html = f"

{m}

" self.ui.webView.setHtml(html) @@ -670,9 +634,7 @@ class PackageDetails(QtWidgets.QWidget): ) + "" ) - self.ui.labelWarningInfo.setStyleSheet( - "color:" + utils.attention_color_string() - ) + self.ui.labelWarningInfo.setStyleSheet("color:" + utils.attention_color_string()) def branch_changed(self, name: str) -> None: """Displays a dialog confirming the branch changed, and tries to access the @@ -695,9 +657,7 @@ class PackageDetails(QtWidgets.QWidget): self.repo.repo_type = Addon.Kind.WORKBENCH self.repo.metadata = None self.repo.installed_version = None - self.repo.updated_timestamp = ( - QtCore.QDateTime.currentDateTime().toSecsSinceEpoch() - ) + self.repo.updated_timestamp = QtCore.QDateTime.currentDateTime().toSecsSinceEpoch() self.repo.branch = name self.repo.set_status(Addon.Status.PENDING_RESTART) @@ -707,9 +667,7 @@ class PackageDetails(QtWidgets.QWidget): ).format(name) installed_version_string += "" self.ui.labelPackageDetails.setText(installed_version_string) - self.ui.labelPackageDetails.setStyleSheet( - "color:" + utils.attention_color_string() - ) + self.ui.labelPackageDetails.setStyleSheet("color:" + utils.attention_color_string()) self.update_status.emit(self.repo) @@ -738,9 +696,7 @@ if HAS_QTWEBENGINE: requested_url.host() == "wiki.freecad.org" or requested_url.host() == "wiki.freecad.org" ): - return super().acceptNavigationRequest( - requested_url, _type, isMainFrame - ) + return super().acceptNavigationRequest(requested_url, _type, isMainFrame) QtGui.QDesktopServices.openUrl(requested_url) self.stored_url = self.url() QtCore.QTimer.singleShot(0, self._reload_stored_url) @@ -838,9 +794,7 @@ class Ui_PackageDetails(object): self.verticalLayout_2.addWidget(self.labelPackageDetails) self.labelInstallationLocation = QtWidgets.QLabel(PackageDetails) - self.labelInstallationLocation.setTextInteractionFlags( - QtCore.Qt.TextSelectableByMouse - ) + self.labelInstallationLocation.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) self.labelInstallationLocation.hide() self.verticalLayout_2.addWidget(self.labelInstallationLocation) @@ -917,9 +871,7 @@ class Ui_PackageDetails(object): QtCore.QCoreApplication.translate("AddonsInstaller", "Update", None) ) self.buttonCheckForUpdate.setText( - QtCore.QCoreApplication.translate( - "AddonsInstaller", "Check for Update", None - ) + QtCore.QCoreApplication.translate("AddonsInstaller", "Check for Update", None) ) self.buttonExecute.setText( QtCore.QCoreApplication.translate("AddonsInstaller", "Run Macro", None) @@ -934,9 +886,7 @@ class Ui_PackageDetails(object): QtCore.QCoreApplication.translate("AddonsInstaller", "Disable", None) ) self.buttonBack.setToolTip( - QtCore.QCoreApplication.translate( - "AddonsInstaller", "Return to package list", None - ) + QtCore.QCoreApplication.translate("AddonsInstaller", "Return to package list", None) ) if not HAS_QTWEBENGINE: self.missingWebViewLabel.setText( diff --git a/src/Mod/AddonManager/package_list.py b/src/Mod/AddonManager/package_list.py index 8629eaacb2..a9dd3dc598 100644 --- a/src/Mod/AddonManager/package_list.py +++ b/src/Mod/AddonManager/package_list.py @@ -116,9 +116,7 @@ class PackageList(QtWidgets.QWidget): self.item_filter.setHidePy2(pref.GetBool("HidePy2", True)) self.item_filter.setHideObsolete(pref.GetBool("HideObsolete", True)) - self.item_filter.setHideNewerFreeCADRequired( - pref.GetBool("HideNewerFreeCADRequired", True) - ) + self.item_filter.setHideNewerFreeCADRequired(pref.GetBool("HideNewerFreeCADRequired", True)) def on_listPackages_clicked(self, index: QtCore.QModelIndex): """Determine what addon was selected and emit the itemSelected signal with it as @@ -155,9 +153,7 @@ class PackageList(QtWidgets.QWidget): """filter name and description by the regex specified by text_filter""" if text_filter: - if hasattr( - self.item_filter, "setFilterRegularExpression" - ): # Added in Qt 5.12 + if hasattr(self.item_filter, "setFilterRegularExpression"): # Added in Qt 5.12 test_regex = QtCore.QRegularExpression(text_filter) else: test_regex = QtCore.QRegExp(text_filter) @@ -171,9 +167,7 @@ class PackageList(QtWidgets.QWidget): self.ui.labelFilterValidity.setToolTip( translate("AddonsInstaller", "Filter regular expression is invalid") ) - icon = QtGui.QIcon.fromTheme( - "cancel", QtGui.QIcon(":/icons/edit_Cancel.svg") - ) + icon = QtGui.QIcon.fromTheme("cancel", QtGui.QIcon(":/icons/edit_Cancel.svg")) self.ui.labelFilterValidity.setPixmap(icon.pixmap(16, 16)) self.ui.labelFilterValidity.show() else: @@ -227,17 +221,17 @@ class PackageListItemModel(QtCore.QAbstractListModel): if role == QtCore.Qt.ToolTipRole: tooltip = "" if self.repos[row].repo_type == Addon.Kind.PACKAGE: - tooltip = translate( - "AddonsInstaller", "Click for details about package {}" - ).format(self.repos[row].display_name) + tooltip = translate("AddonsInstaller", "Click for details about package {}").format( + self.repos[row].display_name + ) elif self.repos[row].repo_type == Addon.Kind.WORKBENCH: tooltip = translate( "AddonsInstaller", "Click for details about workbench {}" ).format(self.repos[row].display_name) elif self.repos[row].repo_type == Addon.Kind.MACRO: - tooltip = translate( - "AddonsInstaller", "Click for details about macro {}" - ).format(self.repos[row].display_name) + tooltip = translate("AddonsInstaller", "Click for details about macro {}").format( + self.repos[row].display_name + ) return tooltip if role == PackageListItemModel.DataAccessRole: return self.repos[row] @@ -246,9 +240,7 @@ class PackageListItemModel(QtCore.QAbstractListModel): """No header in this implementation: always returns None.""" return None - def setData( - self, index: QtCore.QModelIndex, value, role=QtCore.Qt.EditRole - ) -> None: + def setData(self, index: QtCore.QModelIndex, value, role=QtCore.Qt.EditRole) -> None: """Set the data for this row. The column of the index is ignored.""" row = index.row() @@ -290,18 +282,14 @@ class PackageListItemModel(QtCore.QAbstractListModel): """Set the status of addon with name to status.""" for row, item in enumerate(self.repos): if item.name == name: - self.setData( - self.index(row, 0), status, PackageListItemModel.StatusUpdateRole - ) + self.setData(self.index(row, 0), status, PackageListItemModel.StatusUpdateRole) return def update_item_icon(self, name: str, icon: QtGui.QIcon) -> None: """Set the icon for Addon with name to icon""" for row, item in enumerate(self.repos): if item.name == name: - self.setData( - self.index(row, 0), icon, PackageListItemModel.IconUpdateRole - ) + self.setData(self.index(row, 0), icon, PackageListItemModel.IconUpdateRole) return def reload_item(self, repo: Addon) -> None: @@ -432,9 +420,7 @@ class PackageListItemDelegate(QtWidgets.QStyledItemDelegate): if self.displayStyle == ListDisplayStyle.EXPANDED: if repo.macro.author: caption = translate("AddonsInstaller", "Author") - self.widget.ui.labelMaintainer.setText( - caption + ": " + repo.macro.author - ) + self.widget.ui.labelMaintainer.setText(caption + ": " + repo.macro.author) else: self.widget.ui.labelMaintainer.setText("") @@ -454,14 +440,8 @@ class PackageListItemDelegate(QtWidgets.QStyledItemDelegate): result = translate("AddonsInstaller", "Pending restart") if repo.is_disabled(): - style = ( - "style='color:" + utils.warning_color_string() + "; font-weight:bold;'" - ) - result += ( - f" [" - + translate("AddonsInstaller", "DISABLED") - + "]" - ) + style = "style='color:" + utils.warning_color_string() + "; font-weight:bold;'" + result += f" [" + translate("AddonsInstaller", "DISABLED") + "]" return result @@ -480,15 +460,11 @@ class PackageListItemDelegate(QtWidgets.QStyledItemDelegate): ) installed_version_string += str(repo.installed_version) else: - installed_version_string = "
" + translate( - "AddonsInstaller", "Unknown version" - ) + installed_version_string = "
" + translate("AddonsInstaller", "Unknown version") installed_date_string = "" if repo.updated_timestamp: - installed_date_string = ( - "
" + translate("AddonsInstaller", "Installed on") + ": " - ) + installed_date_string = "
" + translate("AddonsInstaller", "Installed on") + ": " installed_date_string += ( QtCore.QDateTime.fromTime_t(repo.updated_timestamp) .date() @@ -519,13 +495,9 @@ class PackageListItemDelegate(QtWidgets.QStyledItemDelegate): result = translate("AddonsInstaller", "Pending restart") if repo.is_disabled(): - style = ( - "style='color:" + utils.warning_color_string() + "; font-weight:bold;'" - ) + style = "style='color:" + utils.warning_color_string() + "; font-weight:bold;'" result += ( - f"
[" - + translate("AddonsInstaller", "DISABLED") - + "]" + f"
[" + translate("AddonsInstaller", "DISABLED") + "]" ) return result @@ -623,19 +595,11 @@ class PackageListFilter(QtCore.QSortFilterProxyModel): return False # If it's not installed, check to see if it's Py2 only - if ( - data.status() == Addon.Status.NOT_INSTALLED - and self.hide_py2 - and data.python2 - ): + if data.status() == Addon.Status.NOT_INSTALLED and self.hide_py2 and data.python2: return False # If it's not installed, check to see if it's marked obsolete - if ( - data.status() == Addon.Status.NOT_INSTALLED - and self.hide_obsolete - and data.obsolete - ): + if data.status() == Addon.Status.NOT_INSTALLED and self.hide_obsolete and data.obsolete: return False # If it's not installed, check to see if it's for a newer version of FreeCAD @@ -664,11 +628,7 @@ class PackageListFilter(QtCore.QSortFilterProxyModel): return True if re.match(desc).hasMatch(): return True - if ( - data.macro - and data.macro.comment - and re.match(data.macro.comment).hasMatch() - ): + if data.macro and data.macro.comment and re.match(data.macro.comment).hasMatch(): return True for tag in data.tags: if re.match(tag).hasMatch(): @@ -682,11 +642,7 @@ class PackageListFilter(QtCore.QSortFilterProxyModel): return True if re.indexIn(desc) != -1: return True - if ( - data.macro - and data.macro.comment - and re.indexIn(data.macro.comment) != -1 - ): + if data.macro and data.macro.comment and re.indexIn(data.macro.comment) != -1: return True for tag in data.tags: if re.indexIn(tag) != -1: @@ -712,9 +668,7 @@ class Ui_PackageList: self.buttonCompactLayout.setCheckable(True) self.buttonCompactLayout.setAutoExclusive(True) self.buttonCompactLayout.setIcon( - QtGui.QIcon.fromTheme( - "expanded_view", QtGui.QIcon(":/icons/compact_view.svg") - ) + QtGui.QIcon.fromTheme("expanded_view", QtGui.QIcon(":/icons/compact_view.svg")) ) self.horizontalLayout_6.addWidget(self.buttonCompactLayout) @@ -725,9 +679,7 @@ class Ui_PackageList: self.buttonExpandedLayout.setChecked(True) self.buttonExpandedLayout.setAutoExclusive(True) self.buttonExpandedLayout.setIcon( - QtGui.QIcon.fromTheme( - "expanded_view", QtGui.QIcon(":/icons/expanded_view.svg") - ) + QtGui.QIcon.fromTheme("expanded_view", QtGui.QIcon(":/icons/expanded_view.svg")) ) self.horizontalLayout_6.addWidget(self.buttonExpandedLayout) @@ -791,9 +743,7 @@ class Ui_PackageList: def retranslateUi(self, _): self.labelPackagesContaining.setText( - QtCore.QCoreApplication.translate( - "AddonsInstaller", "Show Addons containing:", None - ) + QtCore.QCoreApplication.translate("AddonsInstaller", "Show Addons containing:", None) ) self.comboPackageType.setItemText( 0, QtCore.QCoreApplication.translate("AddonsInstaller", "All", None) @@ -806,9 +756,7 @@ class Ui_PackageList: ) self.comboPackageType.setItemText( 3, - QtCore.QCoreApplication.translate( - "AddonsInstaller", "Preference Packs", None - ), + QtCore.QCoreApplication.translate("AddonsInstaller", "Preference Packs", None), ) self.labelStatus.setText( QtCore.QCoreApplication.translate("AddonsInstaller", "Status:", None) @@ -827,9 +775,7 @@ class Ui_PackageList: ) self.comboStatus.setItemText( StatusFilter.UPDATE_AVAILABLE, - QtCore.QCoreApplication.translate( - "AddonsInstaller", "Update available", None - ), + QtCore.QCoreApplication.translate("AddonsInstaller", "Update available", None), ) self.lineEditFilter.setPlaceholderText( QtCore.QCoreApplication.translate("AddonsInstaller", "Filter", None)