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

Fix ClassVar as string fails when getting type hints #6824

Merged
merged 5 commits into from
May 16, 2018

Conversation

nnja
Copy link
Contributor

@nnja nnja commented May 14, 2018

@the-knights-who-say-ni
Copy link

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately our records indicate you have not signed the CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

When your account is ready, please add a comment in this pull request
and a Python core developer will remove the CLA not signed label
to make the bot check again.

Thanks again to your contribution and we look forward to looking at it!

Lib/typing.py Outdated
self.__forward_value__ = _type_check(
eval(self.__forward_code__, globalns, localns),
"Forward references must evaluate to types.")
self.__forward_value__ = eval(self.__forward_code__, globalns, localns)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure just removing the check is the right thing to do. Instead I would rather fix _type_check.

We can of course abandon any runtime validation, but this should be a conscious decision and goes beyond the scope of this patch.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, get_type_hints() is not running _type_check on non-forward references so I feel it's a bit weird that we do it for forward references only. Why do we need the additional check for that case? It did successfully evaluate after all, just as if you didn't use a ForwardRef.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed inconsistent, but the proposed solution creates a bigger inconsistency IMO. This code is also called from other places like List['C'], with this change arbitrary string will be valid. The actual problem is that currently _type_check is used for two different purposes:

  • Check whether something is valid as a type
  • Check whether something is valid as a type argument

The proper solution is to disentangle these two. Namely, at this particular position we only need to check if it is a valid type, so we can use a less restrictive check. I think the proper solution would be to add an optional argument to _type_check to skip the two corresponding checks.

@ilevkivskyi
Copy link
Member

Could you please also add a short NEWS entry? (You can use blurb to do this.)

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review declined.

@nnja nnja force-pushed the fix_classvar_as_string_failing branch from 7861376 to b8f0472 Compare May 15, 2018 18:58
@nnja
Copy link
Contributor Author

nnja commented May 15, 2018

The PR has been updated based on comments by @ilevkivskyi and @ambv, added a NEWS entry, and re-signed the contributor agreement (I believe I had already signed it a few years ago). Please recheck. Thank you.

@ambv ambv merged commit 2d2d3b1 into python:master May 16, 2018
@miss-islington
Copy link
Contributor

Thanks @nnja for the PR, and @ambv for merging it 🌮🎉.. I'm working now to backport this PR to: 3.7.
🐍🍒⛏🤖

@ambv
Copy link
Contributor

ambv commented May 16, 2018

Thanks! ✨ 🍰 ✨

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request May 16, 2018
(cherry picked from commit 2d2d3b1)

Co-authored-by: Nina Zakharenko <[email protected]>
@bedevere-bot
Copy link

GH-6912 is a backport of this pull request to the 3.7 branch.

ambv pushed a commit that referenced this pull request May 16, 2018
@@ -998,7 +1005,7 @@ def get_type_hints(obj, globalns=None, localns=None):
if value is None:
value = type(None)
if isinstance(value, str):
value = ForwardRef(value)
value = ForwardRef(value, is_argument=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not having time to review this earlier, this all looks good except for the meaning is exactly the opposite to what I expected :-) There are two options:

  • Rename is_argument to is_not_argument everywhere (arguably ugly)
  • Carefully replace True with False and vice versa, and update the corresponding checks

@nnja @ambv Will any of you have time to make a PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ilevkivskyi cc/ @ambv Yes, I'll have time tomorrow evening on my flight home.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ivan, I don't think the meaning is reversed? As I understand it:

  • "argument" is what's directly an annotation on a function argument and so on; so it includes non-types
  • otherwise, it has to be a type (like inside generics)

If you still want to make a change to this, I would prefer renaming to is_annotation which signifies that we're talking about an entire annotations.

Copy link
Member

@ilevkivskyi ilevkivskyi May 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renaming to is_annotation is a possible option, but IMO is still less clear than is_argument with reversed value, since the latter makes simple distinction between these two cases:

  • List['int'], here 'int' appears as a type argument in another type
  • 'int' here 'int' appears just as a type

In the first case the rules are stricter, e.g. ClassVar can't appear as a type argument.

In view of this, the ideal option would be to both rename it to is_type_argument and reverse False to True, but I don't want to ask for too much :-) I will be happy with either option if there will be a short comment explaining what is_argument/is_annotation/is_type_argument means.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the term "type argument" used anywhere in typing? I only heard of them being called "generics".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, cool, in this case you're right, let's just reverse True with False and vice versa.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ambv @ilevkivskyi Should I open a new PR for these changes? What's the needed course of action for the backport? #6912

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please make a PR against master branch. Also it makes sense to do this ASAP, since 3.7rc1 is out in one day.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ilevkivskyi 👍I can work on this tonight. Will you be available to review?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ilevkivskyi Done! The updated PR is #7039. Please let me know how it looks.

@ilevkivskyi
Copy link
Member

Will you be available to review?

Yes, I will be available until midnight PST

@terryjreedy
Copy link
Member

The CLA label should have been verified before merging this.

@ambv
Copy link
Contributor

ambv commented Aug 30, 2018

This was during PyCon sprints. I knew the CLA is signed, bugs.python.org was behind. The confirmation there is manual.

@terryjreedy
Copy link
Member

Ah. Instantly recorded signings would be great for sprints.

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

Successfully merging this pull request may close these issues.

ClassVar as string fails when getting type hints
8 participants