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

Pep 9001 Eval command #32

Open
onerandomusername opened this issue Apr 1, 2022 · 2 comments
Open

Pep 9001 Eval command #32

onerandomusername opened this issue Apr 1, 2022 · 2 comments

Comments

@onerandomusername
Copy link

should be able to eval pep 9001 code in snekbox

this is possible and I have an idea to implement it

@wookie184
Copy link
Contributor

Sounds like it should be possible, but would require some unformatting which is a bit hacky. At this point it might just be easier and faster to wait for CPython to implement the PEP. Thoughts?

@lemonyte
Copy link
Member

lemonyte commented Apr 4, 2022

Here's a simple unblurplifier (unformatter) that turns PEP 9001 code back into valid Python. Is it hacky? Yes, but at least it works well enough to qualify for "if it's stupid but it works, it ain't stupid". Also has an option to format the output with Black so it looks like proper Python code rather than a total mess.

import re
import black

import_context_code = """
import importlib
class ImportContext:
    def __init__(self, name: str):
        self.name = name

    def __enter__(self):
        return importlib.import_module(self.name, package=__package__)

    def __exit__(self, exc_type, exc_value, exc_tb):
        pass
"""


def unblurplify(src: str, format: bool = False) -> str:
    """Format blurplified source code into valid Python code."""
    # Invert indents back to regular indentation
    src = invert_indents(src)
    # Inject ImportContext class to handle `with import ...` statements
    src = import_context_code + "\n" + src
    # Replace `unimport` with `del`
    src = re.sub(r"unimport", r"del", src)
    # Replace `sync def` with `sync`
    src = re.sub(r"\bsync\s+def", r"def", src)
    # Replace `import ...` statements with ImportContext class
    src = re.sub(r"\bwith\s+import\s+(\S+)\s+:", r"with ImportContext('\1') as \1:", src)
    # Replace `import ... as ...` statements with ImportContext class
    src = re.sub(r"\bwith\s+import\s+(\S+)\s+as\s+(\S+)\s+:", r"with ImportContext('\1') as \2:", src)
    # Remove type unannotations
    src = re.sub(r"!:\s*[^,)]*", r"", src)
    src = re.sub(r"!->\s*[^:]*", r"", src)
    if format:
        src = black.format_str(src, mode=black.Mode(line_length=120))
    return src

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

No branches or pull requests

3 participants