def serialize(cust_obj): """A function to serialize custom objects passed to a model Args: cust_obj(callable): a custom layer or function to serialize Returns: a dict of the serialized components of the object""" ser_func = dict() if isinstance(cust_obj, types.FunctionType): func_code = six.get_function_code(cust_obj) func_code_d = dill.dumps(func_code).decode('raw_unicode_escape') ser_func['func_code_d'] = func_code_d ser_func['name_d'] = pickle.dumps( cust_obj.__name__).decode('raw_unicode_escape') ser_func['args_d'] = pickle.dumps( six.get_function_defaults(cust_obj)).decode('raw_unicode_escape') clos = dill.dumps( six.get_function_closure(cust_obj)).decode('raw_unicode_escape') ser_func['clos_d'] = clos ser_func['type_obj'] = 'func' else: if hasattr(cust_obj, '__module__'): # pragma: no cover cust_obj.__module__ = '__main__' ser_func['name_d'] = None ser_func['args_d'] = None ser_func['clos_d'] = None ser_func['type_obj'] = 'class' loaded = dill.dumps(cust_obj).decode('raw_unicode_escape') ser_func['func_code_d'] = loaded return ser_func
def _build_new_function(func, name): code = six.get_function_code(func) func_globals = six.get_function_globals(func) func_defaults = six.get_function_defaults(func) func_closure = six.get_function_closure(func) return types.FunctionType(code, func_globals, name, func_defaults, func_closure)
def construct_new_test_function(original_func, name, build_params): """Builds a new test function based on parameterized data. :param original_func: The original test function that is used as a template :param name: The fullname of the new test function :param build_params: A dictionary or list containing args or kwargs for the new test :return: A new function object """ new_func = types.FunctionType( six.get_function_code(original_func), six.get_function_globals(original_func), name=name, argdefs=six.get_function_defaults(original_func) ) # Support either an arg list or kwarg dict for our data build_args = build_params if isinstance(build_params, list) else [] build_kwargs = build_params if isinstance(build_params, dict) else {} # Build a test wrapper to execute with our kwargs def test_wrapper(func, test_args, test_kwargs): @functools.wraps(func) def wrapper(self): return func(self, *test_args, **test_kwargs) return wrapper return test_wrapper(new_func, build_args, build_kwargs)
def infrastructure( confirm=True, color=colors.yellow, autoconfirm_env_var='FABRICIO_INFRASTRUCTURE_AUTOCONFIRM', ): def _decorator(task): @functools.wraps(task) def _task(*args, **kwargs): if confirm: confirmed = utils.yes(os.environ.get(autoconfirm_env_var, 0)) if not confirmed and not console.confirm( 'Are you sure you want to select {infrastructure} ' 'infrastructure to run task(s) on?'.format( infrastructure=color(task.__name__), ), default=False, ): fab.abort('Aborted') fab.env.infrastructure = task.__name__ return task(*args, **kwargs) return fab.task(_task) fab.env.setdefault('infrastructure', None) if callable(confirm): func, confirm = confirm, six.get_function_defaults(infrastructure)[0] return _decorator(func) return _decorator
def get_required_fixtures(obj): '''Get fixture names required by given :param obj:''' required_names = getattr(obj, '__tobiko_required_fixtures__', None) if required_names is None: if is_test_method(obj): # Get fixtures from default values that are fixtures required = { default for default in six.get_function_defaults(obj) or [] if is_fixture(default) } elif inspect.isclass(obj): # Get fixtures from members of type RequiredFixtureProperty required = { prop.fixture for prop in get_required_fixture_properties(obj) } else: # Other types have no fixtures required = set() # Return every fixture name only once required_names = sorted( [get_fixture_name(fixture) for fixture in required]) try: # try to cache list for later use obj.__tobiko_required_fixtures__ = required_names except AttributeError: pass return required_names
def get_function_arguments(func): """Return (args, kwargs) for func, excluding `self`""" code = six.get_function_code(func) defaults = six.get_function_defaults(func) or [] arg_names = [var for var in code.co_varnames[: code.co_argcount] if var != "self"] n_required = len(arg_names) - len(defaults) return arg_names[:n_required], arg_names[n_required:]
def wrapped(cls, *args, **kwargs): def is_mod_of_all(user, subreddit): mod_subs = user.get_cached_moderated_reddits() subs = six.text_type(subreddit).lower().split('+') return all(sub in mod_subs for sub in subs) if cls is None: # Occurs with (un)friend assert login raise errors.LoginRequired(function.__name__) # This segment of code uses hasattr to determine what instance type # the function was called on. We could use isinstance if we wanted # to import the types at runtime (decorators is used by all the # types). if mod: if hasattr(cls, 'reddit_session'): # Defer access until necessary for RedditContentObject. # This is because scoped sessions may not require this # attribute to exist, thus it might not be set. subreddit = cls if hasattr(cls, '_fast_name') else False else: subreddit = kwargs.get('subreddit', args[0] if args else None) if subreddit is None: # Try the default value defaults = six.get_function_defaults(function) subreddit = defaults[0] if defaults else None else: subreddit = None obj = getattr(cls, 'reddit_session', cls) # This function sets _use_oauth for one time use only. # Verify that statement is actually true. assert not obj._use_oauth # pylint: disable=W0212 if scope and obj.has_scope(scope): obj._use_oauth = True # pylint: disable=W0212 elif oauth_only: raise errors.OAuthScopeRequired(function.__name__, scope) elif login and obj.is_logged_in(): if subreddit is False: # Now fetch the subreddit attribute. There is no good # reason for it to not be set during a logged in session. subreddit = cls.subreddit if mod and not is_mod_of_all(obj.user, subreddit): if scope: raise errors.ModeratorOrScopeRequired( function.__name__, scope) raise errors.ModeratorRequired(function.__name__) elif login: if scope: raise errors.LoginOrScopeRequired(function.__name__, scope) raise errors.LoginRequired(function.__name__) try: return function(cls, *args, **kwargs) finally: obj._use_oauth = False # pylint: disable=W0212
def wrapped(cls, *args, **kwargs): def is_mod_of_all(user, subreddit): mod_subs = user.get_cached_moderated_reddits() subs = six.text_type(subreddit).lower().split('+') return all(sub in mod_subs for sub in subs) if cls is None: # Occurs with (un)friend assert login raise errors.LoginRequired(function.__name__) # This segment of code uses hasattr to determine what instance type # the function was called on. We could use isinstance if we wanted # to import the types at runtime (decorators is used by all the # types). if mod: if hasattr(cls, 'reddit_session'): # Defer access until necessary for RedditContentObject. # This is because scoped sessions may not require this # attribute to exist, thus it might not be set. subreddit = cls if hasattr(cls, '_fast_name') else False else: subreddit = kwargs.get( 'subreddit', args[0] if args else None) if subreddit is None: # Try the default value defaults = six.get_function_defaults(function) subreddit = defaults[0] if defaults else None else: subreddit = None obj = getattr(cls, 'reddit_session', cls) # This function sets _use_oauth for one time use only. # Verify that statement is actually true. assert not obj._use_oauth # pylint: disable=W0212 if scope and obj.has_scope(scope): obj._use_oauth = True # pylint: disable=W0212 elif oauth_only: raise errors.OAuthScopeRequired(function.__name__, scope) elif login and obj.is_logged_in(): if subreddit is False: # Now fetch the subreddit attribute. There is no good # reason for it to not be set during a logged in session. subreddit = cls.subreddit if mod and not is_mod_of_all(obj.user, subreddit): if scope: raise errors.ModeratorOrScopeRequired( function.__name__, scope) raise errors.ModeratorRequired(function.__name__) elif login: if scope: raise errors.LoginOrScopeRequired(function.__name__, scope) raise errors.LoginRequired(function.__name__) try: return function(cls, *args, **kwargs) finally: obj._use_oauth = False # pylint: disable=W0212
def get_function_arguments(func): """Return (args, kwargs) for func, excluding `self`""" code = six.get_function_code(func) defaults = six.get_function_defaults(func) or [] arg_names = [ var for var in code.co_varnames[:code.co_argcount] if var != 'self' ] n_required = len(arg_names) - len(defaults) return arg_names[:n_required], arg_names[n_required:]
def _update_function(oldfunc, newfunc): """Update a function object.""" if _closure_changed(six.get_function_closure(oldfunc), six.get_function_closure(newfunc)): raise ClosureChanged() setattr(oldfunc, six._func_code, six.get_function_code(newfunc)) setattr(oldfunc, six._func_defaults, six.get_function_defaults(newfunc)) _update_scope(six.get_function_globals(oldfunc), six.get_function_globals(newfunc)) # XXX What else? return oldfunc
def copy_func(f, name=None): """Create a copy of a function. Parameters ---------- f : function Function to copy. name : str, optional Name of new function. """ return types.FunctionType(six.get_function_code(f), six.get_function_globals(f), name or f.__name__, six.get_function_defaults(f), six.get_function_closure(f))
def reset_defaults(function): import six from copy import deepcopy defaults = six.get_function_defaults(function) def decorator(*args, **kwargs): if six.PY3: function.__defaults__ = deepcopy(defaults) else: function.func_defaults = deepcopy(defaults) return function(*args, **kwargs) decorator.__name__ = function.__name__ decorator.__doc__ = function.__doc__ return decorator
def named_decorator(wrapper, wrapped, decorator): """Takes a wrapper, a wrapped function and a decorator and renames the wrapper to look like wrapped@wrapper :param wrapper: wrapper returned by the decorator :type wrapper: function :param wrapped: wrapped function :type wrapped: function :param decorator: outer decorator :type decorator: function Usage:: def with_log_and_call(log_message): def wrapper(method): def inner_wrapper(*args, **kwargs): print(log_message) return method(*args, **kargs) return named_decorator(inner_wrapper, method, with_log_and_call) return wrapper """ if (getattr(wrapped, '__name__', None) is None or getattr(decorator, '__name__', None) is None): # If the wrapped function does not have a name, abort since we can't # assign a better name. This can happen if you're trying to wrap # function-like objects. return wrapper c = get_function_code(wrapper) updated_decorator_name = '{}@{}'.format( wrapped.__name__, decorator.__name__, ) code_type_args = code_type_args_for_rename(c, updated_decorator_name) code = CodeType(*code_type_args) updated_decorator = FunctionType( code, # Use our updated code object get_function_globals(wrapper), updated_decorator_name, get_function_defaults(wrapper), get_function_closure(wrapper), ) return functools.update_wrapper(updated_decorator, wrapped)
def save_function(pickler, obj): if not _locate_function(obj, pickler): log.info("F1: %s" % obj) globs = get_function_globals(obj) mod_name = obj.__module__ pickler.save_reduce(_create_function, (get_function_code(obj), {}, obj.__name__, get_function_defaults(obj), get_function_closure(obj), obj.__dict__, mod_name), obj=obj, func_globals=globs) log.info("# F1 %s" % obj) else: log.info("F2: %s" % obj) StockPickler.save_global(pickler, obj) log.info("# F2 %s" % obj) return
def _fetch_argnames_argvalues(method, args, kwargs): # argnames = inspect.getargspec(method)[0] nargs = six.get_function_code(method).co_argcount names = six.get_function_code(method).co_varnames argnames = list(names[:nargs]) if len(argnames) == 0: return ([],[]) if len(argnames) == 1 and argnames[0] == 'self': return ([],[]) if argnames[0] == 'self': del argnames[0] defaults = six.get_function_defaults(method) if defaults is None: defaults = [] argvalues = _map_args_kwargs_to_argvalues(args, kwargs, argnames, defaults) return (argnames, argvalues)
def _fetch_argnames_argvalues(method, args, kwargs): # argnames = inspect.getargspec(method)[0] nargs = six.get_function_code(method).co_argcount names = six.get_function_code(method).co_varnames argnames = list(names[:nargs]) if len(argnames) == 0: return ([], []) if len(argnames) == 1 and argnames[0] == 'self': return ([], []) if argnames[0] == 'self': del argnames[0] defaults = six.get_function_defaults(method) if defaults is None: defaults = [] argvalues = _map_args_kwargs_to_argvalues(args, kwargs, argnames, defaults) return (argnames, argvalues)
def _generate_params_from_function(func): """Generate Parameters from function arguments. Will set the Parameter key, default value, and optional value.""" parameters_to_return = [] code = six.get_function_code(func) function_arguments = list(code.co_varnames or [])[:code.co_argcount] function_defaults = list(six.get_function_defaults(func) or []) while len(function_defaults) != len(function_arguments): function_defaults.insert(0, None) for index, param_name in enumerate(function_arguments): # Skip Self or Class reference if index == 0 and isinstance(func, types.FunctionType): continue default = function_defaults[index] optional = False if default is None else True parameters_to_return.append( Parameter(key=param_name, default=default, optional=optional)) return parameters_to_return
def test_get_function_defaults(): def f(x, y=3, b=4): pass assert six.get_function_defaults(f) == (3, 4)
import functools import gc import os import pytest import six default_scope = six.get_function_defaults(pytest.fixture)[0] scope = os.environ.get("gc_scope", default_scope) @pytest.fixture(scope, autouse=True) def switch(request): if request.config.getoption("gc_disable"): request.addfinalizer(gc.enable) gc.disable() @pytest.fixture(scope, autouse=True) def change_threshold(request): threshold = request.config.getoption("gc_threshold") if threshold: request.addfinalizer( functools.partial(gc.set_threshold, *gc.get_threshold()) ) gc.set_threshold(*threshold)
def _RedirectEntryPoint(function_name, entry_point, config): assert function_name assert entry_point assert config # <Use of exec> pylint: disable = W0122 # <Use of eval> pylint: disable = W0123 required_arguments = [] if config.Configurations: if function_name != "Clean" or config.ConfigurationRequiredOnClean: assert "configuration" in entry_point.ConstraintsDecorator.Preconditions, function_name entry_point.ConstraintsDecorator.Preconditions["configuration"] = CommandLine.EnumTypeInfo(config.Configurations) required_arguments.append("configuration") if config.RequiresOutputDir: required_arguments.append("output_dir") num_required_args = six.get_function_code(entry_point.Function).co_argcount - len(list(six.get_function_defaults(entry_point.Function) or [])) arguments = six.get_function_code(entry_point.Function).co_varnames[:num_required_args] if required_arguments and list(arguments[:len(required_arguments) + 1]) != required_arguments: raise Exception("The entry point '{}' should begin with the arguments '{}' ('{}' were found)".format( function_name, ', '.join(required_arguments), ', '.join(arguments), )) # Dynamically redefine the function so that it prints information that lets the user know the the # functionality can't be executed on the current platform/configuration/environment. if config.RequiredDevelopmentEnvironment and config.RequiredDevelopmentEnvironment.lower() not in [ CurrentShell.Name.lower(), CurrentShell.CategoryName.lower(), ]: exec(textwrap.dedent( """\ def {name}({args}): sys.stdout.write("\\nINFO: This can only be run on '{env}'.\\n") return 0 """).format( name=function_name, args=', '.join(arguments), env=config.RequiredDevelopmentEnvironment, )) entry_point.Function = eval(function_name) elif config.RequiredDevelopmentConfigurations and not _RedirectEntryPoint_IsSupportedDevelopmentConfiguration(config.RequiredDevelopmentConfigurations): exec(textwrap.dedent( """\ def {name}({args}): sys.stdout.write("\\nINFO: This can only be run in development environments activated with the configurations {configs}.\\n") return 0 """).format( name=function_name, args=', '.join(arguments), configs=', '.join([ "'{}'".format(configuration) for configuration in config.RequiredDevelopmentConfigurations ]), )) entry_point.Function = eval(function_name) elif config.DisableIfDependencyEnvironment: repo_path = os.getenv(RepositoryBootstrapConstants.DE_REPO_ROOT_NAME) if FileSystem.GetCommonPath(repo_path, inspect.getfile(entry_point.Function)).rstrip(os.path.sep) != repo_path: exec(textwrap.dedent( """\ def {name}({args}): sys.stdout.write("\\nINFO: This module is not build when invoked as a dependency.\\n") return 0 """).format( name=function_name, args=', '.join(arguments), )) entry_point.Function = eval(function_name)
def setUp(self): # http://effbot.org/zone/default-values.htm six.get_function_defaults(do_tally)[0][:] = [] pass
def func_defaults(self): return six.get_function_defaults(self.bobo_original)
def main(args): if args.list: templates = shellcraft.templates if args.shellcode: templates = filter(lambda a: args.shellcode in a, templates) elif not args.syscalls: templates = filter(is_not_a_syscall_template, templates) print('\n'.join(templates)) exit() if not args.shellcode: common.parser.print_usage() exit() try: func = get_template(args.shellcode) except AttributeError: log.error( "Unknown shellcraft template %r. Use --list to see available shellcodes." % args.shellcode) if args.show: # remove doctests doc = [] in_doctest = False block_indent = None caption = None lines = func.__doc__.splitlines() i = 0 while i < len(lines): line = lines[i] if line.lstrip().startswith('>>>'): # this line starts a doctest in_doctest = True block_indent = None if caption: # delete back up to the caption doc = doc[:caption - i] caption = None elif line == '': # skip blank lines pass elif in_doctest: # indentation marks the end of a doctest indent = len(line) - len(line.lstrip()) if block_indent is None: if not line.lstrip().startswith('...'): block_indent = indent elif indent < block_indent: in_doctest = False block_indent = None # re-evalutate this line continue elif line.endswith(':'): # save index of caption caption = i else: # this is not blank space and we're not in a doctest, so the # previous caption (if any) was not for a doctest caption = None if not in_doctest: doc.append(line) i += 1 print('\n'.join(doc).rstrip()) exit() defargs = len(six.get_function_defaults(func) or ()) reqargs = six.get_function_code(func).co_argcount - defargs if len(args.args) < reqargs: if defargs > 0: log.critical('%s takes at least %d arguments' % (args.shellcode, reqargs)) sys.exit(1) else: log.critical('%s takes exactly %d arguments' % (args.shellcode, reqargs)) sys.exit(1) # Captain uglyness saves the day! for i, val in enumerate(args.args): try: args.args[i] = util.safeeval.expr(val) except ValueError: pass # And he strikes again! list(map(common.context_arg, args.shellcode.split('.'))) code = func(*args.args) if args.before: code = shellcraft.trap() + code if args.after: code = code + shellcraft.trap() if args.format in ['a', 'asm', 'assembly']: if args.color: from pygments import highlight from pygments.formatters import TerminalFormatter from pwnlib.lexer import PwntoolsLexer code = highlight(code, PwntoolsLexer(), TerminalFormatter()) print(code) exit() if args.format == 'p': print(cpp(code)) exit() assembly = code vma = args.address if vma: vma = pwnlib.util.safeeval.expr(vma) if args.format in ['e', 'elf']: args.format = 'default' try: os.fchmod(args.out.fileno(), 0o700) except OSError: pass if not args.avoid: code = read( make_elf_from_assembly(assembly, vma=vma, shared=args.shared)) else: code = asm(assembly) code = encode(code, args.avoid) code = make_elf(code, vma=vma, shared=args.shared) # code = read(make_elf(encode(asm(code), args.avoid))) else: code = encode(asm(assembly), args.avoid) if args.format == 'default': if args.out.isatty(): args.format = 'hex' else: args.format = 'raw' arch = args.shellcode.split('.')[0] if args.debug: if not args.avoid: proc = gdb.debug_assembly(assembly, arch=arch, vma=vma) else: proc = gdb.debug_shellcode(code, arch=arch, vma=vma) proc.interactive() sys.exit(0) if args.run: proc = run_shellcode(code, arch=arch) proc.interactive() sys.exit(0) if args.format in ['s', 'str', 'string']: code = _string(code) elif args.format == 'c': code = '{' + ', '.join(map(hex, bytearray(code))) + '}' + '\n' elif args.format in ['h', 'hex']: code = pwnlib.util.fiddling.enhex(code) + '\n' elif args.format in ['i', 'hexii']: code = hexii(code) + '\n' elif args.format in ['d', 'escaped']: code = ''.join('\\x%02x' % c for c in bytearray(code)) + '\n' if not sys.stdin.isatty(): args.out.write(getattr(sys.stdin, 'buffer', sys.stdin).read()) if not hasattr(code, 'decode'): code = code.encode() args.out.write(code)
def _compilecode(function, name, impl, args, varargs, kwargs): """Get generated code. :return: function proxy generated code. :rtype: str """ newcodestr, generatedname, impl_name = _generatecode( function=function, name=name, impl=impl, args=args, varargs=varargs, kwargs=kwargs ) try: __file__ = getfile(function) except TypeError: __file__ = '<string>' # compile newcodestr code = compile(newcodestr, __file__, 'single') # define the code with the new function _globals = {} exec_(code, _globals) # get new code _var = _globals[generatedname] newco = get_function_code(_var) # get new consts list newconsts = list(newco.co_consts) if PY3: newcode = list(newco.co_code) else: newcode = [ord(co) for co in newco.co_code] consts_values = {impl_name: impl} # change LOAD_GLOBAL to LOAD_CONST index = 0 newcodelen = len(newcode) while index < newcodelen: if newcode[index] == LOAD_GLOBAL: oparg = newcode[index + 1] + (newcode[index + 2] << 8) name = newco.co_names[oparg] if name in consts_values: const_value = consts_values[name] if const_value in newconsts: pos = newconsts.index(const_value) else: pos = len(newconsts) newconsts.append(consts_values[name]) newcode[index] = LOAD_CONST newcode[index + 1] = pos & 0xFF newcode[index + 2] = pos >> 8 index += 1 codeobj = getcodeobj(newconsts, newcode, newco, get_function_code(function)) # instanciate a new function if function is None or isbuiltin(function): result = FunctionType(codeobj, {}) else: result = type(function)( codeobj, get_function_globals(function), function.__name__, get_function_defaults(function), get_function_closure(function) ) return result
def __new__(self, name, bases, dct): # enforce use of classmethod for getType() and setDefaults() if 'getType' in dct and not isinstance(dct['getType'], classmethod): dct['getType'] = classmethod(dct['getType']) if 'setDefaults' in dct and not isinstance(dct['setDefaults'], classmethod): dct['setDefaults'] = classmethod(dct['setDefaults']) # collect what are properties (basically, any public name; C++ variables # shouldn't start with an '_' because of portability constraints, hence # it is safe to assume that any such vars are python private ones) newclass = type.__new__(self, name, bases, dct) if 'AthenaCommon' not in newclass.__module__: # check for required methods and the right number of arguments # meths = { 'getServices' : 1, # retrieve list of services to configure meths = { 'getDlls': 1, # provide list of Dlls to load 'getGaudiType': 1, # return string describing component class 'getHandle': 1, # provide access to C++ side component instance 'getType': 1 } # return the type of the actual C++ component for meth, nArgs in meths.items(): try: f = six.get_unbound_function(getattr(newclass, meth)) except AttributeError: raise NotImplementedError("%s is missing in class %s" % (meth, str(newclass))) # in addition, verify the number of arguments w/o defaults nargcount = six.get_function_code(f).co_argcount dflts = six.get_function_defaults(f) ndefaults = dflts and len(dflts) or 0 if not nargcount - ndefaults <= nArgs <= nargcount: raise TypeError("%s.%s requires exactly %d arguments" % (newclass, meth, nArgs)) # cache references of instances by name for duplicate removal newclass.configurables = weakref.WeakValueDictionary() # loop over slots, which are all assumed to be properties, create proxies, defaults properties = {} slots = dct.get('__slots__') if slots: props = [x for x in slots if x[0] != '_'] propDict = dct.get('_propertyDocDct') for prop in props: docString = propDict and propDict.get(prop) if type(slots) == dict: default = slots[prop] else: default = None proxy = PropertyProxy.PropertyProxyFactory( getattr(newclass, prop), docString, default) properties[prop] = proxy setattr(newclass, prop, proxy) # complete set of properties includes those from base classes for base in bases: try: bprops = base._properties.copy() bprops.update(properties) properties = bprops except AttributeError: pass newclass._properties = properties return newclass
def __new__ ( cls, *args, **kwargs ): """To Gaudi, any object with the same type/name is the same object. Hence, this is mimicked in the configuration: instantiating a new Configurable of a type with the same name will return the same instance.""" # try to get the name of the Configurable (having a name is compulsory) if 'name' in kwargs: # simple keyword (by far the easiest) name = kwargs[ 'name' ] elif 'name' in six.get_function_code(cls.__init__).co_varnames: # either positional in args, or default index = list(six.get_function_code(cls.__init__).co_varnames).index( 'name' ) try: # var names index is offset by one as __init__ is to be called with self name = args[ index - 1 ] except IndexError: # retrieve default value, then name = six.get_function_defaults(cls.__init__)[ index - (len(args)+1) ] else: # positional index is assumed (will work most of the time) try: name = args[1] # '0' is for self except (IndexError,TypeError): raise TypeError( 'no "name" argument while instantiating "%s"' % cls.__name__ ) if name == Configurable.DefaultName: # select either conventional name, or the type of the class if hasattr( cls, 'DefaultedName' ): name = cls.DefaultedName else: name = cls.getType() elif not name or type(name) != str: # unnamed, highly specialized user code, etc. ... unacceptable raise TypeError( 'could not retrieve name from %s.__init__ arguments' % cls.__name__ ) # close backdoor access to otherwise private subalgs/tools if 0 <= name.find( '.' ): raise NameError( '"%s": Gaudi name indexing with "." to private configurables not ' 'allowed, as it leads to uncheckable backdoors' % name ) if 0 <= name.find( '/' ): raise NameError( '"%s": type separator "/" no allowed in component name, ' 'typename is derived from configurable instead' % name ) #Uncomment the following line for debugging: #print "cls.configurableRun3Behavior=",cls.configurableRun3Behavior if cls.configurableRun3Behavior==0: # ordinary recycle case try: conf = cls.configurables[ name ] # initialize additional properties, if any for n,v in kwargs.items(): try: setattr( conf, n, v ) except AttributeError as originalAttributeError: # rather annoying that we have to be somewhat silent here (the # most common cases are 'name' and user kw args to be supplied # to an overridden __init__) log.debug( 'not accepting keyword "%s" as a property', n ) # now for a completely different can of worms ... acceptableKeyWord = False # little helper def flat( classtree ): if isinstance( classtree, list ) or isinstance( classtree, tuple ): return [ j for i in classtree for j in flat( i ) ] else: return [ classtree ] # the following attempts to figure out if the missing attribute # is in fact an acceptable formal function argument to __init__, import inspect allclasses = flat( inspect.getclasstree( [ conf.__class__ ] ) ) for confklass in allclasses: try: # the following may result in the same init tried several # times, but we shouldn't be in this loop too often anyway confinit = getattr( confklass, '__init__' ) if n in six.get_function_code(confinit).co_varnames: log.debug( 'accepting keyword "%s" as an argument for %s.__init__', n, confklass.__name__ ) acceptableKeyWord = True break except AttributeError: pass # raising here will break the usage of keywords in __init__, but # there don't appear to be such cases in ATLAS yet ... if not acceptableKeyWord: raise originalAttributeError return conf except KeyError: pass else: #Run 3 style config #Uncomment this line to verify that RecExCommon doesn't use that #print "Run 3 style config" pass #end if not new configuration approach # still here: create a new instance ... conf = object.__new__( cls ) # ... python convention says to silently return, if __new__ fails ... if conf is None: return # ... initialize it cls.__init__( conf, *args, **kwargs ) # update normal, per-class cache if cls.configurableRun3Behavior==0: cls.configurables[ name ] = conf # update generics super-cache if name in cls.allConfigurables and conf.getType() != cls.allConfigurables[ name ].getType(): raise TypeError( 'attempt to redefine type of "%s" (was: %s, new: %s)' % (name,cls.allConfigurables[ name ].getType(), conf.getType()) ) cls.allConfigurables[ name ] = conf return conf