Exemple #1
0
    def merge(self,
              mfr,
              root=None,
              override=False,
              ignore_collision=True,
              sep="/",
              force=None):
        """Merge another manufacturer with compatible target.

    This method registers all the factories from the given `Manufacturer`.
    The resulting key of the merged factories will have the following form:

      * "root<sep><factory_key>"

    For instance, using the default `sep="/"`, the merged factory key becomes:

      * "root/<factory_key>"

    This allows convenient grouping of factories by context, without the need
    to hard-code the path-like key at registration. If `root` is `None`, the
    original method name is used.

    Args:
      mfr: `Manufacturer` or a zero-argument function that returns an
        instance of it.
      root: A string that serves as the root of the factory keys from `mfr`.
        If None, the original factory key will be used directly.
      override: If True, overwrites the original factory in case of key
        collision. Defaults to False. See `ignore_collision` for collision
        handling when `override` is False.
      ignore_collision: Will only take effect when `override` is False.
        If True, the factory key collision is ignored, i.e. the original factory
        is preserved. Otherwise, an error would be raised when key collision
        occurs. Defaults to False.
      sep: Separator between root and method name in the resulting factory key.
        Defaults to "/".
      force: Deprecated. Use `override` instead. If specified, this overrides
        `override` for backwards compatibility.

    Raises:
      KeyConflictError:
        - Any of the resulting keys has been registered when `override` and
          `ignore_collision` are both False.
      TypeError:
        - `mfr` is not a `Manufacturer` nor a zero-argument function that
            returns an instance of it.
        - Target of `mfr` is not a subclass of this target.
    """
        override = deprecation.handle_renamed_arg("override", override,
                                                  "force", force)
        mfr = fn_util.maybe_call(mfr, Manufacturer)

        self._validate_merge(mfr, root, override, ignore_collision, sep)
        self._merge(root,
                    mfr,
                    override=override,
                    ignore_collision=ignore_collision,
                    sep=sep)
Exemple #2
0
    def merge_all(self, mfr_dict, **kwargs):
        """Merges multiple manufacturers.

    Args:
      mfr_dict: A dictionary mapping each root to either of the following:
        1. A `Manufacturer` instance with compatible target
        2. A zero-argument function that returns (1) above
        3. An iterable of either of (1, 2) above
        4. A zero-argument function that returns either of (1, 3) above
      **kwargs: Merge options:
        * override: If True, overwrites the original factory registration in
            case of key collision. Defaults to False. See `raise_on_collision`
            for collision handling if not `override`.
        * ignore_collision: If True, the factory key collision is ignored when
            `override` is False, and the original factory is preserved.
            Otherwise, an error would be raised. Defaults to False.
        * sep: Separator between root and method name in the resulting factory
            key. Defaults to "/". See `Manufacturer.merge` for details.
        * force: Deprecated. Use `override` instead. If specified, this
            overrides `override` for backwards compatibility.

    Raises:
      KeyConflictError:
        - Any of the resulting keys has been registered when `override` and
          `ignore_collision` are both False
      TypeError:
        - Any values of `mfr_dict` is not one of the described ones above.
        - Target of any `Manufacturer` that is not a subclass of this target.
    """
        if "force" in kwargs:
            deprecation.warn(
                "Parameter `force` is deprecated. Use `override` instead.")
            kwargs["override"] = kwargs.pop("force")

        mfr_dict_validated = collections.defaultdict(list)
        for root, mfrs in mfr_dict.items():
            if callable(mfrs):
                mfrs = mfrs()
            if not hasattr(mfrs, "__iter__"):
                mfrs = [mfrs]

            for mfr in mfrs:
                mfr = fn_util.maybe_call(mfr, Manufacturer)
                self._validate_merge(mfr, root, **kwargs)
                mfr_dict_validated[root].append(mfr)

        for root, mfrs in mfr_dict_validated.items():
            [self._merge(root, mfr, **kwargs) for mfr in mfrs]
Exemple #3
0
    def register_all(self, mfrs, **kwargs):
        """Registers multiple `Manufacturer`s at once.

    Args:
      mfrs: An iterable of `Manufacturer`s, or zero-argument functions where
        each returns an instance of it.
      **kwargs: Register options
        * override: If True, when a `Manufacturer` with the same target class
            exists, detaches the original one and registers `mfr`. If False,
            an error is raised instead. Defaults to False.

    Raises:
      KeyConflictError:
        - `Manufacturer` class collision occurs and `override` is False.
    """
        checked = []
        for mfr in mfrs:
            mfr = fn_util.maybe_call(mfr, Manufacturer)
            checked.append(mfr)
        [self.register(mfr, **kwargs) for mfr in checked]
Exemple #4
0
 def _merge_mfr(self, mfr, **kwargs):
     mfr = fn_util.maybe_call(mfr, Manufacturer)
     _mfr = self.get_or_create(mfr.cls)
     _mfr.merge(mfr, **kwargs)
Exemple #5
0
 def _merge(self, broker, **kwargs):
     broker = fn_util.maybe_call(broker, Broker)
     for cls in broker.classes:
         mfr = broker.get(cls)
         self.merge_mfr(mfr, **kwargs)