Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Introduce signature utilities for python 3.8 #155

Closed
wants to merge 1 commit into from

Conversation

4383
Copy link
Collaborator

@4383 4383 commented May 17, 2019

To prevent stdlib getfullargspec deprecation these propose to introduce
a backward compat for python version who will remove getfullargspec.

These changes are more to discuss with you about the cross vendoring between mako, dogpile etc...

related to #154

To prevent stdlib getfullargspec deprecation these propose to introduce
a backward compat for python version who will remove getfullargspec.

Change-Id: I77ab0cb79d678f4d2763c89ea5aa18e3646672be
@4383 4383 changed the title Introduce signature utilities for python 3.8 [WIP] Introduce signature utilities for python 3.8 May 17, 2019
@zzzeek
Copy link
Member

zzzeek commented May 17, 2019

OK so my notion was, since this has to be in four projects, to lift the Python 3.3 version, which apparently is not on github, so it's this:

FullArgSpec = namedtuple('FullArgSpec',
    'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')

def getfullargspec(func):
    """Get the names and default values of a function's arguments.

    A tuple of seven things is returned:
    (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations).
    'args' is a list of the argument names.
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
    'defaults' is an n-tuple of the default values of the last n arguments.
    'kwonlyargs' is a list of keyword-only argument names.
    'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
    'annotations' is a dictionary mapping argument names to annotations.

    The first four items in the tuple correspond to getargspec().
    """

    if ismethod(func):
        func = func.__func__
    if not isfunction(func):
        raise TypeError('{!r} is not a Python function'.format(func))
    args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__)
    return FullArgSpec(args, varargs, varkw, func.__defaults__,
            kwonlyargs, func.__kwdefaults__, func.__annotations__)

def _getfullargs(co):
    """Get information about the arguments accepted by a code object.

    Four things are returned: (args, varargs, kwonlyargs, varkw), where
    'args' and 'kwonlyargs' are lists of argument names, and 'varargs'
    and 'varkw' are the names of the * and ** arguments or None."""

    if not iscode(co):
        raise TypeError('{!r} is not a code object'.format(co))

    nargs = co.co_argcount
    names = co.co_varnames
    nkwargs = co.co_kwonlyargcount
    args = list(names[:nargs])
    kwonlyargs = list(names[nargs:nargs+nkwargs])
    step = 0

    nargs += nkwargs
    varargs = None
    if co.co_flags & CO_VARARGS:
        varargs = co.co_varnames[nargs]
        nargs = nargs + 1
    varkw = None
    if co.co_flags & CO_VARKEYWORDS:
        varkw = co.co_varnames[nargs]
    return args, varargs, kwonlyargs, varkw

per my performance test at https://gist.github.com/zzzeek/0eb0636fa3917f36ffd887d9f765c208 it is 5-20x faster than any current implementation

@4383
Copy link
Collaborator Author

4383 commented May 17, 2019

I've intialize this project based on the py3.3 code => https://github.com/4383/contrat
Quick and dirty if you want to take a look.

(I use pbr to package it but I can also use vanilla setuptools/distutils)

@zzzeek
Copy link
Member

zzzeek commented May 17, 2019

sorry I know im being difficult here, I was looking for to make a very truncated version just of getfullargspec() and then have it present directly in each project (dogpile, mako, alembic, sqlalchemy). I don't want to make an additional package because 1. external dependency 2. competes with upstream Python who will want to be fixing Signature's performance 3. not sure if the 3.3 implementation is even going to work b.c. i need to see what syntaxes we might be missing .

if you want I can annotate everything at https://github.com/4383/contrat/blob/master/contrat/__init__.py that I don't need

@zzzeek
Copy link
Member

zzzeek commented May 17, 2019

also note they are un-deprecating getfullargspec() for now. so we have time. I do want to improve on performance thoguh but tihs is more important for sqlalchemy

@4383
Copy link
Collaborator Author

4383 commented May 18, 2019

sorry I know im being difficult here,

No problem

I was looking for to make a very truncated version just of getfullargspec() and then have it present directly in each project (dogpile, mako, alembic, sqlalchemy). I don't want to make an additional package because 1. external dependency 2. competes with upstream Python who will want to be fixing Signature's performance 3. not sure if the 3.3 implementation is even going to work b.c. i need to see what syntaxes we might be missing .

if you want I can annotate everything at https://github.com/4383/contrat/blob/master/contrat/__init__.py that I don't need

Yeah good idea

@4383
Copy link
Collaborator Author

4383 commented May 18, 2019

also note they are un-deprecating getfullargspec() for now. so we have time. I do want to improve on performance thoguh but tihs is more important for sqlalchemy

Yep I know

@4383
Copy link
Collaborator Author

4383 commented Jun 4, 2019

I guess I can close this one now (related to d0ff02b)

@4383 4383 closed this Jun 4, 2019
@zzzeek
Copy link
Member

zzzeek commented Jun 4, 2019

yeah I did them all at once!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants