-
Notifications
You must be signed in to change notification settings - Fork 51
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
feat: add support for vyper archives (.vyz) #328
base: master
Are you sure you want to change the base?
Conversation
@charles-cooper the type handling feels a bit messy but unless we want to introduce a new |
def _create_compiler_data( | ||
path: Path, resolved_path: Path, source_code: str | bytes, settings: Settings | ||
) -> CompilerData: | ||
try: | ||
return _create_archive_compiler_data(source_code, settings) | ||
except NotZipInput: | ||
pass | ||
|
||
if isinstance(source_code, bytes): | ||
source_code = source_code.decode() | ||
|
||
global _search_path | ||
file_input = FileInput( | ||
contents=source_code, source_id=-1, path=path, resolved_path=resolved_path | ||
) | ||
input_bundle = FilesystemInputBundle(get_search_paths(_search_path)) | ||
return CompilerData(file_input, input_bundle, settings) | ||
|
||
|
||
def _create_archive_compiler_data( | ||
zip_contents: str | bytes, settings: Settings | ||
) -> CompilerData: | ||
with _open_zip(zip_contents) as archive: | ||
# read the whole zip into memory so it can be serialized to the cache | ||
files = {name: archive.read(name).decode() for name in archive.namelist()} | ||
|
||
targets = files["MANIFEST/compilation_targets"].splitlines() | ||
if len(targets) != 1: | ||
raise BadArchive("Multiple compilation targets not supported!") | ||
|
||
input_bundle = JSONInputBundle( | ||
input_json={ | ||
PurePath(name): {"content": content} for name, content in files.items() | ||
}, | ||
search_paths=[PurePath(p) for p in files["MANIFEST/searchpaths"].splitlines()], | ||
) | ||
|
||
main_path = PurePath(targets[0]) | ||
file = input_bundle.load_file(main_path) | ||
assert isinstance(file, FileInput) # help mypy | ||
settings_json = json.loads(files["MANIFEST/settings.json"]) | ||
settings = merge_settings( | ||
settings, | ||
Settings.from_dict(settings_json), | ||
lhs_source="command line", | ||
rhs_source="archive settings", | ||
) | ||
integrity_sum = files["MANIFEST/integrity"].strip() | ||
return CompilerData(file, input_bundle, settings, integrity_sum) | ||
|
||
|
||
def _open_zip(zip_contents): | ||
if isinstance(zip_contents, str): | ||
zip_contents = zip_contents.encode() | ||
try: | ||
buf = BytesIO(zip_contents) | ||
return ZipFile(buf, mode="r") | ||
except BadZipFile as e1: | ||
try: | ||
# don't validate base64 to allow for newlines | ||
zip_contents = b64decode(zip_contents, validate=False) | ||
buf = BytesIO(zip_contents) | ||
return ZipFile(buf, mode="r") | ||
except (BadZipFile, binascii.Error): | ||
raise NotZipInput() from e1 | ||
|
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 think we should refactor the compiler so that we can return CompilerData
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.
So no vyz before 0.4.0b2 at the very least? 😞
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 suppose we could keep it this way but with a note to delete after refactored in vyper
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.
that conversion of the input bundle is a bit awkward though
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.
it is, but this is the workaround I found instead of that archive._lock=None
input_bundle = JSONInputBundle( | ||
input_json={ | ||
PurePath(name): {"content": content} for name, content in files.items() | ||
}, | ||
search_paths=[PurePath(p) for p in files["MANIFEST/searchpaths"].splitlines()], | ||
) |
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.
🫣
related: vyperlang/vyper#4366 |
What I did
How I did it
Cute Animal Picture