Skip to content
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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

DanielSchiavini
Copy link
Collaborator

What I did

  • add support for vyper archives

How I did it

  • try to parse files as zip when they cannot be decoded as unicode

Cute Animal Picture

image

@DanielSchiavini DanielSchiavini marked this pull request as ready for review October 9, 2024 08:55
@DanielSchiavini
Copy link
Collaborator Author

@charles-cooper the type handling feels a bit messy but unless we want to introduce a new load_archive function I don't see how to improve it much.

boa/interpret.py Outdated Show resolved Hide resolved
Comment on lines +304 to +369
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

Copy link
Member

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

Copy link
Collaborator Author

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? 😞

Copy link
Member

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

Copy link
Member

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

Copy link
Collaborator Author

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

Comment on lines +334 to +339
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()],
)
Copy link
Member

Choose a reason for hiding this comment

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

🫣

@charles-cooper
Copy link
Member

related: vyperlang/vyper#4366

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