Skip to content

Tuple[] internals changes in Python 3.6 #11

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

Closed
miohtama opened this issue Dec 30, 2016 · 6 comments
Closed

Tuple[] internals changes in Python 3.6 #11

miohtama opened this issue Dec 30, 2016 · 6 comments
Labels

Comments

@miohtama
Copy link

miohtama commented Dec 30, 2016

Python 3.6 TupleMeta no longer has __tuple_args__. Hitting a Tuple annotation when running sphinx-build causes exception.

Instead one can extra arguments from Tuple like:

def format_annotation(annotation):
    if inspect.isclass(annotation):
        if annotation.__module__ == 'builtins':
            if annotation.__qualname__ == 'NoneType':
                return '``None``'
            else:
                return ':class:`{}`'.format(annotation.__qualname__)

        extra = ''
        if annotation.__module__ in ('typing', 'backports.typing'):
            if annotation.__qualname__ == 'Union':
                params = annotation.__union_params__
                if len(params) == 2 and params[1].__qualname__ == 'NoneType':
                    annotation = Optional
                    params = (params[0],)
            elif annotation.__qualname__ == 'Tuple':

                if hasattr(annotation, "__tuple_params__"):
                    # Python 3.5
                    params = annotation.__tuple_params__
                    if annotation.__tuple_use_ellipsis__:
                        params += ('...',)
                else:
                    # Python 3.6
                    params = getattr(annotation, "__args__", None)
                    # TODO: Handle ellipsis

            else:
                params = getattr(annotation, '__parameters__', None)

            if params:
                extra = '\\[' + ', '.join(format_annotation(param) for param in params) + ']'

        return ':class:`~{}.{}`{}'.format(annotation.__module__, annotation.__qualname__, extra)

    return str(annotation)

However, I did not yet figure out how to handle the ellipsis case, as internals of typing.py are pretty mindblowing.

@wheerd
Copy link
Contributor

wheerd commented Dec 31, 2016

The same goes for Union: It now basically inherits from Generic and has an __args__ attribute.

@gaborbernat
Copy link
Member

The whole function needs some rework for Python 3.6. Union is also no longer a class (see python/typing#380). I've started creating unit test for the project on my fork. So that we can know what works and what not beyond trial and error.

@agronholm
Copy link
Collaborator

I know all this, and I've fixed the same problem in my other project, typeguard. I am in the process of fixing the code, assisted by the test suite written by @wheerd. But it will take some time because I've been swamped with my commercial work for a while. I'm hoping things will calm down in the coming couple weeks.

@miohtama
Copy link
Author

Does anyone know if there are better reflection APIs coming to typing in the future versions of Python? @JukkaL?

@JukkaL
Copy link

JukkaL commented Jan 31, 2017

@miohtama It seems likely that reflection is going to improve. For example, have a look at python/typing#377.

@agronholm
Copy link
Collaborator

Should be fixed by 712d432.

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

No branches or pull requests

5 participants