예제 #1
0
파일: central.py 프로젝트: ulm/pkgcore
    def _instantiate(self):
        """Call our type's callable, cache and return the result.

        Calling instantiate more than once will return the cached value.
        """

        # Needed because this code can run twice even with instance
        # caching if we trigger an ComplexInstantiationError.
        config = mappings.ProtectedDict(self.config)

        # Instantiate section refs.
        # Careful: not everything we have for needs to be in the conf dict
        # (because of default values) and not everything in the conf dict
        # needs to have a type (because of allow_unknowns).
        for name, val in config.items():
            typename = self.type.types.get(name)
            if typename is None:
                continue
            # central already checked the type, no need to repeat that here.
            unlist_it = False
            if typename.startswith('ref:'):
                val = [val]
                unlist_it = True
            if typename.startswith('refs:') or unlist_it:
                try:
                    final_val = []
                    for ref in val:
                        final_val.append(ref.instantiate())
                except IGNORED_EXCEPTIONS:
                    raise
                except Exception as e:
                    raise errors.ConfigurationError(
                        f'Instantiating reference {name!r} pointing at {ref.name!r}'
                    ) from e
                if unlist_it:
                    final_val = final_val[0]
                config[name] = final_val

        if self.type.requires_config:
            if self.manager is None:
                raise Exception('configuration internal error; '
                                'requires_config is enabled '
                                'but we have no config manager to return ')
            manager = self.manager()
            if manager is None:
                raise Exception(
                    'Configuration internal error, potentially '
                    'client code error; manager requested, but the config '
                    'manager is no longer in memory')

            config[self.type.requires_config] = manager

        callable_obj = self.type.callable

        pargs = []
        for var in self.type.positional:
            pargs.append(config.pop(var))
        # Python is basically the worst language ever:
        # TypeError: repo() argument after ** must be a dictionary
        configdict = dict(config)
        try:
            self._instance = callable_obj(*pargs, **configdict)
        except IGNORED_EXCEPTIONS:
            raise
        except Exception as e:
            source = errors._identify_functor_source(self.type.callable)
            raise errors.InstantiationError(
                self.name, f'exception caught from {source!r}') from e
        if self._instance is None:
            raise errors.ComplexInstantiationError('No object returned',
                                                   callable_obj=callable_obj,
                                                   pargs=pargs,
                                                   kwargs=configdict)

        return self._instance
예제 #2
0
 def setup_method(self, method):
     self.orig = {1: -1, 2: -2}
     self.dict = mappings.ProtectedDict(self.orig)
예제 #3
0
 def setUp(self):
     self.orig = {1: -1, 2: -2}
     self.dict = mappings.ProtectedDict(self.orig)