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