From 2bafd7b68f28bfa108aa83fd412587be702cfdfd Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Thu, 2 May 2024 10:13:21 +0200 Subject: [PATCH] MNT metadata routing: remove `MethodMapping.from_str()` and sort `caller`, `callee` in `MethodPair()` (#28422) Co-authored-by: Adrin Jalali Co-authored-by: Guillaume Lemaitre --- .../miscellaneous/plot_metadata_routing.py | 28 +++--- sklearn/calibration.py | 4 +- sklearn/feature_selection/_from_model.py | 4 +- sklearn/linear_model/_coordinate_descent.py | 2 +- sklearn/linear_model/_least_angle.py | 2 +- sklearn/linear_model/_logistic.py | 6 +- sklearn/linear_model/_omp.py | 2 +- sklearn/metrics/_scorer.py | 4 +- sklearn/metrics/tests/test_score_objects.py | 8 +- sklearn/multiclass.py | 10 +-- sklearn/multioutput.py | 8 +- sklearn/tests/metadata_routing_common.py | 21 ++++- sklearn/tests/test_metadata_routing.py | 56 ++++++------ sklearn/utils/_metadata_requests.py | 87 ++++++------------- 14 files changed, 113 insertions(+), 129 deletions(-) diff --git a/examples/miscellaneous/plot_metadata_routing.py b/examples/miscellaneous/plot_metadata_routing.py index ef7012fb61a..e96b54436cf 100644 --- a/examples/miscellaneous/plot_metadata_routing.py +++ b/examples/miscellaneous/plot_metadata_routing.py @@ -167,9 +167,9 @@ class MetaClassifier(MetaEstimatorMixin, ClassifierMixin, BaseEstimator): router = MetadataRouter(owner=self.__class__.__name__).add( estimator=self.estimator, method_mapping=MethodMapping() - .add(callee="fit", caller="fit") - .add(callee="predict", caller="predict") - .add(callee="score", caller="score"), + .add(caller="fit", callee="fit") + .add(caller="predict", callee="predict") + .add(caller="score", callee="score"), ) return router @@ -356,9 +356,9 @@ class RouterConsumerClassifier(MetaEstimatorMixin, ClassifierMixin, BaseEstimato .add( estimator=self.estimator, method_mapping=MethodMapping() - .add(callee="fit", caller="fit") - .add(callee="predict", caller="predict") - .add(callee="score", caller="score"), + .add(caller="fit", callee="fit") + .add(caller="predict", callee="predict") + .add(caller="score", callee="score"), ) ) return router @@ -488,16 +488,16 @@ class SimplePipeline(ClassifierMixin, BaseEstimator): # The metadata is routed such that it retraces how # `SimplePipeline` internally calls the transformer's `fit` and # `transform` methods in its own methods (`fit` and `predict`). - .add(callee="fit", caller="fit") - .add(callee="transform", caller="fit") - .add(callee="transform", caller="predict"), + .add(caller="fit", callee="fit") + .add(caller="fit", callee="transform") + .add(caller="predict", callee="transform"), ) # We add the routing for the classifier. .add( classifier=self.classifier, method_mapping=MethodMapping() - .add(callee="fit", caller="fit") - .add(callee="predict", caller="predict"), + .add(caller="fit", callee="fit") + .add(caller="predict", callee="predict"), ) ) return router @@ -612,7 +612,7 @@ class MetaRegressor(MetaEstimatorMixin, RegressorMixin, BaseEstimator): def get_metadata_routing(self): router = MetadataRouter(owner=self.__class__.__name__).add( estimator=self.estimator, - method_mapping=MethodMapping().add(callee="fit", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) return router @@ -651,7 +651,7 @@ class WeightedMetaRegressor(MetaEstimatorMixin, RegressorMixin, BaseEstimator): .add_self_request(self) .add( estimator=self.estimator, - method_mapping=MethodMapping().add(callee="fit", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) ) return router @@ -692,7 +692,7 @@ for w in record: print(w.message) # %% -# In the end, we disable the configuration flag for metadata routing: +# At the end we disable the configuration flag for metadata routing: set_config(enable_metadata_routing=False) diff --git a/sklearn/calibration.py b/sklearn/calibration.py index 40d3e5363a7..2e1a46e6889 100644 --- a/sklearn/calibration.py +++ b/sklearn/calibration.py @@ -523,11 +523,11 @@ class CalibratedClassifierCV(ClassifierMixin, MetaEstimatorMixin, BaseEstimator) .add_self_request(self) .add( estimator=self._get_estimator(), - method_mapping=MethodMapping().add(callee="fit", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) .add( splitter=self.cv, - method_mapping=MethodMapping().add(callee="split", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="split"), ) ) return router diff --git a/sklearn/feature_selection/_from_model.py b/sklearn/feature_selection/_from_model.py index 5610121f152..46c2b9ebbb1 100644 --- a/sklearn/feature_selection/_from_model.py +++ b/sklearn/feature_selection/_from_model.py @@ -513,8 +513,8 @@ class SelectFromModel(MetaEstimatorMixin, SelectorMixin, BaseEstimator): router = MetadataRouter(owner=self.__class__.__name__).add( estimator=self.estimator, method_mapping=MethodMapping() - .add(callee="partial_fit", caller="partial_fit") - .add(callee="fit", caller="fit"), + .add(caller="partial_fit", callee="partial_fit") + .add(caller="fit", callee="fit"), ) return router diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index 05d7b93f3e0..45cdb8bdf2e 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -1860,7 +1860,7 @@ class LinearModelCV(MultiOutputMixin, LinearModel, ABC): .add_self_request(self) .add( splitter=check_cv(self.cv), - method_mapping=MethodMapping().add(callee="split", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="split"), ) ) return router diff --git a/sklearn/linear_model/_least_angle.py b/sklearn/linear_model/_least_angle.py index f29bcb4c891..81e8abb8bc5 100644 --- a/sklearn/linear_model/_least_angle.py +++ b/sklearn/linear_model/_least_angle.py @@ -1821,7 +1821,7 @@ class LarsCV(Lars): """ router = MetadataRouter(owner=self.__class__.__name__).add( splitter=check_cv(self.cv), - method_mapping=MethodMapping().add(callee="split", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="split"), ) return router diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 129d3f6cc94..481ccf6c7e5 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -2166,13 +2166,13 @@ class LogisticRegressionCV(LogisticRegression, LinearClassifierMixin, BaseEstima .add_self_request(self) .add( splitter=self.cv, - method_mapping=MethodMapping().add(callee="split", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="split"), ) .add( scorer=self._get_scorer(), method_mapping=MethodMapping() - .add(callee="score", caller="score") - .add(callee="score", caller="fit"), + .add(caller="score", callee="score") + .add(caller="fit", callee="score"), ) ) return router diff --git a/sklearn/linear_model/_omp.py b/sklearn/linear_model/_omp.py index 2d6fe488697..f52ef553eab 100644 --- a/sklearn/linear_model/_omp.py +++ b/sklearn/linear_model/_omp.py @@ -1116,6 +1116,6 @@ class OrthogonalMatchingPursuitCV(RegressorMixin, LinearModel): router = MetadataRouter(owner=self.__class__.__name__).add( splitter=self.cv, - method_mapping=MethodMapping().add(callee="split", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="split"), ) return router diff --git a/sklearn/metrics/_scorer.py b/sklearn/metrics/_scorer.py index 19ca055a81b..adeec587994 100644 --- a/sklearn/metrics/_scorer.py +++ b/sklearn/metrics/_scorer.py @@ -32,6 +32,7 @@ from ..utils._response import _get_response_values from ..utils.metadata_routing import ( MetadataRequest, MetadataRouter, + MethodMapping, _MetadataRequester, _raise_for_params, _routing_enabled, @@ -188,7 +189,8 @@ class _MultimetricScorer: routing information. """ return MetadataRouter(owner=self.__class__.__name__).add( - **self._scorers, method_mapping="score" + **self._scorers, + method_mapping=MethodMapping().add(caller="score", callee="score"), ) diff --git a/sklearn/metrics/tests/test_score_objects.py b/sklearn/metrics/tests/test_score_objects.py index ac10e0413af..e45e0d30767 100644 --- a/sklearn/metrics/tests/test_score_objects.py +++ b/sklearn/metrics/tests/test_score_objects.py @@ -61,7 +61,7 @@ from sklearn.utils._testing import ( assert_array_equal, ignore_warnings, ) -from sklearn.utils.metadata_routing import MetadataRouter +from sklearn.utils.metadata_routing import MetadataRouter, MethodMapping REGRESSION_SCORERS = [ "d2_absolute_error_score", @@ -1233,7 +1233,8 @@ def test_scorer_metadata_request(name): # make sure putting the scorer in a router doesn't request anything by # default router = MetadataRouter(owner="test").add( - method_mapping="score", scorer=get_scorer(name) + scorer=get_scorer(name), + method_mapping=MethodMapping().add(caller="score", callee="score"), ) # make sure `sample_weight` is refused if passed. with pytest.raises(TypeError, match="got unexpected argument"): @@ -1244,7 +1245,8 @@ def test_scorer_metadata_request(name): # make sure putting weighted_scorer in a router requests sample_weight router = MetadataRouter(owner="test").add( - scorer=weighted_scorer, method_mapping="score" + scorer=weighted_scorer, + method_mapping=MethodMapping().add(caller="score", callee="score"), ) router.validate_metadata(params={"sample_weight": 1}, method="score") routed_params = router.route_params(params={"sample_weight": 1}, caller="score") diff --git a/sklearn/multiclass.py b/sklearn/multiclass.py index 075095ad414..d8c7904b81c 100644 --- a/sklearn/multiclass.py +++ b/sklearn/multiclass.py @@ -619,8 +619,8 @@ class OneVsRestClassifier( .add( estimator=self.estimator, method_mapping=MethodMapping() - .add(callee="fit", caller="fit") - .add(callee="partial_fit", caller="partial_fit"), + .add(caller="fit", callee="fit") + .add(caller="partial_fit", callee="partial_fit"), ) ) return router @@ -1018,8 +1018,8 @@ class OneVsOneClassifier(MetaEstimatorMixin, ClassifierMixin, BaseEstimator): .add( estimator=self.estimator, method_mapping=MethodMapping() - .add(callee="fit", caller="fit") - .add(callee="partial_fit", caller="partial_fit"), + .add(caller="fit", callee="fit") + .add(caller="partial_fit", callee="partial_fit"), ) ) return router @@ -1264,6 +1264,6 @@ class OutputCodeClassifier(MetaEstimatorMixin, ClassifierMixin, BaseEstimator): router = MetadataRouter(owner=self.__class__.__name__).add( estimator=self.estimator, - method_mapping=MethodMapping().add(callee="fit", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) return router diff --git a/sklearn/multioutput.py b/sklearn/multioutput.py index e0da38357e7..d3814974c63 100644 --- a/sklearn/multioutput.py +++ b/sklearn/multioutput.py @@ -334,8 +334,8 @@ class _MultiOutputEstimator(MetaEstimatorMixin, BaseEstimator, metaclass=ABCMeta router = MetadataRouter(owner=self.__class__.__name__).add( estimator=self.estimator, method_mapping=MethodMapping() - .add(callee="partial_fit", caller="partial_fit") - .add(callee="fit", caller="fit"), + .add(caller="partial_fit", callee="partial_fit") + .add(caller="fit", callee="fit"), ) return router @@ -1096,7 +1096,7 @@ class ClassifierChain(MetaEstimatorMixin, ClassifierMixin, _BaseChain): """ router = MetadataRouter(owner=self.__class__.__name__).add( estimator=self.base_estimator, - method_mapping=MethodMapping().add(callee="fit", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) return router @@ -1245,7 +1245,7 @@ class RegressorChain(MetaEstimatorMixin, RegressorMixin, _BaseChain): """ router = MetadataRouter(owner=self.__class__.__name__).add( estimator=self.base_estimator, - method_mapping=MethodMapping().add(callee="fit", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) return router diff --git a/sklearn/tests/metadata_routing_common.py b/sklearn/tests/metadata_routing_common.py index 3df47d3f8dd..889524bc05d 100644 --- a/sklearn/tests/metadata_routing_common.py +++ b/sklearn/tests/metadata_routing_common.py @@ -19,6 +19,7 @@ from sklearn.utils._metadata_requests import ( ) from sklearn.utils.metadata_routing import ( MetadataRouter, + MethodMapping, process_routing, ) from sklearn.utils.multiclass import _check_partial_fit_first_call @@ -418,7 +419,8 @@ class MetaRegressor(MetaEstimatorMixin, RegressorMixin, BaseEstimator): def get_metadata_routing(self): router = MetadataRouter(owner=self.__class__.__name__).add( - estimator=self.estimator, method_mapping="one-to-one" + estimator=self.estimator, + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) return router @@ -447,7 +449,12 @@ class WeightedMetaRegressor(MetaEstimatorMixin, RegressorMixin, BaseEstimator): router = ( MetadataRouter(owner=self.__class__.__name__) .add_self_request(self) - .add(estimator=self.estimator, method_mapping="one-to-one") + .add( + estimator=self.estimator, + method_mapping=MethodMapping() + .add(caller="fit", callee="fit") + .add(caller="predict", callee="predict"), + ) ) return router @@ -472,7 +479,10 @@ class WeightedMetaClassifier(MetaEstimatorMixin, ClassifierMixin, BaseEstimator) router = ( MetadataRouter(owner=self.__class__.__name__) .add_self_request(self) - .add(estimator=self.estimator, method_mapping="fit") + .add( + estimator=self.estimator, + method_mapping=MethodMapping().add(caller="fit", callee="fit"), + ) ) return router @@ -494,5 +504,8 @@ class MetaTransformer(MetaEstimatorMixin, TransformerMixin, BaseEstimator): def get_metadata_routing(self): return MetadataRouter(owner=self.__class__.__name__).add( - transformer=self.transformer, method_mapping="one-to-one" + transformer=self.transformer, + method_mapping=MethodMapping() + .add(caller="fit", callee="fit") + .add(caller="transform", callee="transform"), ) diff --git a/sklearn/tests/test_metadata_routing.py b/sklearn/tests/test_metadata_routing.py index 110452870d6..109c730bf07 100644 --- a/sklearn/tests/test_metadata_routing.py +++ b/sklearn/tests/test_metadata_routing.py @@ -114,11 +114,16 @@ class SimplePipeline(BaseEstimator): router.add( **{f"step_{i}": step}, method_mapping=MethodMapping() - .add(callee="fit", caller="fit") - .add(callee="transform", caller="fit") - .add(callee="transform", caller="predict"), + .add(caller="fit", callee="fit") + .add(caller="fit", callee="transform") + .add(caller="predict", callee="transform"), ) - router.add(predictor=self.steps[-1], method_mapping="one-to-one") + router.add( + predictor=self.steps[-1], + method_mapping=MethodMapping() + .add(caller="fit", callee="fit") + .add(caller="predict", callee="predict"), + ) return router @@ -150,7 +155,10 @@ def test_assert_request_is_empty(): assert_request_is_empty( MetadataRouter(owner="test") .add_self_request(WeightedMetaRegressor(estimator=None)) - .add(method_mapping="fit", estimator=ConsumingRegressor()) + .add( + estimator=ConsumingRegressor(), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), + ) ) @@ -677,13 +685,13 @@ def test_estimator_warnings(): MetadataRequest(owner="test"), "{}", ), - (MethodMapping.from_str("score"), "[{'callee': 'score', 'caller': 'score'}]"), ( MetadataRouter(owner="test").add( - method_mapping="predict", estimator=ConsumingRegressor() + estimator=ConsumingRegressor(), + method_mapping=MethodMapping().add(caller="predict", callee="predict"), ), ( - "{'estimator': {'mapping': [{'callee': 'predict', 'caller':" + "{'estimator': {'mapping': [{'caller': 'predict', 'callee':" " 'predict'}], 'router': {'fit': {'sample_weight': None, 'metadata':" " None}, 'partial_fit': {'sample_weight': None, 'metadata': None}," " 'predict': {'sample_weight': None, 'metadata': None}, 'score':" @@ -702,24 +710,17 @@ def test_string_representations(obj, string): ( MethodMapping(), "add", - {"callee": "invalid", "caller": "fit"}, + {"caller": "fit", "callee": "invalid"}, ValueError, "Given callee", ), ( MethodMapping(), "add", - {"callee": "fit", "caller": "invalid"}, + {"caller": "invalid", "callee": "fit"}, ValueError, "Given caller", ), - ( - MethodMapping, - "from_str", - {"route": "invalid"}, - ValueError, - "route should be 'one-to-one' or a single method!", - ), ( MetadataRouter(owner="test"), "add_self_request", @@ -749,16 +750,17 @@ def test_methodmapping(): ) mm_list = list(mm) - assert mm_list[0] == ("transform", "fit") + assert mm_list[0] == ("fit", "transform") assert mm_list[1] == ("fit", "fit") - mm = MethodMapping.from_str("one-to-one") + mm = MethodMapping() for method in METHODS: + mm.add(caller=method, callee=method) assert MethodPair(method, method) in mm._routes assert len(mm._routes) == len(METHODS) - mm = MethodMapping.from_str("score") - assert repr(mm) == "[{'callee': 'score', 'caller': 'score'}]" + mm = MethodMapping().add(caller="score", callee="score") + assert repr(mm) == "[{'caller': 'score', 'callee': 'score'}]" def test_metadatarouter_add_self_request(): @@ -793,12 +795,12 @@ def test_metadatarouter_add_self_request(): def test_metadata_routing_add(): # adding one with a string `method_mapping` router = MetadataRouter(owner="test").add( - method_mapping="fit", est=ConsumingRegressor().set_fit_request(sample_weight="weights"), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) assert ( str(router) - == "{'est': {'mapping': [{'callee': 'fit', 'caller': 'fit'}], 'router': {'fit':" + == "{'est': {'mapping': [{'caller': 'fit', 'callee': 'fit'}], 'router': {'fit':" " {'sample_weight': 'weights', 'metadata': None}, 'partial_fit':" " {'sample_weight': None, 'metadata': None}, 'predict': {'sample_weight':" " None, 'metadata': None}, 'score': {'sample_weight': None, 'metadata':" @@ -807,12 +809,12 @@ def test_metadata_routing_add(): # adding one with an instance of MethodMapping router = MetadataRouter(owner="test").add( - method_mapping=MethodMapping().add(callee="score", caller="fit"), + method_mapping=MethodMapping().add(caller="fit", callee="score"), est=ConsumingRegressor().set_score_request(sample_weight=True), ) assert ( str(router) - == "{'est': {'mapping': [{'callee': 'score', 'caller': 'fit'}], 'router':" + == "{'est': {'mapping': [{'caller': 'fit', 'callee': 'score'}], 'router':" " {'fit': {'sample_weight': None, 'metadata': None}, 'partial_fit':" " {'sample_weight': None, 'metadata': None}, 'predict': {'sample_weight':" " None, 'metadata': None}, 'score': {'sample_weight': True, 'metadata':" @@ -829,17 +831,17 @@ def test_metadata_routing_get_param_names(): ) ) .add( - method_mapping="fit", trs=ConsumingTransformer().set_fit_request( sample_weight="transform_weights" ), + method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) ) assert ( str(router) == "{'$self_request': {'fit': {'sample_weight': 'self_weights'}, 'score':" - " {'sample_weight': None}}, 'trs': {'mapping': [{'callee': 'fit', 'caller':" + " {'sample_weight': None}}, 'trs': {'mapping': [{'caller': 'fit', 'callee':" " 'fit'}], 'router': {'fit': {'sample_weight': 'transform_weights'," " 'metadata': None}, 'transform': {'sample_weight': None, 'metadata': None}," " 'inverse_transform': {'sample_weight': None, 'metadata': None}}}}" diff --git a/sklearn/utils/_metadata_requests.py b/sklearn/utils/_metadata_requests.py index 4acac0f9fd2..f7305396211 100644 --- a/sklearn/utils/_metadata_requests.py +++ b/sklearn/utils/_metadata_requests.py @@ -693,19 +693,18 @@ RouterMappingPair = namedtuple("RouterMappingPair", ["mapping", "router"]) # A namedtuple storing a single method route. A collection of these namedtuples # is stored in a MetadataRouter. -MethodPair = namedtuple("MethodPair", ["callee", "caller"]) +MethodPair = namedtuple("MethodPair", ["caller", "callee"]) class MethodMapping: - """Stores the mapping between callee and caller methods for a router. + """Stores the mapping between caller and callee methods for a router. This class is primarily used in a ``get_metadata_routing()`` of a router object when defining the mapping between a sub-object (a sub-estimator or a - scorer) to the router's methods. It stores a collection of ``Route`` - namedtuples. + scorer) to the router's methods. It stores a collection of namedtuples. Iterating through an instance of this class will yield named - ``MethodPair(callee, caller)`` tuples. + ``MethodPair(caller, callee)`` tuples. .. versionadded:: 1.3 """ @@ -716,33 +715,34 @@ class MethodMapping: def __iter__(self): return iter(self._routes) - def add(self, *, callee, caller): + def add(self, *, caller, callee): """Add a method mapping. Parameters ---------- - callee : str - Child object's method name. This method is called in ``caller``. caller : str Parent estimator's method name in which the ``callee`` is called. + callee : str + Child object's method name. This method is called in ``caller``. + Returns ------- self : MethodMapping Returns self. """ - if callee not in METHODS: - raise ValueError( - f"Given callee:{callee} is not a valid method. Valid methods are:" - f" {METHODS}" - ) if caller not in METHODS: raise ValueError( f"Given caller:{caller} is not a valid method. Valid methods are:" f" {METHODS}" ) - self._routes.append(MethodPair(callee=callee, caller=caller)) + if callee not in METHODS: + raise ValueError( + f"Given callee:{callee} is not a valid method. Valid methods are:" + f" {METHODS}" + ) + self._routes.append(MethodPair(caller=caller, callee=callee)) return self def _serialize(self): @@ -755,38 +755,9 @@ class MethodMapping: """ result = list() for route in self._routes: - result.append({"callee": route.callee, "caller": route.caller}) + result.append({"caller": route.caller, "callee": route.callee}) return result - @classmethod - def from_str(cls, route): - """Construct an instance from a string. - - Parameters - ---------- - route : str - A string representing the mapping, it can be: - - - `"one-to-one"`: a one to one mapping for all methods. - - `"method"`: the name of a single method, such as ``fit``, - ``transform``, ``score``, etc. - - Returns - ------- - obj : MethodMapping - A :class:`~sklearn.utils.metadata_routing.MethodMapping` instance - constructed from the given string. - """ - routing = cls() - if route == "one-to-one": - for method in METHODS: - routing.add(callee=method, caller=method) - elif route in METHODS: - routing.add(callee=route, caller=route) - else: - raise ValueError("route should be 'one-to-one' or a single method!") - return routing - def __repr__(self): return str(self._serialize()) @@ -868,10 +839,8 @@ class MetadataRouter: Parameters ---------- - method_mapping : MethodMapping or str - The mapping between the child and the parent's methods. If str, the - output of :func:`~sklearn.utils.metadata_routing.MethodMapping.from_str` - is used. + method_mapping : MethodMapping + The mapping between the child and the parent's methods. **objs : dict A dictionary of objects from which metadata is extracted by calling @@ -882,10 +851,7 @@ class MetadataRouter: self : MetadataRouter Returns `self`. """ - if isinstance(method_mapping, str): - method_mapping = MethodMapping.from_str(method_mapping) - else: - method_mapping = deepcopy(method_mapping) + method_mapping = deepcopy(method_mapping) for name, obj in objs.items(): self._route_mappings[name] = RouterMappingPair( @@ -916,7 +882,7 @@ class MetadataRouter: res = res | self._self_request.consumes(method=method, params=params) for _, route_mapping in self._route_mappings.items(): - for callee, caller in route_mapping.mapping: + for caller, callee in route_mapping.mapping: if caller == method: res = res | route_mapping.router.consumes( method=callee, params=params @@ -959,7 +925,7 @@ class MetadataRouter: ) for name, route_mapping in self._route_mappings.items(): - for callee, caller in route_mapping.mapping: + for caller, callee in route_mapping.mapping: if caller == method: res = res.union( route_mapping.router._get_param_names( @@ -1065,7 +1031,7 @@ class MetadataRouter: router, mapping = route_mapping.router, route_mapping.mapping res[name] = Bunch() - for _callee, _caller in mapping: + for _caller, _callee in mapping: if _caller == caller: res[name][_callee] = router._route_params( params=params, @@ -1127,12 +1093,11 @@ class MetadataRouter: def __iter__(self): if self._self_request: - yield ( - "$self_request", - RouterMappingPair( - mapping=MethodMapping.from_str("one-to-one"), - router=self._self_request, - ), + method_mapping = MethodMapping() + for method in METHODS: + method_mapping.add(caller=method, callee=method) + yield "$self_request", RouterMappingPair( + mapping=method_mapping, router=self._self_request ) for name, route_mapping in self._route_mappings.items(): yield (name, route_mapping)