def check_signature(object_name, reference_object, other_object):
try:<EOL><INDENT>if inspect.isclass(reference_object):<EOL><INDENT>if inspect.isclass(other_object):<EOL><INDENT>if issubclass(other_object, reference_object):<EOL><INDENT>reference_object_map = dict(<EOL>inspect.getmembers(reference_object,<EOL>inspect.isroutine))<EOL>for other_method_name, other_method_code ininspect.getmembers(other_object,<EOL>inspect.isroutine):<EOL><INDENT>if other_method_name in reference_object_map:<EOL><INDENT>check_signature(<EOL>object_name,<EOL>reference_object_map[other_method_name],<EOL>other_method_code)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>other_object_map = dict(<EOL>inspect.getmembers(other_object, inspect.isroutine))<EOL>for reference_method_name, reference_method_code ininspect.getmembers(<EOL>reference_object, inspect.isroutine):<EOL><INDENT>if reference_method_name in other_object_map:<EOL><INDENT>check_signature(<EOL>object_name, reference_method_code,<EOL>other_method_code)<EOL><DEDENT>else:<EOL><INDENT>raise AutodiscoveryCheckerError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>reference_method_name)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise AutodiscoveryCheckerError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(reference_object, other_object))<EOL><DEDENT><DEDENT>elif inspect.isroutine(reference_object):<EOL><INDENT>if inspect.isroutine(other_object):<EOL><INDENT>reference_args, reference_varargs, reference_varkw,reference_defaults = inspect.getargspec(reference_object)<EOL>other_args, other_varargs, other_varkw,other_defaults = inspect.getargspec(other_object)<EOL>if reference_defaults is not None:<EOL><INDENT>reference_defaults = list(reference_defaults)<EOL><DEDENT>else:<EOL><INDENT>reference_defaults = []<EOL><DEDENT>if other_defaults is not None:<EOL><INDENT>other_defaults = list(other_defaults)<EOL><DEDENT>else:<EOL><INDENT>other_defaults = []<EOL><DEDENT>if not (other_varargs or other_varkw):<EOL><INDENT>for reference_arg in reference_args:<EOL><INDENT>if reference_arg not in other_args:<EOL><INDENT>raise AutodiscoveryCheckerError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(reference_arg, reference_object, other_object)<EOL>)<EOL><DEDENT><DEDENT><DEDENT>if not (reference_varargs or reference_varkw):<EOL><INDENT>for other_arg in other_args:<EOL><INDENT>if other_arg not in reference_args:<EOL><INDENT>raise AutodiscoveryCheckerError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(other_arg, other_object, reference_object))<EOL><DEDENT><DEDENT><DEDENT>for reference_arg, other_arg in map(<EOL>None, reference_args, other_args):<EOL><INDENT>if not((reference_arg == other_arg) or<EOL>(reference_arg is None and<EOL>(reference_varargs or reference_varkw)) or<EOL>(other_arg is None and<EOL>(other_args or other_varargs))):<EOL><INDENT>raise AutodiscoveryCheckerError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(other_arg, reference_arg))<EOL><DEDENT><DEDENT>if len(reference_defaults) != len(other_defaults) and not (<EOL>reference_args or reference_varargs or<EOL>other_args or other_varargs):<EOL><INDENT>raise AutodiscoveryCheckerError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise AutodiscoveryCheckerError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % (reference_object, other_object))<EOL><DEDENT><DEDENT><DEDENT>except AutodiscoveryCheckerError as err:<EOL><INDENT>try:<EOL><INDENT>sourcefile = inspect.getsourcefile(other_object)<EOL>sourceline = inspect.getsourcelines(other_object)[<NUM_LIT:1>]<EOL><DEDENT>except IOError:<EOL><INDENT>sourcefile = '<STR_LIT>'<EOL>sourceline = '<STR_LIT>'<EOL><DEDENT>raise AutodiscoveryCheckerError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(object_name, sourcefile, sourceline, err))<EOL><DEDENT>
Given a reference class or function check if an other class or function
could be substituted without causing any instantiation/usage issues.

:param object_name: the name of the object being checked.
:type object_name: string
:param reference_object: the reference class or function.
:type reference_object: class/function
:param other_object: the other class or function to be checked.
:type other_object: class/function
:raise AutodiscoveryCheckerError: in case the other object is not
    compatible with the reference object.