eric6/PluginManager/PluginManager.py

branch
maintenance
changeset 8400
b3eefd7e58d1
parent 8273
698ae46f40a4
parent 8396
437fb6ba91bd
equal deleted inserted replaced
8274:197414ba11cc 8400:b3eefd7e58d1
11 import sys 11 import sys
12 import zipfile 12 import zipfile
13 import types 13 import types
14 import importlib 14 import importlib
15 import contextlib 15 import contextlib
16 import logging
16 17
17 from PyQt5.QtCore import ( 18 from PyQt5.QtCore import (
18 pyqtSignal, QObject, QDate, QFile, QFileInfo, QUrl, QIODevice 19 pyqtSignal, QObject, QDate, QFile, QFileInfo, QUrl, QIODevice
19 ) 20 )
20 from PyQt5.QtGui import QPixmap 21 from PyQt5.QtGui import QPixmap
108 109
109 self.__inactivePluginsKey = "PluginManager/InactivePlugins" 110 self.__inactivePluginsKey = "PluginManager/InactivePlugins"
110 111
111 self.pluginDirs = { 112 self.pluginDirs = {
112 "eric6": os.path.join(getConfig('ericDir'), "Plugins"), 113 "eric6": os.path.join(getConfig('ericDir'), "Plugins"),
113 "global": os.path.join(Utilities.getPythonModulesDirectory(), 114 "global": os.path.join(Utilities.getPythonLibraryDirectory(),
114 "eric6plugins"), 115 "eric6plugins"),
115 "user": os.path.join(Utilities.getConfigDir(), "eric6plugins"), 116 "user": os.path.join(Utilities.getConfigDir(), "eric6plugins"),
116 } 117 }
117 self.__priorityOrder = ["eric6", "global", "user"] 118 self.__priorityOrder = ["eric6", "global", "user"]
118 119
377 for pluginName in self.__foundCoreModules: 378 for pluginName in self.__foundCoreModules:
378 # plug-in under development has priority 379 # plug-in under development has priority
379 if pluginName.startswith("PluginDocumentationSets"): 380 if pluginName.startswith("PluginDocumentationSets"):
380 self.loadPlugin(pluginName, self.pluginDirs["eric6"]) 381 self.loadPlugin(pluginName, self.pluginDirs["eric6"])
381 382
382 def loadPlugin(self, name, directory, reload_=False): 383 def loadPlugin(self, name, directory, reload_=False, install=False):
383 """ 384 """
384 Public method to load a plugin module. 385 Public method to load a plugin module.
385 386
386 Initially all modules are inactive. Modules that are requested on 387 Initially all modules are inactive. Modules that are requested on
387 demand are sorted out and are added to the on demand list. Some 388 demand are sorted out and are added to the on demand list. Some
388 basic validity checks are performed as well. Modules failing these 389 basic validity checks are performed as well. Modules failing these
389 checks are added to the failed modules list. 390 checks are added to the failed modules list.
390 391
391 @param name name of the module to be loaded (string) 392 @param name name of the module to be loaded
392 @param directory name of the plugin directory (string) 393 @type str
393 @param reload_ flag indicating to reload the module (boolean) 394 @param directory name of the plugin directory
395 @type str
396 @param reload_ flag indicating to reload the module
397 @type bool
398 @param install flag indicating a load operation as part of an
399 installation process
400 @type bool
394 @exception PluginLoadError raised to indicate an issue loading 401 @exception PluginLoadError raised to indicate an issue loading
395 the plug-in 402 the plug-in
396 """ 403 """
397 try: 404 try:
398 fname = "{0}.py".format(os.path.join(directory, name)) 405 fname = "{0}.py".format(os.path.join(directory, name))
401 sys.modules[module.__name__] = module 408 sys.modules[module.__name__] = module
402 spec.loader.exec_module(module) 409 spec.loader.exec_module(module)
403 if not hasattr(module, "autoactivate"): 410 if not hasattr(module, "autoactivate"):
404 module.error = self.tr( 411 module.error = self.tr(
405 "Module is missing the 'autoactivate' attribute.") 412 "Module is missing the 'autoactivate' attribute.")
413 logging.debug(
414 "{0}: Module is missing the 'autoactivate' attribute."
415 .format(name)
416 )
406 self.__failedModules[name] = module 417 self.__failedModules[name] = module
407 raise PluginLoadError(name) 418 raise PluginLoadError(name)
408 if getattr(module, "autoactivate", False): 419 if getattr(module, "autoactivate", False):
409 self.__inactiveModules[name] = module 420 self.__inactiveModules[name] = module
410 else: 421 else:
414 ): 425 ):
415 module.error = self.tr( 426 module.error = self.tr(
416 "Module is missing the 'pluginType' " 427 "Module is missing the 'pluginType' "
417 "and/or 'pluginTypename' attributes." 428 "and/or 'pluginTypename' attributes."
418 ) 429 )
430 logging.debug(
431 "{0}: Module is missing the 'pluginType' "
432 "and/or 'pluginTypename' attributes."
433 .format(name)
434 )
419 self.__failedModules[name] = module 435 self.__failedModules[name] = module
420 raise PluginLoadError(name) 436 raise PluginLoadError(name)
421 else: 437 else:
422 self.__onDemandInactiveModules[name] = module 438 self.__onDemandInactiveModules[name] = module
423 module.eric6PluginModuleName = name 439 module.eric6PluginModuleName = name
424 module.eric6PluginModuleFilename = fname 440 module.eric6PluginModuleFilename = fname
441 if install and hasattr(module, "installDependencies"):
442 # ask the module to install its dependencies
443 module.installDependencies(self.pipInstall)
425 self.__modulesCount += 1 444 self.__modulesCount += 1
426 if reload_: 445 if reload_:
427 importlib.reload(module) 446 importlib.reload(module)
428 self.initOnDemandPlugin(name) 447 self.initOnDemandPlugin(name)
429 with contextlib.suppress(KeyError, AttributeError): 448 with contextlib.suppress(KeyError, AttributeError):
434 print("Error loading plug-in module:", name) 453 print("Error loading plug-in module:", name)
435 except Exception as err: 454 except Exception as err:
436 module = types.ModuleType(name) 455 module = types.ModuleType(name)
437 module.error = self.tr( 456 module.error = self.tr(
438 "Module failed to load. Error: {0}").format(str(err)) 457 "Module failed to load. Error: {0}").format(str(err))
458 logging.debug(
459 "{0}: Module failed to load. Error: {1}"
460 .format(name, str(err))
461 )
439 self.__failedModules[name] = module 462 self.__failedModules[name] = module
440 print("Error loading plug-in module:", name) 463 print("Error loading plug-in module:", name)
441 print(str(err)) 464 print(str(err))
442 465
443 def unloadPlugin(self, name): 466 def unloadPlugin(self, name):
611 try: 634 try:
612 obj, ok = pluginObject.activate() 635 obj, ok = pluginObject.activate()
613 except TypeError: 636 except TypeError:
614 module.error = self.tr( 637 module.error = self.tr(
615 "Incompatible plugin activation method.") 638 "Incompatible plugin activation method.")
639 logging.debug(
640 "{0}: Incompatible plugin activation method."
641 .format(name)
642 )
616 obj = None 643 obj = None
617 ok = True 644 ok = True
618 except Exception as err: 645 except Exception as err:
619 module.error = str(err) 646 module.error = str(err)
647 logging.debug("{0}: {1}".format(name, str(err)))
620 obj = None 648 obj = None
621 ok = False 649 ok = False
622 if not ok: 650 if not ok:
623 return None 651 return None
624 652
1414 if ( 1442 if (
1415 getattr(module, "pluginType", "") == type_ and 1443 getattr(module, "pluginType", "") == type_ and
1416 hasattr(module, "clearPrivateData") 1444 hasattr(module, "clearPrivateData")
1417 ): 1445 ):
1418 module.clearPrivateData() 1446 module.clearPrivateData()
1447
1448 ########################################################################
1449 ## Methods to install a plug-in module dependency via pip
1450 ########################################################################
1451
1452 def pipInstall(self, packages):
1453 """
1454 Public method to install the given package via pip.
1455
1456 @param packages list of packages to install
1457 @type list of str
1458 """
1459 try:
1460 pip = e5App().getObject("Pip")
1461 except KeyError:
1462 # Installation is performed via the plug-in installation script.
1463 from PipInterface.Pip import Pip
1464 pip = Pip(self)
1465 pip.installPackages(packages, interpreter=sys.executable)
1419 1466
1420 # 1467 #
1421 # eflag: noqa = M801 1468 # eflag: noqa = M801

eric ide

mercurial