-
-
Notifications
You must be signed in to change notification settings - Fork 130
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
Zipimports #232
Zipimports #232
Conversation
Codecov Report
@@ Coverage Diff @@
## master #232 +/- ##
==========================================
+ Coverage 62.83% 63.33% +0.49%
==========================================
Files 289 289
Lines 23303 23550 +247
==========================================
+ Hits 14643 14915 +272
+ Misses 8660 8635 -25
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a number of inline comment and I focused on the zip importer. Some of them may be related to me not following completely what happens inside the zip importer in particular related to the handling of cached files. On the whole this looks good, but could you please ensure that the lines are no longer than 79 characters (PEP 8), it does not appear to always be the case.
Also could you please make a separate PR for the autocompletion ? I will more time to review this and I think it requires more discussion.
Thanks for your work on this.
enaml/core/import_hooks.py
Outdated
@@ -337,7 +339,27 @@ def _get_magic_info(self, file_info): | |||
timestamp = struct.unpack('i', cache_file.read(4))[0] | |||
return (magic, timestamp) | |||
|
|||
def compile_code(self): | |||
def read_source(self, src_path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not see the point of passing explicitly the src_path, everything is in the file_info so I would simply use that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See further comments for how to avoid code duplication in the ZipImporter
enaml/core/import_hooks.py
Outdated
""" | ||
return read_source(src_path) | ||
|
||
def get_src_mod_time(self, src_path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
enaml/core/import_hooks.py
Outdated
""" Get the last modified time of the given source path """ | ||
return int(os.path.getmtime(src_path)) | ||
|
||
def compile_code(self, src_path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here
enaml/core/import_hooks.py
Outdated
return (code, file_info.src_path) | ||
return (code, src_path) | ||
|
||
def get_cached_code(self, src_path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
enaml/core/import_hooks.py
Outdated
def get_cached_code(self, src_path): | ||
""" Loads and returns the code object for the Enaml module from | ||
the cache if it exists. | ||
Paramters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing blank line before parameters section
enaml/core/import_hooks.py
Outdated
return super(EnamlZipImporter, self).get_src_mod_time(self.archive_path) | ||
|
||
def read_source(self, src_path): | ||
""" Overridden to read the source from the currently opened archive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
tests/test_zipimporter.py
Outdated
zf.writestr(dst, generate_cache(src), compress_type=zipfile.ZIP_DEFLATED) | ||
|
||
|
||
def with_library(f): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be turned into a pytest fixture. I can do it if you are not familiar with them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that would be good.
os.path.exists(archive_path)): | ||
|
||
# Path where code should be within the archive | ||
code_path = '/'.join(pkgpath+[leaf]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not os.path.join ?
enaml/core/import_hooks.py
Outdated
|
||
""" | ||
|
||
# Try to load from the cache on disk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure to follow in which case this can actually apply. Could you explain it to me ?
enaml/core/import_hooks.py
Outdated
# Otherwise, compile from source and attempt to cache it on the system | ||
code_path = os.path.relpath(file_info.src_path, | ||
self.archive_path).replace("\\", "/") | ||
result = self.compile_code(code_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where will the cache be written here ? To me it appears, this should lead to write the cache in the archive.
Ok thanks for looking. I pulled out the scintilla changes and tried to address all the pep8 and doc issues. I also got rid of passing the The caching is a bit confusing. There's two possibilities:
I'm not sure at the moment if the standard importer will cover importing from 1 even if the code was compiled from source within the zip file. If this is the case, then the However the As for the |
I guess what I find the more confusing about the first possibility you evoke concerning the cache is the location of the cache file. Does it live outside the archive ? and how did it end up there, and how can it be found ? |
My understanding is the during the compile_code so yes, if it has write access it will create the cache outside the zip file (if the source exists in the zip). But if the |
I looked into this more, it turns out it always attempts to write the cache but fails since the
So, should I make it write cache to outside the zip or is that undesired behavior? |
That is what I suspected (and also why I failed to understand why we were looking for a cache outside the archive). I am not being familiar with working with zip archive but I guess it would be pretty surprising to modify the content of the archive. So I would say that we can bypass the first cache check and expect to fail writing the cache. However I guess we should first check how Python handles this case. |
I would follow whatever Python is doing. The |
Looking at the Python ZipImporter https://github.com/python/cpython/blob/master/Modules/zipimport.c I do not seed any logic related to writing cache (but I may be wrong). |
This historical PEP goes into the same direction. |
- on windows the tests were crashing because we were non-using universal newlines when reading the files - fix issue with alternative encoding (slight reformating of Python 2 compatibility code) - fix some PEP8 issues - use pytest fixtures in the tests
I fixed some issues while porting the tests to pytest. |
Thanks, merged your changes and also removed the unnecessary caching checks and disabled the |
Basically fixing my own mistake.
This is good to go for me. The only thing that could be improved is adding tests to check that we handle properly encoding declarations. @frmdstryr if you have time to do it feel free to do it. |
@sccolbert any comment on this ? |
Looks generally fine to me. I didn't audit the logic, but if it works, 👍 |
Merging, thanks @frmdstryr for the contribution and sorry for the delay. Closes #115 |
I'm not sure why but git made me commit my other changes so this also includes adding autocomplete to the scintilla widget.
I can break it apart if needed.