def update_data(data_ext, data_rep, pkg): """Update the entry point data with current install state. This update is IN PLACE for both data_ext and data_rep. Uses 'pkg' as the main key for associating the data with the relevant package. """ eps_ext = ilmd.entry_points().get("flake8.extension", {}) eps_rep = ilmd.entry_points().get("flake8.report", {}) try: version = canonicalize_version(ilmd.version(pkg)) summary = ilmd.metadata(pkg).get("Summary") except ilmd.PackageNotFoundError: version = canonicalize_version("0.0") summary = "[no summary]" for data, eps in zip((data_ext, data_rep), (eps_ext, eps_rep)): data.update( { pkg: { "version": version, "summary": summary, "eps": { ep.name: { "module": (val := ep.value.partition(":"))[0], "callable": val[2], } for ep in eps }, } } )
def entrypoints(namespace): """Return setuptools entrypoints for namespace.""" if sys.version_info >= (3, 10): entry_points = importlib_metadata.entry_points(group=namespace) else: entry_points = importlib_metadata.entry_points().get(namespace, []) return ((ep, ep.load()) for ep in entry_points)
def list_engines(): # New selection mechanism introduced with Python 3.10. See GH6514. if sys.version_info >= (3, 10): entrypoints = entry_points(group="xarray.backends") else: entrypoints = entry_points().get("xarray.backends", ()) return build_engines(entrypoints)
def test_entry_points_groups_getitem(self): # Prior versions of entry_points() returned a dict. Ensure # that callers using '.__getitem__()' are supported but warned to # migrate. with suppress_known_deprecation(): entry_points()['entries'] == entry_points(group='entries') with self.assertRaises(KeyError): entry_points()['missing']
def get_entry_points(): try: eps = importlib_metadata.entry_points(group="hypothesis") except TypeError: # Load-time selection requires Python >= 3.10 or importlib_metadata >= 3.6, # so we'll retain this fallback logic for some time to come. See also # https://importlib-metadata.readthedocs.io/en/latest/using.html eps = importlib_metadata.entry_points().get("hypothesis", []) yield from eps
def test_entry_points_groups_getitem(self): """ Prior versions of entry_points() returned a dict. Ensure that callers using '.__getitem__()' are supported but warned to migrate. """ with warnings.catch_warnings(record=True): entry_points()['entries'] == entry_points(group='entries') with self.assertRaises(KeyError): entry_points()['missing']
def load_modules(app=None): logger = logging.getLogger("karp") if not entry_points().get("karp.webapp"): logger.info("No webapp modules to load.") return for ep in entry_points()["karp.webapp"]: logger.info("Loading webapp module: %s", ep.name) mod = ep.load() if app: init_app = getattr(mod, "init_app", None) if init_app: init_app(app)
def load_commands(app=None): if not entry_points().get("karp.clicommands"): print("No cli modules to load.") return for ep in entry_points()["karp.clicommands"]: _logger.info("Loading cli module: %s", ep.name) print("Loading cli module: %s" % ep.name) mod = ep.load() if app: init_app = getattr(mod, "init_app", None) if init_app: init_app(app)
def get_all_markups() -> List[Type[AbstractMarkup]]: """ :returns: list of all markups (both standard and custom ones) """ try: from importlib.metadata import entry_points except ImportError: # backport for older Python versions from importlib_metadata import entry_points try: # Python 3.10+ or importlib_metadata 3.6+ entrypoints = entry_points(group="pymarkups") except TypeError: # Older versions entrypoints = entry_points()["pymarkups"] return [entry_point.load() for entry_point in entrypoints]
def test_core_plugins(self): # test that we can see appropriate core entrypoints # This compatibility layer can be removed when we drop support for # Python < 3.10. Ref https://github.com/enthought/pyface/issues/999. all_entry_points = entry_points() if hasattr(all_entry_points, "select"): plugins = { ep.name for ep in entry_points().select(group='pyface.toolkits') } else: plugins = {ep.name for ep in entry_points()['pyface.toolkits']} self.assertLessEqual({"qt4", "wx", "qt", "null"}, plugins)
def plugin_entrypoints(group="psyplot", name="name"): """This utility function gets the entry points of the psyplot plugins""" if sys.version_info[:2] > (3, 7): from importlib.metadata import entry_points try: eps = entry_points(group=group, name=name) except TypeError: # python<3.10 eps = [ ep for ep in entry_points().get(group, []) if ep.name == name ] else: from pkg_resources import iter_entry_points eps = iter_entry_points(group=group, name=name) return eps
def test_entry_points_dict_construction(self): # Prior versions of entry_points() returned simple lists and # allowed casting those lists into maps by name using ``dict()``. # Capture this now deprecated use-case. with suppress_known_deprecation() as caught: eps = dict(entry_points(group='entries')) assert 'main' in eps assert eps['main'] == entry_points(group='entries')['main'] # check warning expected = next(iter(caught)) assert expected.category is DeprecationWarning assert "Construction of dict of EntryPoints is deprecated" in str( expected)
def test_entry_points_unique_packages(self): """ Entry points should only be exposed for the first package on sys.path with a given name. """ alt_site_dir = self.fixtures.enter_context(fixtures.tempdir()) self.fixtures.enter_context(self.add_sys_path(alt_site_dir)) alt_pkg = { "distinfo_pkg-1.1.0.dist-info": { "METADATA": """ Name: distinfo-pkg Version: 1.1.0 """, "entry_points.txt": """ [entries] main = mod:altmain """, }, } fixtures.build_files(alt_pkg, alt_site_dir) entries = entry_points(group='entries') assert not any( ep.dist.name == 'distinfo-pkg' and ep.dist.version == '1.0.0' for ep in entries) # ns:sub doesn't exist in alt_pkg assert 'ns:sub' not in entries
def cache(self): if self._cache is None: self._cache = { i.name: i for i in importlib_metadata.entry_points().get('crowbar_ext') } return self._cache
def get_entry_points(group_name, *, specs=None, strict=False): """ Get entry points from a specific group. :param str group_name: the name of the entry point group :param list specs: an optional collection of entry point names to retrieve :param bool strict: whether to raise or warn on error :returns: mapping from entry point names to ``EntryPoint`` instances :rtype: dict """ if specs is not None: specs = set(specs) entry_points = {} for entry_point in importlib_metadata.entry_points().get(group_name, []): name = entry_point.name if specs and name not in specs: continue if name in entry_points: msg = (f"Found duplicate entry point '{name}': " 'got {entry_point} and {entry_points[name]}') if strict: raise RuntimeError(msg) logger.warning(msg) continue entry_points[name] = entry_point if specs: pending = specs - set(entry_points) if pending: msg = 'Some specs could not be met: ' msg += ', '.join(map(str, pending)) if strict: raise RuntimeError(msg) logger.warning(msg) return entry_points
def bootstrap(self, bootstrap_id: str): """Make a plugin object instance of a type and key. A python module out there will need to have declared an entry_point for 'mirantis.testing.toolbox.{type}' with entry_point key {name}. The entrypoint must be a factory method of signature: ``` def XXXX(conf: configerus.config.Config, instance_id:str) -> {plugin}: ``` An alternative would be if the entrypoint refers to a sub-package here. The factory should return the plugin, which is likely going to be some kind of an object which has value to the caller of the function. This function does not specify what the return needs to be. """ logger.debug("Running configerus bootstrap entrypoint: %s", bootstrap_id) entry_points = metadata.entry_points()[CONFIGERUS_BOOTSTRAP_ENTRYPOINT] for entry_point in entry_points: if entry_point.name == bootstrap_id: bootstrap_entrypoint = entry_point.load() bootstrap_entrypoint(self) break else: raise KeyError("Bootstrap not found {}:{}".format( CONFIGERUS_BOOTSTRAP_ENTRYPOINT, bootstrap_id))
def load_yaml_template(volume_vars, extension_installer, loader, node): if node.id == 'scalar': props = {} name = loader.construct_scalar(node) else: props = loader.construct_mapping(node, deep=True) name = props.pop('name') for ep in metadata.entry_points().get('hopic.plugins.yaml', ()): if ep.name == name: break else: raise TemplateNotFoundError(name=name, props=props) template_fn = ep.load() template_sig = inspect.signature(template_fn) props = match_template_props_to_signature(name, template_sig.parameters, props) cfg = template_fn(volume_vars, **props) if isinstance(cfg, str): # Parse provided yaml without template substitution install_top_level_extensions(cfg, name, extension_installer, volume_vars) cfg = yaml.load( cfg, ordered_config_loader(volume_vars, extension_installer)) if 'config' in cfg: cfg = cfg['config'] return cfg
def run_checks(*, include_warnings=False) -> Tuple[Set[str], int, int]: """ Run all checks and return check results. :return: 3-tuple (categories of failed checks, number of failed checks, total number of checks) """ fail_categories = set() # remove repeating elements fail = 0 total = 0 for check_entry_pt in importlib_metadata.entry_points().get( 'ros2doctor.checks', []): try: check_class = check_entry_pt.load() except ImportError: doctor_warn( f'Check entry point {check_entry_pt.name} fails to load.') continue try: check_instance = check_class() except Exception: doctor_warn( f'Unable to instantiate check object from {check_entry_pt.name}.' ) continue try: check_category = check_instance.category() result = check_instance.check() if result.error or (include_warnings and result.warning): fail += 1 fail_categories.add(check_category) total += 1 except Exception: doctor_warn(f'Fail to call {check_entry_pt.name} class functions.') return fail_categories, fail, total
def collect_plugins(self): """Collect plugins from all possible ways of loading.""" if not settings.PLUGINS_ENABLED: # Plugins not enabled, do nothing return # pragma: no cover self.plugin_modules = [] # clear # Collect plugins from paths for plugin in settings.PLUGIN_DIRS: modules = get_plugins(importlib.import_module(plugin), InvenTreePlugin) if modules: [self.plugin_modules.append(item) for item in modules] # Check if not running in testing mode and apps should be loaded from hooks if (not settings.PLUGIN_TESTING) or (settings.PLUGIN_TESTING and settings.PLUGIN_TESTING_SETUP): # Collect plugins from setup entry points for entry in metadata.entry_points().get('inventree_plugins', []): # pragma: no cover try: plugin = entry.load() plugin.is_package = True plugin._get_package_metadata() self.plugin_modules.append(plugin) except Exception as error: handle_error(error, do_raise=False, log_name='discovery') # Log collected plugins logger.info(f'Collected {len(self.plugin_modules)} plugins!') logger.info(", ".join([a.__module__ for a in self.plugin_modules]))
def _reseed(config, offset=0): global entrypoint_reseeds seed = config.getoption("randomly_seed") + offset if seed not in random_states: random.seed(seed) random_states[seed] = random.getstate() else: random.setstate(random_states[seed]) if have_factory_boy: factory_set_random_state(random_states[seed]) if have_faker: faker_random.setstate(random_states[seed]) if have_numpy: if seed not in np_random_states: np_random.seed(seed) np_random_states[seed] = np_random.get_state() else: np_random.set_state(np_random_states[seed]) if entrypoint_reseeds is None: entrypoint_reseeds = [ e.load() for e in entry_points().get("pytest_randomly.random_seeder", []) ] for reseed in entrypoint_reseeds: reseed(seed)
def get_http_app(): settings = get_settings() app = FastAPI(debug=settings.debug, title=settings.app_name) app.add_middleware(SessionMiddleware, secret_key=settings.session_secret) @app.on_event("startup") async def setup_edgedb_pool(): app.state.db = await edgedb.create_async_pool(settings.edgedb_dsn) @app.on_event("shutdown") async def setup_edgedb_pool(): db = app.state.db del app.state.db await db.aclose() @app.exception_handler(edgedb.NoDataError) async def no_data_handler(request, exc): return await http_exception_handler( request, HTTPException(status.HTTP_404_NOT_FOUND) ) for ep in entry_points()["authub.http"]: router = ep.load() if not isinstance(router, APIRouter): router = router(app) app.include_router(router) return app
def _configure_external_callbacks() -> List[Callback]: """Collect external callbacks registered through entry points. The entry points are expected to be functions returning a list of callbacks. Return: A list of all callbacks collected from external factories. """ if _PYTHON_GREATER_EQUAL_3_8_0: from importlib.metadata import entry_points factories = entry_points().get("pytorch_lightning.callbacks_factory", ()) else: from pkg_resources import iter_entry_points factories = iter_entry_points("pytorch_lightning.callbacks_factory") external_callbacks = [] for factory in factories: callback_factory = factory.load() callbacks_list: List[Callback] = callback_factory() callbacks_list = [callbacks_list] if isinstance( callbacks_list, Callback) else callbacks_list _log.info( f"Adding {len(callbacks_list)} callbacks from entry point '{factory.name}':" f" {', '.join(type(cb).__name__ for cb in callbacks_list)}") external_callbacks.extend(callbacks_list) return external_callbacks
def load_launch_extensions(cls): """Load launch extensions, in order to get all the exposed substitutions and actions.""" if cls.extensions_loaded is False: for entry_point in importlib_metadata.entry_points().get( 'launch.frontend.launch_extension', []): entry_point.load() cls.extensions_loaded = True
def main(config, scorerOption, init_db, csvfile, idcol, namecol): ep = pickScorer(scorerOption) if ep: ep.load() else: return eps = metadata.entry_points()['csv_reconcile.scorers'] if len(eps) == 0: raise RuntimeError("Please install a \"csv_reconcile.scorers\" plugin") elif scorerOption: for ep in eps: if ep.name == scorerOption: ep.load() break else: raise RuntimeError( "Please install %s \"csv_reconcile.scorers\" plugin" % (scorerOption,)) elif len(eps) == 1: ep = next(iter(eps)) ep.load() else: # prompt for options and quit pass app = create_app(dict(CSVFILE=csvfile, CSVCOLS=(idcol, namecol)), config) if init_db: with app.app_context(): initdb.init_db() click.echo('Initialized the database.') from werkzeug.serving import WSGIRequestHandler WSGIRequestHandler.protocol_version = "HTTP/1.1" app.run()
def generate_reports(*, categories=None) -> List[Report]: """ Print all reports or reports of failed checks to terminal. :return: list of Report objects """ reports = [] for report_entry_pt in importlib_metadata.entry_points().get( 'ros2doctor.report', []): try: report_class = report_entry_pt.load() except ImportError: doctor_warn( f'Report entry point {report_entry_pt.name} fails to load.') continue try: report_instance = report_class() except Exception: doctor_warn( f'Unable to instantiate report object from {report_entry_pt.name}.' ) continue try: report_category = report_instance.category() report = report_instance.report() if categories: if report_category in categories: reports.append(report) else: reports.append(report) except Exception: doctor_warn( f'Fail to call {report_entry_pt.name} class functions.') return reports
def test_entry_point(): """ Keyring provides exactly one 'keyring' console script that's a callable. """ scripts = dict(metadata.entry_points()['console_scripts']) assert callable(scripts['keyring'].load())
def random(orig_colors: ColorList, config: ConfigParser): """Yeah, coz how could we live without a random filter?""" try: include_str = config["filters:random"]["include"] except KeyError: filter_names = [*{i.name for i in entry_points()["larry.filters"]}] filter_names.remove("random") else: filter_names = [*{i.strip() for i in include_str.split()}] if not filter_names: return orig_colors try: chains = int(config["filters:random"]["chains"]) except (KeyError, ValueError): chains = 1 new_colors = orig_colors iters = rand.randint(1, chains) for _ in range(iters): filter_name = rand.choice(filter_names) filter_ = load_filter(filter_name) LOGGER.debug("random: running filter: %s", filter_name) new_colors = filter_(new_colors, config) return new_colors
def installed_array_modules() -> Dict[str, EntryPoint]: """Returns a dictionary of array module names paired to their entry points A convenience wrapper for importlib.metadata.entry_points(). It has the added benefit of working with both the original dict interface and the new select interface, so this can be used warning-free in all modern Python versions. """ try: eps = entry_points(group="array_api") except TypeError: # The select interface for entry_points was introduced in py3.10, # supplanting its dict interface. We fallback to the dict interface so # we can still find entry points in py3.8 and py3.9. eps = entry_points().get("array_api", []) return {ep.name: ep for ep in eps}
def _load_plugins(): """ Locate all setuptools entry points by the name 'keyring backends' and initialize them. Any third-party library may register an entry point by adding the following to their setup.py:: entry_points = { 'keyring.backends': [ 'plugin_name = mylib.mymodule:initialize_func', ], }, `plugin_name` can be anything, and is only used to display the name of the plugin at initialization time. `initialize_func` is optional, but will be invoked if callable. """ entry_points = metadata.entry_points().get('keyring.backends', []) for ep in entry_points: try: log.debug('Loading %s', ep.name) init_func = ep.load() if callable(init_func): init_func() except Exception: log.exception("Error initializing plugin {ep}.".format(**locals()))
def reload_modules(): """ SYNOPSIS void python_reload() DESCRIPTION Reloads all Python efuns. All packages providing the "ldmud_efuns" entry point are loaded. If they were already loaded, they are reloaded. Then the entry point is executed to register the efuns. Before reloading the function on_reload() is called in the module. SEE ALSO python_efun_help(E) """ importlib.reload(metadata) modules = dict(sys.modules) reloaded = set() eps = metadata.entry_points() config = configparser.ConfigParser() config['efuns'] = {} config['types'] = {} config.read(os.path.expanduser('~/.ldmud-efuns')) ep_types = [] if hasattr(ldmud, 'register_type'): ep_types.append(( 'ldmud_type', config['types'], ldmud.register_type, )) if hasattr(ldmud, 'register_efun'): ep_types.append(( 'ldmud_efun', config['efuns'], ldmud.register_efun, )) for ep_name, ep_config, ep_register in ep_types: for entry_point in eps.get(ep_name, ()): if ep_config.getboolean(entry_point.name, True): # Remove the corresponding modules from sys.modules # so they will be reloaded. names = entry_point.module.split('.') for module in ('.'.join(names[:pos]) for pos in range(len(names), 0, -1)): if not module in modules or module in reloaded: break try: sys.modules[module].on_reload() except: pass del sys.modules[module] reloaded.add(module) print("Reload module", module) ep_register(entry_point.name, entry_point.load())