jecki / ts2python

Python-interoperability for Typescript-Interfaces
Apache License 2.0
42 stars 4 forks source link

BUG: cannot import name `main` from `ts2pythonParser` #1

Open Nicholas-Schaub opened 2 years ago

Nicholas-Schaub commented 2 years ago

I installed via (Python 3.9):

pip install ts2pythonParser

When running:

ts2python file.ts

I receive the following error:

ImportError: cannot import name 'main' from 'ts2pythonParser'
Nicholas-Schaub commented 2 years ago

Attempted to fix by commenting:

if __name__=="__main__":

and replace with:

def main():

Then I received the following error:

raise ValueError("Malformed syntax-tree!")

PolusComputeSchema.ts:3:5: Error (1010): 'item' expected by parser 'enum', but »'path',\n  ...« found instead!

The enum being imported is:

export enum PluginOutputType {
    'path',
 }
jecki commented 2 years ago

Thanks for the bug-report and for the suggestion with def main(). Here is a work-around until the enum bug is fixed: Change the enum definition in the typescript-source to:

export enum PluginOutputType { path = 'path' }

i.e. add "path =" and remove the comma before the closing bracket.

jecki commented 2 years ago

The enum-bug is fixed. Just uploaded a new version (0.6.1) to PYPI. Enjoy!

There are still some restrictions concerning the translation of Typescript enums to Python Enums, though. See the updated documentation on mapping of enums

Let me know, if this does not work for you.

Nicholas-Schaub commented 2 years ago

Thanks for the response. I'll check this out.

Nicholas-Schaub commented 2 years ago

I checked it out. Looks like it's working now. I tried converting a module definition to Python, and it didn't work out so well. Some of the other files I tested it out on worked well.

Nicholas-Schaub commented 2 years ago

Actually, one thing I might be able to do is grab individual module interfaces and convert them. It doesn't look like you currently support selecting the types you want to convert. Is that something you would consider implementing?

It might look something like this: ts2python code.ts --types MyTypeToConvert

I could open a separate issue to outline more things and discuss.

Nicholas-Schaub commented 2 years ago

I guess I could explain a bit about what I'm doing. I want to expose code running in typescript to Python, and basically do a 1:1 mapping so that you can read the typescript documentation and then almost directly use the syntax in Python. Basically, Python would execute no code, it would just send to typescript by websocket and return the result. I suspect there is a good, generic way of doing this so that you can directly wrap a typescript module in Python with nominal additional code. The module I'm trying to incorporate into Python has 15k lines in the module definition, so I would definitely be saving time trying to use this kind of abstraction rather than trying to write each function. It would also be easier to maintain.

I'm happy to contribute if this is within the scope of this project. I have a number of other typescript modules I would like to make similar Python wrappers for. If not, it's time for regular expressions...

jecki commented 2 years ago

Thanks for all the input. Allowing to convert just select types from a ts-file (e.g. ts2python code.ts --types MyTypeToConvert ) sounds like a good idea to me. I'd appreciate, if you opened a separate issue for that.

My goals with ts2python were a bit more modest. (I wonder whether the name, I gave the project, is misleading...) I did not want to convert any TypeScript code to Python, but only TypeScript data records. Sort of the opposite of what py-ts-interfaces does. So, I am not planning to implement a full typescript to Python transpiler.

My first, and until now, only use case have been the requests of the language server protocol. So anything that goes beyond the data types and language constructs used there, is likely to fail - for now.

This said, I'd sure like to extend this a little more. Since I am expecting to use this for more projects, I am happy to weed out any errors beforehand. If you like to, you can help me by providing me with TypeScript-files or Typescript-Interface-Definitions that cause trouble when run through ts2python. If the kind of trouble they cause is an error message (either an error message generated by ts2python or a Python error message, because ty2pthon crashed), I can probably figure out the cause myself. (So, you do not need to add any commentary, when sending a file or an example case.) If the kind of trouble is an unexpected or erroneous result, a bit of commentary like providing the expected result would be helpful.

So, go ahead and send me some examples if you like.

Nicholas-Schaub commented 2 years ago

I'll open a new issue shortly for the select types request.

I think I saw py-ts-interfaces, but I ended up using pydantic2ts since I've become a fan of pydantic. It's robust enough where I can create pydantic schema for our FastAPI backends that we can take the body and response objects and directly generate interfaces that the frontend written in typescript can use.

However, one of the things we are running into somewhat commonly is that we have existing typescript that we want to write a Python interface for. I think for the purposes of this project, it might be one step too large to do a complete transpiler, where all code gets converted to Python. I think a more reasonable ask might be to just slightly extend what you've done already with interfaces to something like module definition files. I'm not a typescript guru, but these seem like the equivalent of a C++ header file that contains property and function definitions but do not generally run any code. I think generating Python code that can create function definitions and scrape outputs would give someone a good first step for creating Python bindings to a typescript application.

I have also decided to take over a project for writing vscode extensions using Python. I was trying to contribute to it, but the guy running it decided to archive it without warning.so I'm hard forking and reformatting. One thing I'm trying to do is reduce the amount of actual code writing to create functions, so I'm trying to digest the vscode api module definition: https://github.com/microsoft/vscode/blob/main/src/vscode-dts/vscode.d.ts

What would happen in an ideal world is that when the vscode api module updates, I could grab that using some combination of your package and templating to convert to Python code that calls typescript over a websocket. That way, I write less code and keeping up to date with the latest API is much less maintenance. I have similar use cases for other projects, but I think this is one of the more complicated ones.

jecki commented 2 years ago

I like the suggestion of developing ts2python into something that produces module definition files! Thanks for pointing out the vscode api module definition to me. I will use that as use case for further development and start by trying to make ts2python digest it and transpile at least those parts that ts2python already understands. (Well, as time permits. I can only work once in a while on this project.)

My motivation for writing ts2python was exactly the same: I thought it rather cumbersome to rewrite (or extend) the Python-definitions for a set of typescript interfaces manually every time the API changes. So, I am with you here.

pydantic looks great to me. I have not used it yet, but only looked into its documentation, so far. I went with TypedDicts for ts2python (though other options might be supported in the future), because other than pydantic or Python's dataclasses, TypedDicts allow for sparsely populated objects. As far as I can see pydantic does not offer real support for not-required fields in the sense of PEP655. (pydantic's optional/required fields do not seem to be an equivalent for what is described in PEP655) However, sparsely populated objects seem to be used in abundance by typescript-API, or at least they are in the language server protocol.

jecki commented 2 years ago

Just to let you know: ts2pythonParser.py is now in state, where it is able to digest vscode.d.ts without crashing. However, the result (see: https://github.com/jecki/ts2python/blob/main/devdata/vscode.d.py) still contains many errors and omissions. Rounding this up seems to be more work than I originally expected, so this is going to take a while. I'll drop a note by the time it is nearing a state where the result of transpiling vscode.d.ts can be considered useful.

Nicholas-Schaub commented 2 years ago

Ok, thanks for the update.

I've been playing with my own approach to parsing and generating code using regular expressions and templates. It's definitely a chore. I can only imagine doing it a "correct" way is even moreso.