diff -r 08d340b8b7c7 -r b2faf1b237f9 src/eric7/Project/Project.py --- a/src/eric7/Project/Project.py Sun Mar 03 10:35:47 2024 +0100 +++ b/src/eric7/Project/Project.py Sun Mar 03 15:56:25 2024 +0100 @@ -4889,6 +4889,27 @@ self.createSBOMAct.triggered.connect(self.__createSBOMFile) self.actions.append(self.createSBOMAct) + self.clearByteCodeCachesAct = EricAction( + self.tr("Clear Byte Code Caches"), + self.tr("Clear Byte Code &Caches"), + 0, + 0, + self.othersGrp, + "project_clear_bytecode_caches", + ) + self.clearByteCodeCachesAct.setStatusTip( + self.tr("Clear the byte code caches of the project.") + ) + self.clearByteCodeCachesAct.setWhatsThis( + self.tr( + """<b>Clear Byte Code Caches</b>""" + """<p>This deletes all directories containing byte code cache files.""" + """</p>""" + ) + ) + self.clearByteCodeCachesAct.triggered.connect(self.__clearByteCodeCaches) + self.actions.append(self.clearByteCodeCachesAct) + ################################################################### ## Project Tools - code formatting actions - Black ################################################################### @@ -7152,6 +7173,39 @@ # the configuration file does not exist or is invalid JSON self.__initVenvConfiguration() + ######################################################################### + ## Below are methods implementing some tool functionality + ######################################################################### + + @pyqtSlot() + def __clearByteCodeCaches(self, directory=None): + """ + Private method to recursively clear the byte code caches of a given directory. + + Note: The byte code cache directiries are named '__pycache__'. + + @param directory directory name to clear byte code caches from (defaults to + None) + @type str (optional) + """ + if directory is None: + # When directory is 'None', we were called by the QAction. + if self.ppath: + directory = self.ppath + else: + return + + # step 1: delete the __pycache__ directory + cacheDir = os.path.join(directory, "__pycache__") + if os.path.exists(cacheDir): + shutil.rmtree(cacheDir, ignore_errors=True) + + # step 2: descent into subdirectories + with os.scandir(directory) as dirEntriesIterator: + for dirEntry in dirEntriesIterator: + if dirEntry.is_dir(): + self.__clearByteCodeCaches(dirEntry.path) + # # eflag: noqa = M601