Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 1 | # $Copyright: |
| 2 | # ---------------------------------------------------------------- |
| 3 | # This confidential and proprietary software may be used only as |
| 4 | # authorised by a licensing agreement from ARM Limited |
| 5 | # (C) COPYRIGHT 2015 ARM Limited |
| 6 | # ALL RIGHTS RESERVED |
| 7 | # The entire notice above must be reproduced on all authorised |
| 8 | # copies and copies may only be made to the extent permitted |
| 9 | # by a licensing agreement from ARM Limited. |
| 10 | # ---------------------------------------------------------------- |
| 11 | # File: dynamic.py |
| 12 | # ---------------------------------------------------------------- |
| 13 | # $ |
| 14 | # |
| 15 | |
| 16 | """The idea is to create a wrapper class that |
| 17 | returns a Type of a Class dynamically created based |
| 18 | on the input parameters. Similar to a factory design |
| 19 | pattern |
| 20 | """ |
| 21 | from cr2.base import Base |
| 22 | import re |
| 23 | from cr2.run import Run |
| 24 | |
| 25 | |
| 26 | def default_init(self, path=None): |
| 27 | """Default Constructor for the |
| 28 | Dynamic MetaClass |
| 29 | """ |
| 30 | |
| 31 | super(type(self), self).__init__( |
| 32 | basepath=path, |
| 33 | unique_word=self.unique_word, |
| 34 | ) |
| 35 | |
| 36 | |
| 37 | class DynamicTypeFactory(type): |
| 38 | |
| 39 | """Override the type class to create |
| 40 | a dynamic type on the fly |
| 41 | """ |
| 42 | |
| 43 | def __new__(mcs, name, bases, dct): |
| 44 | """Override the new method""" |
| 45 | return type.__new__(mcs, name, bases, dct) |
| 46 | |
| 47 | def __init__(cls, name, bases, dct): |
| 48 | """Override the constructor""" |
| 49 | super(DynamicTypeFactory, cls).__init__(name, bases, dct) |
| 50 | |
| 51 | |
| 52 | def _get_name(name): |
| 53 | """Internal Method to Change camelcase to |
| 54 | underscores. CamelCase -> camel_case |
| 55 | """ |
| 56 | return re.sub('(?!^)([A-Z]+)', r'_\1', name).lower() |
| 57 | |
| 58 | |
| 59 | def register_dynamic(class_name, unique_word, scope="all"): |
| 60 | """Create a Dynamic Type and register |
| 61 | it with the cr2 Framework""" |
| 62 | |
| 63 | dyn_class = DynamicTypeFactory( |
| 64 | class_name, (Base,), { |
| 65 | "__init__": default_init, |
| 66 | "unique_word": unique_word, |
| 67 | "name": _get_name(class_name) |
| 68 | } |
| 69 | ) |
| 70 | Run.register_class(dyn_class, scope) |
| 71 | return dyn_class |
| 72 | |
| 73 | |
| 74 | def register_class(cls): |
| 75 | """Register a new class implementation |
| 76 | Should be used when the class has |
| 77 | complex helper methods and does not |
| 78 | expect to use the default constructor |
| 79 | """ |
| 80 | |
| 81 | # Check the argspec of the class |
| 82 | Run.register_class(cls) |