exaloop / codon

A high-performance, zero-overhead, extensible Python compiler using LLVM
https://docs.exaloop.io/codon
Other
14.32k stars 502 forks source link

Throws error on str.join(str, Generator[pyobj]) #318

Open codeisnotcode opened 1 year ago

codeisnotcode commented 1 year ago

The code:

from python import re regexPattern = '|'.join(map(re.escape, delimiters))

which was inspired by: https://stackoverflow.com/questions/4998629/split-string-with-multiple-delimiters-in-python

and which works fine in Python (using 'import re' rather than "from python import re'), in Codon throws an error: error: 'str' object has no method 'join' with arguments (str, Generator[pyobj])

xavetar commented 1 year ago

Сodon is not a Python. Formally, it is a completely different language with a similar syntax with extension ".codon" no a ".py". You will get error because the Python string != the Codon string. And Codon map != Python map. When you write: "from python import re", you are importing Python's built-in "re" module, which is not fully compatible with Codon types. In the built-in stdlib Codon library, the ability to use native "re" with a native Codon string is implemented.

For usage with Python string you can use decorator for function, see this. When you mix-code with Python (call method with Python decorator), objects convert to native Python objects (see for str).

xavetar commented 1 year ago

from python import re regexPattern = '|'.join(map(re.escape, delimiters))

For mix-code Codon with Python (before create "main.codon"):

@python
def rx_pn(message: str, delimiters: Tuple[str, str, str]) -> str:
    import re
    from typing import Tuple, Union

    def run(message: str, delimiters: Tuple[Union[str]]) -> str:
        return '|'.join(map(re.escape, delimiters))

    return run(message=message, delimiters=delimiters)

message: str = "stackoverflow (c) is awesome... isn't it?"
delimiters: Tuple[str, str, str] = ("a", "...", "(c)")
print(rx_pn(message, delimiters))

Why you can't do "print(rx_pn(message=message, delimiters=delimiters))"? Decorator is not implemented this feature. I think they will solve the problem in the future.

For Native Codon (before create "main.codon"):

import re

message: str = "stackoverflow (c) is awesome... isn't it?"
delimiters: Tuple[str, str, str] = ("a", "...", "(c)")
regex_pattern: str = '|'.join(map(re.escape, delimiters))

print(regex_pattern)

Then build "codon build -release main.codon" and run "./main".

inumanag commented 1 year ago

While we handle pyobj conversion automatically, the conversion currently does not handle "deep" types (e.g., A[pyobj] won't get casted to A[str]). We will probably work on this in the upcoming releases.