Skip to content

[needs tests] TypedDict: Recognize declaration of TypedDict('Point', {'x': int, 'y': int}). #2206

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 8 commits into from
Oct 19, 2016

Conversation

davidfstr
Copy link
Contributor

@davidfstr davidfstr commented Oct 2, 2016

The automated tests in this PR still need work but the feature implementation should be good.

How to test locally

  • Add davidfstr/mypy remote
$ pwd
/path/to/mypy
$ git remote add davidfstr git@github.com:davidfstr/mypy.git
$ git fetch davidfstr
  • Checkout tip of this PR
$ git checkout declare_typeddict
  • Create TEST.py
$ cat - > TEST.py
from mypy.typing import TypedDict
Point = TypedDict('Point', {'x': int, 'y': int})
point = dict(x=42, y=1337)  # type: Point
^D
  • Run TEST.py to show it has no runtime errors
$ python3 TEST.py
  • Run mypy on TEST.py
$ python3 -m mypy --show-traceback TEST.py 
TEST.py:7: error: Incompatible types in assignment (expression has type Dict[str, int], variable has type "Point")

That single error above is expected since this PR only supports declaring the TypedDict type Point = TypedDict('Point', {'x': int, 'y': int}) but not the TypedDict instance. If you remove the last line (point = dict(x=42, y=1337) # type: Point) then you should get no errors.

Notes

Move typing.TypedDict -> mypy.typing.TypedDict?

During the incremental adding of support of TypedDict over several PRs, it would be a lot easier if TypedDict was not defined in the official typing module but was instead defined in a mypy-specific typing module (like mypy.typing). Then after TypedDict was stabilizied, then TypedDict could be added to the official typing module. Let me know if you this is a good idea.

Done. It's a lot cleaner now. No more conditional imports.

More work required on tests

I have tried to implement tests for TypedDict but am getting a failure I do not understand.

$ python3 runtests.py mypy.test.testsemanal
PARALLEL 2
SUMMARY  3 tasks selected
passed 2, failed 1, pending 0; running 0                                        

FAILURE  #0 run unit-test mypy.test.testsemanal

main:1: note: In module imported here:
/Users/davidf/Projects/mypy/mypy/typing.py:5: error: Name '__builtins__.dict' is not defined
main:1: note: In module imported here:
/Users/davidf/Projects/mypy/mypy/typing.py:5: error: Name '__builtins__.dict' is not defined
/Users/davidf/Projects/mypy/mypy/typing.py:5: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues
/Users/davidf/Projects/mypy/mypy/typing.py:5: note: please use --show-traceback to print a traceback when reporting a bug

SystemExit: 1

test_testsemanal_SemAnalSuite.testCanDefineTypedDictType failed

/Users/davidf/Projects/mypy/mypy/typing.py:5: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues
/Users/davidf/Projects/mypy/mypy/typing.py:5: note: please use --show-traceback to print a traceback when reporting a bug

SystemExit: 1

test_testsemanal_SemAnalSuite.testCannotYetAnnotateDictLiteralAsTypedDict failed

2/476 test cases failed.
*** FAILURE ***

I am not sure how to pass --show-traceback to the test suite, as the error message recommends.

Edit: Simplify instructions now that the new mypy.typing module to hold TypedDict is used in lieu of the standard typing module.

@davidfstr davidfstr mentioned this pull request Oct 2, 2016
@gvanrossum
Copy link
Member

gvanrossum commented Oct 2, 2016 via email

@elazarg
Copy link
Contributor

elazarg commented Oct 2, 2016

Yes, sorry about that.

I think there should be a dedicated module for parsing "special constructs" such as NewType, NamedTuple and TypedDict. They need similar machinery (e.g. AST matcher).

node.kind = GDEF # TODO locally defined TypedDict
node.node = typed_dict

def check_typeddict(self, node: Node, var_name: str = None) -> TypeInfo:
Copy link
Member

Choose a reason for hiding this comment

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

Return should be Optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@davidfstr
Copy link
Contributor Author

Revised to no longer modify the typing module (in typeshed). Instead a new mypy.typing module is introduced for experimental typing extensions that are recognized by mypy specifically.

@davidfstr
Copy link
Contributor Author

@gvanrossum I think we may have different purposes in mind when talking about "an experimental typing module". Therefore I suggest we break off that likely-to-be-involved discussion. I've created a thread here: #2210

@davidfstr
Copy link
Contributor Author

davidfstr commented Oct 2, 2016

Review checklist

[x] Comments from one reviewer.
[x] Comments from a second reviewer. Recommended for a non-trivial and first-time commit.
[x] Working location for TypedDict. --> mypy.typing; okay for now but will be moved later.
[x] Assistance in debugging strange test case crash.
[x] Assistance in removing AST of mypy.typing from the test output.
[x] Fix minor merge conflict. May involve a rebase.

[case testCanDefineTypedDictType]
from mypy.typing import TypedDict
Point = TypedDict('Point', {'x': int, 'y': int})
[out]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you'll need to add test-data/unit/lib-stub/mypy/__init__.pyi and test-data/unit/lib-stub/mypy/typing.pyi, as otherwise mypy won't find the mypy.typing module. Test cases look for stubs here and they don't use typeshed stubs. You can write a minimal stub that lets the tests pass.

Also, the default builtins stubs used in test cases don't include dict. You should be able to add this line to the test case for dict to work (just before [out]):

[builtins fixtures/dict.pyi]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@JukkaL Hey thanks for the tips. This may be enough for me to get the tests to work.

I'll probably take another look Wednesday evening.

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 4, 2016

Hopefully my suggestions regarding stubs in test cases will help you get your test case running. If you still have trouble and I can debug it myself.

The diff looks pretty good to me! Once you have some tests working, just write test cases for more error conditions and this will likely be close to ready.

@ddfisher
Copy link
Collaborator

ddfisher commented Oct 4, 2016

Excited for this! Is there documentation about the usage/exact semantics anywhere?

@davidfstr
Copy link
Contributor Author

So, could I get some help in debugging the test failure that I mentioned above?

It's crashing with an internal error but it's not clear to me how to specify --show-traceback to the test suite. It's also not really clear to me how to run the exact two tests from mypy.test.testsemanal that I care about. runtests.py seems rather opaque.

@davidfstr
Copy link
Contributor Author

Whoops I missed your comment @JukkaL.

I know that there's such a thing as test stubs now, but I'm still not 100% sure on how they work still. Knowing how to narrow down runtests.py to run exactly the tests I care about should help.

@davidfstr
Copy link
Contributor Author

Is there documentation about the usage/exact semantics anywhere?

@ddfisher Take a look at python/typing#28 for discussions around spelling and semantics. Take a look at #985 for the larger implementation plan.

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 4, 2016

@gvanrossum @ddfisher Can you tell why @davidfstr isn't seeing a traceback? I think that tests should always show a traceback by default.

@gvanrossum
Copy link
Member

gvanrossum commented Oct 4, 2016 via email

@gvanrossum
Copy link
Member

I hacked errors.py to always show the traceback and got the following. Maybe it's helpful.

main:1: note: In module imported here:
/Users/guido/src/mypy/mypy/typing.py:5: error: Name '__builtins__.dict' is not defined
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/guido/src/mypy/mypy/myunit/__main__.py", line 18, in <module>
    main()
  File "/Users/guido/src/mypy/mypy/myunit/__init__.py", line 230, in main
    num_total, num_fail, num_skip = run_test_recursive(t, 0, 0, 0, '', 0)
  File "/Users/guido/src/mypy/mypy/myunit/__init__.py", line 279, in run_test_recursive
    stest, num_total, num_fail, num_skip, new_prefix, depth + 1)
  File "/Users/guido/src/mypy/mypy/myunit/__init__.py", line 279, in run_test_recursive
    stest, num_total, num_fail, num_skip, new_prefix, depth + 1)
  File "/Users/guido/src/mypy/mypy/myunit/__init__.py", line 260, in run_test_recursive
    is_fail, is_skip = run_single_test(name, test)
  File "/Users/guido/src/mypy/mypy/myunit/__init__.py", line 292, in run_single_test
    test.run()
  File "/Users/guido/src/mypy/mypy/test/data.py", line 185, in run
    self.perform(self)
  File "/Users/guido/src/mypy/mypy/test/testsemanal.py", line 68, in test_semanal
    alt_lib_path=test_temp_dir)
  File "/Users/guido/src/mypy/mypy/build.py", line 185, in build
    dispatch(sources, manager)
  File "/Users/guido/src/mypy/mypy/build.py", line 1473, in dispatch
    process_graph(graph, manager)
  File "/Users/guido/src/mypy/mypy/build.py", line 1650, in process_graph
    process_stale_scc(graph, scc)
  File "/Users/guido/src/mypy/mypy/build.py", line 1721, in process_stale_scc
    graph[id].semantic_analysis()
  File "/Users/guido/src/mypy/mypy/build.py", line 1405, in semantic_analysis
    self.manager.semantic_analyzer.visit_file(self.tree, self.xpath, self.options)
  File "/Users/guido/src/mypy/mypy/semanal.py", line 240, in visit_file
    self.accept(d)
  File "/Users/guido/src/mypy/mypy/semanal.py", line 2666, in accept
    node.accept(self)
  File "/Users/guido/src/mypy/mypy/nodes.py", line 270, in accept
    return visitor.visit_import_from(self)
  File "/Users/guido/src/mypy/mypy/semanal.py", line 954, in visit_import_from
    node = self.normalize_type_alias(node, imp)
  File "/Users/guido/src/mypy/mypy/semanal.py", line 1008, in normalize_type_alias
    if node.fullname == 'typing.DefaultDict':
AttributeError: 'NoneType' object has no attribute 'fullname'

@gvanrossum
Copy link
Member

Next time you rebase, you'll get #2216 which should show tracebacks whenever a test crashes!

@gvanrossum gvanrossum changed the title TypedDict: Recognize declaration of TypedDict('Point', {'x': int, 'y': int}). [needs tests] TypedDict: Recognize declaration of TypedDict('Point', {'x': int, 'y': int}). Oct 4, 2016
@davidfstr
Copy link
Contributor Author

I've gotten a bit further with @JukkaL's magic line to add to the tests.

However it appears that the test output contains the AST of not just the test case but also the mypy.typing module that it imports. I don't know why the test infrastructure is including it. See output in this gist: https://gist.github.com/davidfstr/628b1d885e6fb6b8159655a37d2cb628

The remaining test issue is probably simple enough for someone familar with the test instructure to just look at it and fix it directly. That would give me more time to actually work on the next implementation phase.

When writing more tests for later phases, is there documentation floating around anywhere for how to really use the test infrstructure? The tests at minimum seem to be using a DSL that I am not familar with.

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 5, 2016

Some modules are filtered out from the output in test_semanal (in mypy/test/testsemanal.py). Can you add the new modules there?

There's some documentation about the test infrastructure in the wiki, but it looks a little out of date: https://github.com/python/mypy/wiki/Implementation-Overview

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 5, 2016

(I made some updates to the implementation overview.)

@davidfstr
Copy link
Contributor Author

Rebased to tip of master. All tests pass.

Only outstanding issue I see is the desire to move mypy/typing.py to a better location, as per #2210 . However I'd recommend we get this change initially committed as-is to avoid further merge conflicts, as this is a somewhat large change.

@gvanrossum
Copy link
Member

gvanrossum commented Oct 6, 2016 via email

@gvanrossum
Copy link
Member

gvanrossum commented Oct 6, 2016 via email

@davidfstr
Copy link
Contributor Author

Okay. I'll consider this PR paused until a separate PR for an empty mypy_extensions/typing.py goes in. Work tracked here: #2210

@gvanrossum
Copy link
Member

I'd really like to see way more unittests for this; the only unittest you've added just checks the parsing (even there I'd like to see more test coverage of the various error cases). Understood that you may want to wait until you've got mypy_extensions squared away. But even so you'll have to add (unfortunately) some "mock stubs" (if that's the term) to test-data/unit/lib-deps and/or test-data/unit/fixtures.

@davidfstr
Copy link
Contributor Author

I've added tests that cover all error scenarios that have error messages.

@davidfstr
Copy link
Contributor Author

Hmm... Normally I'd prefer that mypy_extensions distribute its own .pyi file directly rather than requiring a synchronized checkin to typeshed. But it sounds like that wouldn't work since if sys.path is not consulted then mypy presumably wouldn't find any .pyi files installed in it.

Is there generally a way for a package that is natively typing-aware to distribute its own .pyi files in such a way that mypy would find it without special configuration? Or is typeshed the only supported search location for .pyi files at the present time?

@gvanrossum
Copy link
Member

gvanrossum commented Oct 15, 2016 via email

@davidfstr
Copy link
Contributor Author

Alrighty. Typeshed it is then.

I'll probably create a separate issue as a placeholder for how libraries that wish to distribute their own .pyi files (or have inline annotations) should go about doing that in a way that typecheckers like mypy can locate. Probably a discussion for https://github.com/python/typing .

@gvanrossum
Copy link
Member

gvanrossum commented Oct 15, 2016 via email

@gvanrossum
Copy link
Member

I agree this is getting close, but I would still like to see more tests, in particular tests for the type checker (see test-data/unit/check-*.test). The tests you've added are all semanal tests which means they don't even exercise the type checker at all -- they basically just check the syntactic processing.

@@ -0,0 +1,6 @@
from typing import Dict, Type, TypeVar
Copy link
Member

Choose a reason for hiding this comment

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

We moved this to typeshed.

@davidfstr
Copy link
Contributor Author

This PR makes no substantive changes to the type checker (mypy/checker.py), leaving that work to the next PR in the proposed series, so I'm not sure what kind of tests I'd be able to add. In particular it's not actually possible yet to create an instance of a type instantiated by TypedDict.

In reading test-data/check-namedtuple.test, which is likely analogous to a future check-typeddict.test, most of what is checked there is not implemented yet.

The current tests test the main success case and every error case (that outputs a distinct error message) of mypy/semanal.py@process_typeddict_definition, which is the only major code added in this PR. Are there other cases in the implementation that I'm not seeing that you'd like me to cover?

@gvanrossum
Copy link
Member

Oh. Wait. You were proposing to get this merged and then work on the next
phase? I guess I missed that. (This PR has been pretty "noisy" in the
comments and I've not read everything, assuming much of it was superseded
by later pushes, so apologies for missing that.)

We don't usually merge features until they are fully implemented, so I
would rather see you work on the type checker next. And you'd be surprised
what doing the next step could teach about a previous step that you thought
was complete! :-)

If you want some assurance that you've done the right things so far, I'd
say passing tests are all you need. I did read your changes to semanal.py
and they look basically fine, which is the best you're going to get from
me. :-)

@davidfstr
Copy link
Contributor Author

We don't usually merge features until they are fully implemented, so I
would rather see you work on the type checker next. And you'd be surprised
what doing the next step could teach about a previous step that you thought
was complete! :-)

Sure. I could attack the whole beast. :-) I had the entire feature split up into a larger series of PRs based on a earlier recommendation (below) to use several smaller PRs rather than one big PR. The full implementation series is here: #985 (comment)

I'd suggest starting with a minimal PR that only supports a very small subset of functionality, such as only parsing TypedDict definitions and maybe declaring a variable with a TypedDict type. Small PRs are faster to review and marge and you'll get feedback sooner. It's okay to have half-finished functionality in master (we just don't advertise it until it works well enough).

@gvanrossum
Copy link
Member

OK, Jukka is the boss. I will check this over once more and then
squash-merge it. Sorry!

On Mon, Oct 17, 2016 at 10:06 PM, David Foster notifications@github.com
wrote:

We don't usually merge features until they are fully implemented, so I
would rather see you work on the type checker next. And you'd be surprised
what doing the next step could teach about a previous step that you thought
was complete! :-)

Sure. I could attack the whole beast. :-) I had the entire feature split
up into a larger series of PRs based on a earlier recommendation (below) to
use several smaller PRs rather than one big PR. The full implementation
series is here: #985 (comment)
#985 (comment)

I'd suggest starting with a minimal PR that only supports a very small
subset of functionality, such as only parsing TypedDict definitions and
maybe declaring a variable with a TypedDict type. Small PRs are faster to
review and marge and you'll get feedback sooner. It's okay to have
half-finished functionality in master (we just don't advertise it until it
works well enough).


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#2206 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/ACwrMt7YI5ytabwYKVGmfy0H813ztw_Rks5q1FPmgaJpZM4KL5aa
.

--Guido van Rossum (python.org/~guido)

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.

OK, this is almost ready to merge.

call = node
if not isinstance(call.callee, RefExpr):
return None
callee = call.callee
Copy link
Member

Choose a reason for hiding this comment

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

Micro-optimization: you can move this before the isinstance() check -- it's still the callee even if we don't like it. :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Applied globally.

items, types, ok = self.parse_typeddict_args(call, fullname)
if not ok:
# Error. Construct dummy return value.
return self.build_typeddict_typeinfo('TypedDict', [], [])
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if this isn't going to cause a cascade of spurious errors. Might be better to just return AnyType().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When I alter this line's twin in check_namedtuple() to return None, which means that something other than a NamedTuple was found (as opposed to an invalid NamedTuple), the error detected in the test suite (semanal-namedtuple.test:136) seems less helpful.

Old error: Tuple expected as NamedTuple() field
New error: Invalid base class

Honestly I don't think either error message is particularly good but at least the first one mentions that is has something to do with a NamedTuple.

Based on this regression in error message quality I've left this line as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It might be possible to return an AnyType with a more-invasive change, as I'd need to alter the signature of check_namedtuple and its callers. I'd prefer to tread lightly.

# Error. Construct dummy return value.
return self.build_typeddict_typeinfo('TypedDict', [], [])
else:
# Give it a unique name derived from the line number.
Copy link
Member

Choose a reason for hiding this comment

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

This comment belongs inside the following 'if'.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in both locations.

if name != var_name:
name += '@' + str(call.line)
info = self.build_typeddict_typeinfo(name, items, types)
# Store it as a global just in case it would remain anonymous.
Copy link
Member

Choose a reason for hiding this comment

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

Oh, this sounds risky. Consider:

foo = 12
class C:
    foo = TypedDict('foo', {...})

Now it looks like the global foo will be overwritten for no reason. Maybe only do that if it's anonymous?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't fully understand the implications of changing this line. I will however note that if I remove the line entirely from check_namedtuple() and check_typeddict() then the test suite continues to pass.

Agreed that it seems weird that a type declaration performed anywhere would want to be injected into the global scope. I can remove this line if someone else can confirm that I'm not going to break some subtle preexisting behavior.


def parse_typeddict_args(self, call: CallExpr,
fullname: str) -> Tuple[List[str], List[Type], bool]:
# TODO Share code with check_argument_count in checkexpr.py?
Copy link
Member

Choose a reason for hiding this comment

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

Add TODO: support keyword args.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

types: List[Type]) -> TypeInfo:
strtype = self.named_type('__builtins__.str') # type: Type
dictype = (self.named_type_or_none('builtins.dict', [strtype, AnyType()])
or self.object_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'm guessing this 'or' branch is when the test fixtures don't define dict? It's a fine hack but might deserve a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm guessing this 'or' branch is when the test fixtures don't define dict?

Perhaps. It's the same pattern that build_namedtuple_typeinfo() uses.

I'm not qualified to leave a comment explaining the pattern.


def build_typeddict_typeinfo(self, name: str, items: List[str],
types: List[Type]) -> TypeInfo:
strtype = self.named_type('__builtins__.str') # type: Type
Copy link
Member

Choose a reason for hiding this comment

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

(Not your fault, but don't you find the difference between named_type() and named_type_or_none() jarring? I have to carefully read the implementation every time I see this... :-( )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't really know what the difference is. Presumably named_type_or_none() can fail but there's no documentation explaining what None means in that context.

The underlying lookup_fully_qualified() and lookup_fully_qualified_or_none() have identical documentation even though the latter can presumably fail in some way.

Also named_type_or_none() and lookup_fully_qualified_or_none() can return Optional[...] but aren't marked as such.

Copy link
Member

Choose a reason for hiding this comment

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

We're missing many Optional annotations, so not to worry about those. The difference that was jarring to me is that one starts the lookup in the local namespace (hence __builtins__, which is a secret dict with all the builtins) while the other ("fully qualified") always starts in the module table (hence "builtins"). This is the difference between lookup_qualified() and lookup_fully_qualified_or_none() -- note, "fully".

@@ -127,9 +127,11 @@ N = namedtuple('N', 1) # E: List literal expected as the second argument to name
from collections import namedtuple
N = namedtuple('N', ['x', 1]) # E: String literal expected as namedtuple() item

[case testNamedTupleWithInvalidArgs]
-- NOTE: The following code works at runtime but is not yet supported by mypy.
Copy link
Member

Choose a reason for hiding this comment

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

Honestly, in Python 3.6 I'd love NamedTuple to take keyword args so you can say

Point = typing.NamedTuple('Point', x=int, y=int)

It requires Python 3.6+ because that promises to preserve keyword arg order.

But this would require support in typing too. (@ilevkivskyi?) Not for this PR obviously...

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it would be easy to implement in typing.py
I will open an issue there now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed that keyword args would be a nice syntax to use for NamedTuple.

@davidfstr
Copy link
Contributor Author

Revised. Rebased to tip of master.

@gvanrossum gvanrossum merged commit 76a9a62 into python:master Oct 19, 2016
@gvanrossum
Copy link
Member

Thanks! You can now move on to the next step. (How many steps were you planning?)

@davidfstr
Copy link
Contributor Author

The next step is probably the biggest of the initial steps, as it involves making the type checker aware of TypedDict.

Here are the next few steps, as taken from #985 (comment) :
(2) PR - Create TypedDict instance
(3) PR - Manipulate named TypedDict
(4) PR - Declare TypedDict type with class-based syntax (for Python 3.6+)
(5) PR - Create and manipulate anonymous TypedDict

If (2) and (3) are turn out to be highly coupled, I may opt to do them together.

@gvanrossum
Copy link
Member

gvanrossum commented Oct 19, 2016 via email

@davidfstr
Copy link
Contributor Author

I really much prefer writing
TypedDict('P', x=int, y=int) rather than TypedDict('P', {'x': int, 'y':
int}).

Yes I was thinking of doing that (1b) in parallel with (2)+:
(1) PR - Declare TypedDict type

@gvanrossum
Copy link
Member

gvanrossum commented Oct 19, 2016 via email

@ilevkivskyi
Copy link
Member

(4) PR - Declare TypedDict type with class-based syntax (for Python 3.6+)

As it could be seen from #2245 it is quite easy to implement the 3.6+ syntax when previous steps are done.

@davidfstr davidfstr deleted the declare_typeddict branch October 21, 2016 02:29
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.

6 participants