Get typing.NewType working (#1344)

Squashed from the following commits:

* Update pep0484.py

(I don't think I want to know why the cursor jumped to the beginning of the line with every keystroke in GitHub's online editor. Change was entered backwards.)

* Added test for inline use of NewType. Currently assuming that wrapped instances should get the underlying type.

* Altered tests per https://github.com/davidhalter/jedi/issues/1015#issuecomment-356131566

* Add NewTypeFunction to typing evaluation module

* Update AUTHORS.txt

* Add a new test, and a speculative justification

For now, address only the second comment

* Copy code from third comment on the PR

From inspection, I *believe* I understand what this code is doing, and as such, I believe this should cause the new test I added in response to the second comment to fail, because that test is based on faulty assumptions.

* Explicitly discard the key from the tuple

* Update pep0484_typing.py

* Test for the wrapped type, not the wrapper "type"

* Change the return value from calling a NewType
This commit is contained in:
mwchase
2019-07-02 01:42:59 -04:00
committed by Dave Halter
parent cb95dbc707
commit 925fc89447
3 changed files with 54 additions and 0 deletions

View File

@@ -51,5 +51,6 @@ Maksim Novikov (@m-novikov) <mnovikov.work@gmail.com>
Tobias Rzepka (@TobiasRzepka)
micbou (@micbou)
Dima Gerasimov (@karlicoss) <karlicoss@gmail.com>
Max Woerner Chase (@mwchase) <max.chase@gmail.com>
Note: (@user) means a github user name.

View File

@@ -115,6 +115,8 @@ class TypingModuleName(NameWrapper):
yield builtin_from_name(evaluator, u'True')
elif name == 'overload':
yield OverloadFunction.create_cached(evaluator, self.parent_context, self.tree_name)
elif name == 'NewType':
yield NewTypeFunction.create_cached(evaluator, self.parent_context, self.tree_name)
elif name == 'cast':
# TODO implement cast
yield CastFunction.create_cached(evaluator, self.parent_context, self.tree_name)
@@ -459,6 +461,32 @@ class OverloadFunction(_BaseTypingContext):
return func_context_set
class NewTypeFunction(_BaseTypingContext):
def py__call__(self, arguments):
ordered_args = arguments.unpack()
next(ordered_args, (None, None))
_, second_arg = next(ordered_args, (None, None))
if second_arg is None:
return NO_CONTEXTS
return ContextSet(
NewType(
self.evaluator,
contextualized_node.context,
contextualized_node.node,
second_arg.infer(),
) for contextualized_node in arguments.get_calling_nodes())
class NewType(Context):
def __init__(self, evaluator, parent_context, tree_node, type_context_set):
super(NewType, self).__init__(evaluator, parent_context)
self._type_context_set = type_context_set
self.tree_node = tree_node
def py__call__(self, arguments):
return self._type_context_set.execute_annotation()
class CastFunction(_BaseTypingContext):
@repack_with_argument_clinic('type, object, /')
def py__call__(self, type_context_set, object_context_set):

View File

@@ -256,6 +256,31 @@ for key in x.keys():
for value in x.values():
#? int()
value
WrappingType = typing.NewType('WrappingType', str) # Chosen arbitrarily
y = WrappingType(0) # Per https://github.com/davidhalter/jedi/issues/1015#issuecomment-355795929
#? str()
y
def testnewtype(y):
"""
:type y: WrappingType
"""
#? str()
y
#? ["upper"]
y.u
WrappingType2 = typing.NewType()
def testnewtype2(y):
"""
:type y: WrappingType2
"""
#?
y
#? []
y.
# python >= 3.4
class TestDefaultDict(typing.DefaultDict[str, int]):