| OLD | NEW |
| 1 # Copyright 2013-2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2013-2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import collections | 5 import collections |
| 6 import contextlib | 6 import contextlib |
| 7 import imp | 7 import imp |
| 8 import inspect | 8 import inspect |
| 9 import os | 9 import os |
| 10 import sys | 10 import sys |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 self._instances = {} | 474 self._instances = {} |
| 475 | 475 |
| 476 def instantiate(self, mod): | 476 def instantiate(self, mod): |
| 477 if mod in self._instances: | 477 if mod in self._instances: |
| 478 return self._instances[mod] | 478 return self._instances[mod] |
| 479 deps_dict = { name: self.instantiate(dep) | 479 deps_dict = { name: self.instantiate(dep) |
| 480 for name, dep in mod.LOADED_DEPS.iteritems() } | 480 for name, dep in mod.LOADED_DEPS.iteritems() } |
| 481 self._instances[mod] = self._instantiator(mod, deps_dict) | 481 self._instances[mod] = self._instantiator(mod, deps_dict) |
| 482 return self._instances[mod] | 482 return self._instances[mod] |
| 483 | 483 |
| 484 | |
| 485 def _invoke_with_properties(callable_obj, all_props, prop_defs, arg_names, | 484 def _invoke_with_properties(callable_obj, all_props, prop_defs, arg_names, |
| 486 **additional_args): | 485 **additional_args): |
| 487 """Internal version of invoke_with_properties. | 486 """Internal version of invoke_with_properties. |
| 488 | 487 |
| 489 The main difference is it gets passed the argument names as `arg_names`. | 488 The main difference is it gets passed the argument names as `arg_names`. |
| 490 This allows us to reuse this logic elsewhere, without defining a fake function | 489 This allows us to reuse this logic elsewhere, without defining a fake function |
| 491 which has arbitrary argument names. | 490 which has arbitrary argument names. |
| 492 """ | 491 """ |
| 493 for name, prop in prop_defs.items(): | 492 for name, prop in prop_defs.items(): |
| 494 if not isinstance(prop, BoundProperty): | 493 if not isinstance(prop, BoundProperty): |
| 495 raise ValueError( | 494 raise ValueError( |
| 496 "You tried to invoke {} with an unbound Property {} named {}".format( | 495 "You tried to invoke {} with an unbound Property {} named {}".format( |
| 497 callable, prop, name)) | 496 callable, prop, name)) |
| 498 | 497 |
| 499 # Maps parameter names to property names | |
| 500 param_name_mapping = { | |
| 501 prop.param_name: name for name, prop in prop_defs.iteritems()} | |
| 502 | |
| 503 props = [] | 498 props = [] |
| 504 | 499 for arg in arg_names: |
| 505 for param_name in arg_names: | 500 if arg in additional_args: |
| 506 if param_name in additional_args: | 501 props.append(additional_args.pop(arg)) |
| 507 props.append(additional_args.pop(param_name)) | |
| 508 continue | 502 continue |
| 509 | 503 |
| 510 if param_name not in param_name_mapping: | 504 if arg not in prop_defs: |
| 511 raise UndefinedPropertyException( | 505 raise UndefinedPropertyException( |
| 512 "Missing property definition for parameter '{}'.".format(param_name)) | 506 "Missing property definition for '{}'.".format(arg)) |
| 513 | 507 |
| 514 prop_name = param_name_mapping[param_name] | 508 prop = prop_defs[arg] |
| 515 | |
| 516 if prop_name not in prop_defs: | |
| 517 raise UndefinedPropertyException( | |
| 518 "Missing property value for '{}'.".format(prop_name)) | |
| 519 | |
| 520 prop = prop_defs[prop_name] | |
| 521 props.append(prop.interpret(all_props.get( | 509 props.append(prop.interpret(all_props.get( |
| 522 prop_name, PROPERTY_SENTINEL))) | 510 prop.param_name, PROPERTY_SENTINEL))) |
| 523 | 511 |
| 524 return callable_obj(*props, **additional_args) | 512 return callable_obj(*props, **additional_args) |
| 525 | 513 |
| 526 | |
| 527 def invoke_with_properties(callable_obj, all_props, prop_defs, | 514 def invoke_with_properties(callable_obj, all_props, prop_defs, |
| 528 **additional_args): | 515 **additional_args): |
| 529 """ | 516 """ |
| 530 Invokes callable with filtered, type-checked properties. | 517 Invokes callable with filtered, type-checked properties. |
| 531 | 518 |
| 532 Args: | 519 Args: |
| 533 callable_obj: The function to call, or class to instantiate. | 520 callable_obj: The function to call, or class to instantiate. |
| 534 This supports passing in either RunSteps, or a recipe module, | 521 This supports passing in either RunSteps, or a recipe module, |
| 535 which is a class. | 522 which is a class. |
| 536 all_props: A dictionary containing all the properties (strings) currently | 523 all_props: A dictionary containing all the properties (instances of BoundPro
perty) |
| 537 defined in the system. | 524 currently defined in the system. |
| 538 prop_defs: A dictionary of property name to property definitions | 525 prop_defs: A dictionary of name to property definitions for this callable. |
| 539 (BoundProperty) for this callable. | |
| 540 additional_args: kwargs to pass through to the callable. | 526 additional_args: kwargs to pass through to the callable. |
| 541 Note that the names of the arguments can correspond to | 527 Note that the names of the arguments can correspond to |
| 542 positional arguments as well. | 528 positional arguments as well. |
| 543 | 529 |
| 544 Returns: | 530 Returns: |
| 545 The result of calling callable with the filtered properties | 531 The result of calling callable with the filtered properties |
| 546 and additional arguments. | 532 and additional arguments. |
| 547 """ | 533 """ |
| 548 # Check that we got passed BoundProperties, and not Properties | 534 # Check that we got passed BoundProperties, and not Properties |
| 549 | 535 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 modapi = (getattr(mod, 'TEST_API', None) or RecipeTestApi)(module=mod) | 580 modapi = (getattr(mod, 'TEST_API', None) or RecipeTestApi)(module=mod) |
| 595 for k,v in deps.iteritems(): | 581 for k,v in deps.iteritems(): |
| 596 setattr(modapi.m, k, v) | 582 setattr(modapi.m, k, v) |
| 597 return modapi | 583 return modapi |
| 598 | 584 |
| 599 mapper = DependencyMapper(instantiator) | 585 mapper = DependencyMapper(instantiator) |
| 600 api = RecipeTestApi(module=None) | 586 api = RecipeTestApi(module=None) |
| 601 for k,v in toplevel_deps.iteritems(): | 587 for k,v in toplevel_deps.iteritems(): |
| 602 setattr(api, k, mapper.instantiate(v)) | 588 setattr(api, k, mapper.instantiate(v)) |
| 603 return api | 589 return api |
| OLD | NEW |