(cls, obj, s, skip_bound_arg=True)
return cls(parameters, return_annotation=cls.empty)
Private helper to parse content of '__text_signature__'
    and return a Signature based on it.
Private helper to parse content of '__text_signature__'
    and return a Signature based on it.
Private helper to parse content of __text_signature__ and return a Signature based on it .
def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
    """Private helper to parse content of '__text_signature__'
    and return a Signature based on it.
    """
    # Lazy import ast because it's relatively heavy and
    # it's not used for other than this function.
    import ast

    Parameter = cls._parameter_cls

    clean_signature, self_parameter, last_positional_only = \
        _signature_strip_non_python_syntax(s)

    program = "def foo" + clean_signature + ": pass"

    try:
        module = ast.parse(program)
    except SyntaxError:
        module = None

    if not isinstance(module, ast.Module):
        raise ValueError("{!r} builtin has invalid signature".format(obj))

    f = module.body[0]

    parameters = []
    empty = Parameter.empty
    invalid = object()

    module = None
    module_dict = {}
    module_name = getattr(obj, '__module__', None)
    if module_name:
        module = sys.modules.get(module_name, None)
        if module:
            module_dict = module.__dict__
    sys_module_dict = sys.modules.copy()

    def parse_name(node):
        assert isinstance(node, ast.arg)
        if node.annotation is not None:
            raise ValueError("Annotations are not currently supported")
        return node.arg

    def wrap_value(s):
        try:
            value = eval(s, module_dict)
        except NameError:
            try:
                value = eval(s, sys_module_dict)
            except NameError:
                raise RuntimeError()

        if isinstance(value, (str, int, float, bytes, bool, type(None))):
            return ast.Constant(value)
        raise RuntimeError()

    class RewriteSymbolics(ast.NodeTransformer):
        def visit_Attribute(self, node):
            a = []
            n = node
            while isinstance(n, ast.Attribute):
                a.append(n.attr)
                n = n.value
            if not isinstance(n, ast.Name):
                raise RuntimeError()
            a.append(n.id)
            value = ".".join(reversed(a))
            return wrap_value(value)

        def visit_Name(self, node):
            if not isinstance(node.ctx, ast.Load):
                raise ValueError()
            return wrap_value(node.id)

    def p(name_node, default_node, default=empty):
        name = parse_name(name_node)
        if name is invalid:
            return None
        if default_node and default_node is not _empty:
            try:
                default_node = RewriteSymbolics().visit(default_node)
                o = ast.literal_eval(default_node)
            except ValueError:
                o = invalid
            if o is invalid:
                return None
            default = o if o is not invalid else default
        parameters.append(Parameter(name, kind, default=default, annotation=empty))

    # non-keyword-only parameters
    args = reversed(f.args.args)
    defaults = reversed(f.args.defaults)
    iter = itertools.zip_longest(args, defaults, fillvalue=None)
    if last_positional_only is not None:
        kind = Parameter.POSITIONAL_ONLY
    else:
        kind = Parameter.POSITIONAL_OR_KEYWORD
    for i, (name, default) in enumerate(reversed(list(iter))):
        p(name, default)
        if i == last_positional_only:
            kind = Parameter.POSITIONAL_OR_KEYWORD

    # *args
    if f.args.vararg:
        kind = Parameter.VAR_POSITIONAL
        p(f.args.vararg, empty)

    # keyword-only arguments
    kind = Parameter.KEYWORD_ONLY
    for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults):
        p(name, default)

    # **kwargs
    if f.args.kwarg:
        kind = Parameter.VAR_KEYWORD
        p(f.args.kwarg, empty)

    if self_parameter is not None:
        # Possibly strip the bound argument:
        #    - We *always* strip first bound argument if
        #      it is a module.
        #    - We don't strip first bound argument if
        #      skip_bound_arg is False.
        assert parameters
        _self = getattr(obj, '__self__', None)
        self_isbound = _self is not None
        self_ismodule = ismodule(_self)
        if self_isbound and (self_ismodule or skip_bound_arg):
            parameters.pop(0)
        else:
            # for builtins, self parameter is always positional-only!
            p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
            parameters[0] = p

    return cls(parameters, return_annotation=cls.empty)
def _signature_fromstr ( cls , obj , s , skip_bound_arg = True ) : # Lazy import ast because it's relatively heavy and # it's not used for other than this function. import ast Parameter = cls . _parameter_cls clean_signature , self_parameter , last_positional_only = _signature_strip_non_python_syntax ( s ) program = "def foo" + clean_signature + ": pass" try : module = ast . parse ( program ) except SyntaxError : module = None if not isinstance ( module , ast . Module ) : raise ValueError ( "{!r} builtin has invalid signature" . format ( obj ) ) f = module . body [ 0 ] parameters = [ ] empty = Parameter . empty invalid = object ( ) module = None module_dict = { } module_name = getattr ( obj , '__module__' , None ) if module_name : module = sys . modules . get ( module_name , None ) if module : module_dict = module . __dict__ sys_module_dict = sys . modules . copy ( ) def parse_name ( node ) : assert isinstance ( node , ast . arg ) if node . annotation is not None : raise ValueError ( "Annotations are not currently supported" ) return node . arg def wrap_value ( s ) : try : value = eval ( s , module_dict ) except NameError : try : value = eval ( s , sys_module_dict ) except NameError : raise RuntimeError ( ) if isinstance ( value , ( str , int , float , bytes , bool , type ( None ) ) ) : return ast . Constant ( value ) raise RuntimeError ( ) class RewriteSymbolics ( ast . NodeTransformer ) : def visit_Attribute ( self , node ) : a = [ ] n = node while isinstance ( n , ast . Attribute ) : a . append ( n . attr ) n = n . value if not isinstance ( n , ast . Name ) : raise RuntimeError ( ) a . append ( n . id ) value = "." . join ( reversed ( a ) ) return wrap_value ( value ) def visit_Name ( self , node ) : if not isinstance ( node . ctx , ast . Load ) : raise ValueError ( ) return wrap_value ( node . id ) def p ( name_node , default_node , default = empty ) : name = parse_name ( name_node ) if name is invalid : return None if default_node and default_node is not _empty : try : default_node = RewriteSymbolics ( ) . visit ( default_node ) o = ast . literal_eval ( default_node ) except ValueError : o = invalid if o is invalid : return None default = o if o is not invalid else default parameters . append ( Parameter ( name , kind , default = default , annotation = empty ) ) # non-keyword-only parameters args = reversed ( f . args . args ) defaults = reversed ( f . args . defaults ) iter = itertools . zip_longest ( args , defaults , fillvalue = None ) if last_positional_only is not None : kind = Parameter . POSITIONAL_ONLY else : kind = Parameter . POSITIONAL_OR_KEYWORD for i , ( name , default ) in enumerate ( reversed ( list ( iter ) ) ) : p ( name , default ) if i == last_positional_only : kind = Parameter . POSITIONAL_OR_KEYWORD # *args if f . args . vararg : kind = Parameter . VAR_POSITIONAL p ( f . args . vararg , empty ) # keyword-only arguments kind = Parameter . KEYWORD_ONLY for name , default in zip ( f . args . kwonlyargs , f . args . kw_defaults ) : p ( name , default ) # **kwargs if f . args . kwarg : kind = Parameter . VAR_KEYWORD p ( f . args . kwarg , empty ) if self_parameter is not None : # Possibly strip the bound argument: #    - We *always* strip first bound argument if #      it is a module. #    - We don't strip first bound argument if #      skip_bound_arg is False. assert parameters _self = getattr ( obj , '__self__' , None ) self_isbound = _self is not None self_ismodule = ismodule ( _self ) if self_isbound and ( self_ismodule or skip_bound_arg ) : parameters . pop ( 0 ) else : # for builtins, self parameter is always positional-only! p = parameters [ 0 ] . replace ( kind = Parameter . POSITIONAL_ONLY ) parameters [ 0 ] = p return cls ( parameters , return_annotation = cls . empty )