예제 #1
0
 def test_resolve_without_attr(self):
     ep = EntryPoint(
         name='ep',
         value='importlib.metadata',
         group='grp',
     )
     assert ep.load() is importlib.metadata
예제 #2
0
 def test_sortable(self):
     """
     EntryPoint objects are sortable, but result is undefined.
     """
     sorted([
         EntryPoint(name='b', value='val', group='group'),
         EntryPoint(name='a', value='val', group='group'),
     ])
예제 #3
0
파일: test_main.py 프로젝트: zyzek/cpython
 def test_sortable(self):
     """
     EntryPoint objects are sortable, but result is undefined.
     """
     sorted([
         EntryPoint('b', 'val', 'group'),
         EntryPoint('a', 'val', 'group'),
     ])
예제 #4
0
def test_load_from_entry_point__old_api():
    # The following module/class exists but uses an old version of the extensions API
    # therefore, we should have a meaningful error when trying to load it.
    entry = f"{test_extensions_pkg}.incompatible_v3_api_fake_extension:FakeExtension"
    fake = EntryPoint("fake", entry, "pyscaffold.cli")
    with pytest.raises(ErrorLoadingExtension):
        extensions.load_from_entry_point(fake)
예제 #5
0
def test_load_from_entry_point__error():
    # This module does not exist, so Python will have some trouble loading it
    # EntryPoint(name, value, group)
    fake = EntryPoint("fake", "pyscaffoldext.SOOOOO___fake___:Fake",
                      "pyscaffold.cli")
    with pytest.raises(ErrorLoadingExtension):
        extensions.load_from_entry_point(fake)
예제 #6
0
def dummy_duplicated_entrypoints():
    specs = [
        ["engine1", "xarray.tests.test_plugins:backend_1", "xarray.backends"],
        ["engine1", "xarray.tests.test_plugins:backend_2", "xarray.backends"],
        ["engine2", "xarray.tests.test_plugins:backend_1", "xarray.backends"],
        ["engine2", "xarray.tests.test_plugins:backend_2", "xarray.backends"],
    ]
    eps = [EntryPoint(name, value, group) for name, value, group in specs]
    return eps
예제 #7
0
def test_backends_dict_from_pkg() -> None:
    specs = [
        ["engine1", "xarray.tests.test_plugins:backend_1", "xarray.backends"],
        ["engine2", "xarray.tests.test_plugins:backend_2", "xarray.backends"],
    ]
    entrypoints = [EntryPoint(name, value, group) for name, value, group in specs]
    engines = plugins.backends_dict_from_pkg(entrypoints)
    assert len(engines) == 2
    assert engines.keys() == set(("engine1", "engine2"))
예제 #8
0
def test_build_engines_sorted() -> None:
    dummy_pkg_entrypoints = [
        EntryPoint("dummy2", "xarray.tests.test_plugins:backend_1", "xarray.backends"),
        EntryPoint("dummy1", "xarray.tests.test_plugins:backend_1", "xarray.backends"),
    ]
    backend_entrypoints = plugins.build_engines(dummy_pkg_entrypoints)
    backend_entrypoints = list(backend_entrypoints)

    indices = []
    for be in plugins.STANDARD_BACKENDS_ORDER:
        try:
            index = backend_entrypoints.index(be)
            backend_entrypoints.pop(index)
            indices.append(index)
        except ValueError:
            pass

    assert set(indices) < {0, -1}
    assert list(backend_entrypoints) == sorted(backend_entrypoints)
예제 #9
0
def test_build_engines() -> None:
    dummy_pkg_entrypoint = EntryPoint(
        "cfgrib", "xarray.tests.test_plugins:backend_1", "xarray_backends"
    )
    backend_entrypoints = plugins.build_engines([dummy_pkg_entrypoint])

    assert isinstance(backend_entrypoints["cfgrib"], DummyBackendEntrypoint1)
    assert backend_entrypoints["cfgrib"].open_dataset_parameters == (
        "filename_or_obj",
        "decoder",
    )
예제 #10
0
def test_broken_plugin() -> None:
    broken_backend = EntryPoint(
        "broken_backend",
        "xarray.tests.test_plugins:backend_1",
        "xarray.backends",
    )
    with pytest.warns(RuntimeWarning) as record:
        _ = plugins.build_engines([broken_backend])
    assert len(record) == 1
    message = str(record[0].message)
    assert "Engine 'broken_backend'" in message
예제 #11
0
class Discovery(PluginLoader):
    _ENTRY_POINTS = {
        "virtualenv.discovery": [
            EntryPoint(
                name=name,
                value=f"virtualenv.discovery.{dst}",
                group="virtualenv.discovery"
            ) for name, dst in [
                ("builtin", "builtin:Builtin")
            ]
        ]
    }
예제 #12
0
def test_error_loading_external_extension():
    # Assert the error message displays some meaningful text
    extension = "pyscaffoldext.fake.extension"

    # Extension name is given directly
    ex = str(ErrorLoadingExtension(extension))
    assert "an error loading" in ex
    assert "fake" in ex

    # Entrypoint is given
    fake = EntryPoint("fake", f"{extension}:Fake", "pyscaffold.cli")
    ex = str(ErrorLoadingExtension(entry_point=fake))
    assert "an error loading" in ex
    assert "fake" in ex
예제 #13
0
def test_wrong_extension(monkeypatch, tmpfolder):
    # Given an entry point with some problems is registered in the pyscaffold.cli group
    # (e.g. failing implementation, wrong dependencies that cause the python file to
    # fail to evaluate)
    fake = EntryPoint("fake", "pyscaffoldext.SOOO__fake__:Fake",
                      "pyscaffold.cli")
    entry_points_mock = Mock(return_value={"pyscaffold.cli": [fake]})
    monkeypatch.setattr("pyscaffold.extensions.entry_points",
                        entry_points_mock)
    with pytest.raises(ErrorLoadingExtension,
                       match=r".*error loading.*fake.*"):
        # When putup is called with the corresponding flag
        args = ["my-project"]
        cli.main(args)
        entry_points_mock.assert_called()
예제 #14
0
def test_auto_loading_xontribs(xession, shell, mocker):
    from importlib.metadata import EntryPoint

    group = "xonsh.xontribs"

    mocker.patch(
        "importlib.metadata.entry_points",
        autospec=True,
        return_value={
            group: [EntryPoint(name="test", group=group, value="test.module")]
        },
    )
    xontribs_load = mocker.patch("xonsh.xontribs.xontribs_load")
    xonsh.main.premain([])
    assert xession.builtins.autoloaded_xontribs == {"test": "test.module"}
    xontribs_load.assert_called()
예제 #15
0
class SeederSelector(ComponentBuilder):
    _ENTRY_POINTS = {
        "virtualenv.seed": [
            EntryPoint(name=name,
                       value=f"virtualenv.seed.embed.{dst}",
                       group="virtualenv.seed")
            for name, dst in [("pip", "pip_invoke:PipInvoke"),
                              ("app-data",
                               "via_app_data.via_app_data:FromAppData")]
        ]
    }

    def __init__(self, interpreter, parser):
        possible = self.options("virtualenv.seed")
        super(SeederSelector, self).__init__(interpreter, parser, "seeder",
                                             possible)

    def add_selector_arg_parse(self, name, choices):
        self.parser.add_argument(
            "--{}".format(name),
            choices=choices,
            default=self._get_default(),
            required=False,
            help="seed packages install method",
        )
        self.parser.add_argument(
            "--no-seed",
            "--without-pip",
            help="do not install seed packages",
            action="store_true",
            dest="no_seed",
        )

    @staticmethod
    def _get_default():
        return "app-data"

    def handle_selected_arg_parse(self, options):
        return super(SeederSelector, self).handle_selected_arg_parse(options)

    def create(self, options):
        return self._impl_class(options)
예제 #16
0
파일: manager.py 프로젝트: pomes/valiant
    def _load_local_plugins(self, local_plugins: Mapping[str, str]) -> None:
        """Load local plugins from config.

        Args:
            local_plugins: x.
        """
        for name, entry_str in local_plugins.items():
            """
            I've set mypy to ignore an error on the line below:
                - Unexpected keyword argument "group" for "EntryPoint"

            As the EntryPoint definition I see is a NamedTuple with "group" being
            an attribute (Python 3.8 importlib):

                class EntryPoint(
                    collections.namedtuple('EntryPointBase', 'name value group')):
            """
            entry_point = EntryPoint(  # type: ignore
                name=name,
                value=entry_str,
                group=self.namespace)
            self._load_plugin_from_entrypoint(entry_point, local=True)
예제 #17
0
class CreatorSelector(ComponentBuilder):
    _ENTRY_POINTS = {
        "virtualenv.create": [
            EntryPoint(
                name=name,
                value=f"virtualenv.create.via_global_ref.{dst}",
                group="virtualenv.create"
            ) for name, dst in [
                ("venv", "venv:Venv"),
                ("cpython3-posix", "builtin.cpython.cpython3:CPython3Posix"),
                ("cpython3-win", "builtin.cpython.cpython3:CPython3Windows"),
                ("cpython2-posix", "builtin.cpython.cpython2:CPython2Posix"),
                ("cpython2-mac-framework", "builtin.cpython.mac_os:CPython2macOsFramework"),
                ("cpython3-mac-framework", "builtin.cpython.mac_os:CPython3macOsFramework"),
                ("cpython2-win", "builtin.cpython.cpython2:CPython2Windows"),
                ("pypy2-posix", "builtin.pypy.pypy2:PyPy2Posix"),
                ("pypy2-win", "builtin.pypy.pypy2:Pypy2Windows"),
                ("pypy3-posix", "builtin.pypy.pypy3:PyPy3Posix"),
                ("pypy3-win", "builtin.pypy.pypy3:Pypy3Windows")
            ]
        ]
    }

    def __init__(self, interpreter, parser):
        creators, self.key_to_meta, self.describe, self.builtin_key = self.for_interpreter(interpreter)
        super(CreatorSelector, self).__init__(interpreter, parser, "creator", creators)

    @classmethod
    def for_interpreter(cls, interpreter):
        key_to_class, key_to_meta, builtin_key, describe = OrderedDict(), {}, None, None
        errors = defaultdict(list)
        for key, creator_class in cls.options("virtualenv.create").items():
            if key == "builtin":
                raise RuntimeError("builtin creator is a reserved name")
            meta = creator_class.can_create(interpreter)
            if meta:
                if meta.error:
                    errors[meta.error].append(creator_class)
                else:
                    if "builtin" not in key_to_class and issubclass(creator_class, VirtualenvBuiltin):
                        builtin_key = key
                        key_to_class["builtin"] = creator_class
                        key_to_meta["builtin"] = meta
                    key_to_class[key] = creator_class
                    key_to_meta[key] = meta
            if describe is None and issubclass(creator_class, Describe) and creator_class.can_describe(interpreter):
                describe = creator_class
        if not key_to_meta:
            if errors:
                rows = ["{} for creators {}".format(k, ", ".join(i.__name__ for i in v)) for k, v in errors.items()]
                raise RuntimeError("\n".join(rows))
            else:
                raise RuntimeError("No virtualenv implementation for {}".format(interpreter))
        return CreatorInfo(
            key_to_class=key_to_class,
            key_to_meta=key_to_meta,
            describe=describe,
            builtin_key=builtin_key,
        )

    def add_selector_arg_parse(self, name, choices):
        # prefer the built-in venv if present, otherwise fallback to first defined type
        choices = sorted(choices, key=lambda a: 0 if a == "builtin" else 1)
        default_value = self._get_default(choices)
        self.parser.add_argument(
            "--{}".format(name),
            choices=choices,
            default=default_value,
            required=False,
            help="create environment via{}".format(
                "" if self.builtin_key is None else " (builtin = {})".format(self.builtin_key),
            ),
        )

    @staticmethod
    def _get_default(choices):
        return next(iter(choices))

    def populate_selected_argparse(self, selected, app_data):
        self.parser.description = "options for {} {}".format(self.name, selected)
        self._impl_class.add_parser_arguments(self.parser, self.interpreter, self.key_to_meta[selected], app_data)

    def create(self, options):
        options.meta = self.key_to_meta[getattr(options, self.name)]
        if not issubclass(self._impl_class, Describe):
            options.describe = self.describe(options, self.interpreter)
        return super(CreatorSelector, self).create(options)
예제 #18
0
 def test_positional_args(self):
     """
     Capture legacy (namedtuple) construction, discouraged.
     """
     EntryPoint('name', 'value', 'group')
예제 #19
0
def load_from_entry_point(entry_point: EntryPoint) -> Extension:
    """Carefully load the extension, raising a meaningful message in case of errors"""
    try:
        return entry_point.load()(entry_point.name)
    except Exception as ex:
        raise ErrorLoadingExtension(entry_point=entry_point) from ex
예제 #20
0
class ActivationSelector(ComponentBuilder):
    _ENTRY_POINTS = {
        "virtualenv.activate": [
            EntryPoint(name=name,
                       value=f"virtualenv.activation.{dst}",
                       group="virtualenv.activate") for name, dst in
            [("bash",
              "bash:BashActivator"), ("cshell", "cshell:CShellActivator"),
             ("batch", "batch:BatchActivator"), (
                 "fish",
                 "fish:FishActivator"), ("nushell",
                                         "nushell:NushellActivator"),
             ("powershell", "powershell:PowerShellActivator"
              ), ("python", "python:PythonActivator")]
        ]
    }

    def __init__(self, interpreter, parser):
        self.default = None
        possible = OrderedDict(
            (k, v) for k, v in self.options("virtualenv.activate").items()
            if v.supports(interpreter))
        super(ActivationSelector, self).__init__(interpreter, parser,
                                                 "activators", possible)
        self.parser.description = "options for activation scripts"
        self.active = None

    def add_selector_arg_parse(self, name, choices):
        self.default = ",".join(choices)
        self.parser.add_argument(
            "--{}".format(name),
            default=self.default,
            metavar="comma_sep_list",
            required=False,
            help="activators to generate - default is all supported",
            type=self._extract_activators,
        )

    def _extract_activators(self, entered_str):
        elements = [e.strip() for e in entered_str.split(",") if e.strip()]
        missing = [e for e in elements if e not in self.possible]
        if missing:
            raise ArgumentTypeError(
                "the following activators are not available {}".format(
                    ",".join(missing)))
        return elements

    def handle_selected_arg_parse(self, options):
        selected_activators = (self._extract_activators(self.default)
                               if options.activators is self.default else
                               options.activators)
        self.active = {
            k: v
            for k, v in self.possible.items() if k in selected_activators
        }
        self.parser.add_argument(
            "--prompt",
            dest="prompt",
            metavar="prompt",
            help=("provides an alternative prompt prefix for this environment "
                  "(value of . means name of the current working directory)"),
            default=None,
        )
        for activator in self.active.values():
            activator.add_parser_arguments(self.parser, self.interpreter)

    def create(self, options):
        return [
            activator_class(options)
            for activator_class in self.active.values()
        ]