Skip to content

Declare literal_hash as Optional[Key] #3658

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

Merged
merged 3 commits into from
Jul 5, 2017
Merged

Conversation

elazarg
Copy link
Contributor

@elazarg elazarg commented Jul 4, 2017

literal_hash = None # type: Key is an actual initialization and the None value is accessed, so it should be declared that way. Strict-optional mode does not catch it since it looks like a declaration.

(Surfaced in #3071 here)

mypy/binder.py Outdated
@@ -15,7 +15,7 @@
BindableExpression = Union[IndexExpr, MemberExpr, NameExpr]


class Frame(Dict[Key, Type]):
class Frame(Dict[Optional[Key], Type]):
Copy link
Member

Choose a reason for hiding this comment

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

Does the base class really have to use Optional[Key] as its key type? Does None really occur as a valid key?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You can't just remove the Optional here. I'm not sure that the value actually occurs (it does not make much sense to me), but the type is used in 5 different places*,
I tried to avoid adding if key is not None to keep the change minimal.

(*) lines 109, 116, 151, 270, 271

Copy link
Member

Choose a reason for hiding this comment

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

I think the actual semantics is that keys should not be None. Therefore it should not be Optional here. Also, saving few lines of code does not justify adding potentially misleading hints. Strict optional typically touches subtle things, thus everything should be written as "right" as possible.

mypy/binder.py Outdated
@@ -15,7 +15,7 @@
BindableExpression = Union[IndexExpr, MemberExpr, NameExpr]


class Frame(Dict[Key, Type]):
class Frame(Dict[Optional[Key], Type]):
Copy link
Member

Choose a reason for hiding this comment

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

I think the actual semantics is that keys should not be None. Therefore it should not be Optional here. Also, saving few lines of code does not justify adding potentially misleading hints. Strict optional typically touches subtle things, thus everything should be written as "right" as possible.

mypy/binder.py Outdated
@@ -31,7 +31,7 @@ def __init__(self) -> None:
self.unreachable = False


class DeclarationsFrame(Dict[Key, Optional[Type]]):
class DeclarationsFrame(Dict[Optional[Key], Optional[Type]]):
Copy link
Member

Choose a reason for hiding this comment

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

This Optional is also not needed IMO.

mypy/binder.py Outdated
@@ -125,7 +125,8 @@ def put(self, expr: Expression, typ: Type) -> None:
if key not in self.declarations:
assert isinstance(expr, BindableTypes)
self.declarations[key] = get_declaration(expr)
self._add_dependencies(key)
if key is not None:
self._add_dependencies(key)
Copy link
Member

Choose a reason for hiding this comment

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

This change actually looks reasonable.

Copy link
Member

Choose a reason for hiding this comment

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

I cannot comment there, but you can just add similar things for return self._get(expr.literal_hash) etc., or assert expr.literal_hash is not None where appropriate.

@elazarg
Copy link
Contributor Author

elazarg commented Jul 5, 2017

Maybe it's better to simply initialize the field to () or ('Not a literal',), although the assertions (!= ()) might still be helpful.

Copy link
Member

@ilevkivskyi ilevkivskyi left a comment

Choose a reason for hiding this comment

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

Looks good now, just one more small suggestion.

mypy/binder.py Outdated
@@ -122,6 +122,7 @@ def put(self, expr: Expression, typ: Type) -> None:
if not expr.literal:
return
key = expr.literal_hash
assert key is not None
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer to see a descriptive assertion message here, maybe "Internal error: binder tried to put non-literal", ditto for get and cleanse.

@ilevkivskyi ilevkivskyi merged commit 5a046ee into python:master Jul 5, 2017
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.

3 participants