Skip to content

[WIP] Make incremental not propagate staleness if the public interface of a module is unchanged - #2002

Closed
Michael0x2a wants to merge 7 commits into
python:masterfrom
Michael0x2a:incremental-interface
Closed

Michael0x2a wants to merge 7 commits into
python:masterfrom
Michael0x2a:incremental-interface

Conversation

@Michael0x2a

Copy link
Copy Markdown
Collaborator

This pull request modifies incremental mode so that if a module is modified in a way such that the types for any of its publicly accessible symbols are unchanged, we recheck the file but don't queue up the importers to be rechecked. For example, if we change the contents of a certain function but not its type signature, we would ideally like to have to re-check only that file and not all the dependees.

Or, more precisely, if module A imports module B and module B's public interface is unchanged, then we consider module B to be internally stale but not externally stale and consider module A to still be fresh.

It does so by adding a new visitor named InterfaceExtractor within modinterface.py that makes a best-effort attempt at extracting the "public interface" of a module once its been parsed. Since this extraction happens at an early stage in the pipeline (in build.load_graph, which calls parse_file) it's not necessarily always possible to extract the actual types, so the extractor falls back to using a serialized form of the underlying symbol node in those cases.

The public interface of a module consists of al imports, all top-level variables/functions/classes, and all methods/class attributes/nested class definitions.

This is a work-in-progress. TODO:

  • Figure out why two test cases are failing
  • Add even more test cases
  • Since imports are a part of the public interface, changing the public interface causes incremental to often revert back to its current behavior (propagate "staleness" to all importers). It would be nice to figure out how to also throttle this back.

@Michael0x2a Michael0x2a changed the title [WIP] Make incremental stop treating [WIP] Make incremental not propagate staleness if the public interface of a module is unchanged Aug 9, 2016
@Michael0x2a
Michael0x2a force-pushed the incremental-interface branch from 63dc1b2 to 331db38 Compare August 9, 2016 22:39
This commit modifies the incremental tests so that changes that don't
change the "public interface" of the file will not trigger a recheck in
any dependees.
"modinterface.py" is a new stage of the parsing process that ideally
happens relatively early, right after each file is parsed. It performs a
lightweight, best-effort-basis crawl of the parse tree to try and obtain
approximate type signatures of a given module to determine what its
"public interface" is.

If it cannot deduce the type signature of a given symbol, it resorts to
using a serialized form of the entire expression so that absolutely any
changes to how that symbol is derived is reflected.
Previously, if the file timestamp or size differed from the data
stored in the meta files, we treated it as immediately stale.

In preparation for the interface changes, this commit extracts that
logic into a separate flag.
This commit modifies the file parsing logic to also compute and store
the public interface for a module.

The public interface is not yet used anywhere.
This commit finally enables the build process to throttle back
incremental mode when the public interface of a method is not changed.
Previously, we always extracted the public interface, even though
there's really no need to do so when not running incremental mode.
@Michael0x2a

Copy link
Copy Markdown
Collaborator Author

#2014 is a better and more accurate version of this pull request.

@Michael0x2a
Michael0x2a deleted the incremental-interface branch August 15, 2016 22:17
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.

2 participants