m-ou-se / blog

My blog. https://blog.m-ou.se/
4 stars 0 forks source link

writing-python-inside-rust-1/ #2

Open utterances-bot opened 4 years ago

utterances-bot commented 4 years ago

Writing Python inside your Rust code — Part 1 - Mara's Blog

About a year ago, I published a Rust crate called inline-python, which allows you to easily mix some Python into your Rust code using a python!{ .. } macro. In this series, I’ll go through the process of developing this crate from scratch.

https://blog.m-ou.se/writing-python-inside-rust-1/

Omar-Elrefaei commented 4 years ago

Amazing read. Love the feel of the blog.

Few notes:

First, let’s take a look at how we can ... Python code from Rust.

And I am not sure if the long space in What’s next was intentional.

m-ou-se commented 4 years ago

@Omar-Elrefaei Thanks! Updated.

kevincox commented 4 years ago

Instead of swallowing initial whitespace you could just print if True: as the first line. This makes the column numbers correct and gives nicer errors if the code "dedents". I think that would always be an error but you would get a consistent syntax error with python.

This however wouldn't work if the user's code started on the first line of the file, but I don't think there is a fix that gets the correct column and line number in that case without manually manipulating the Python AST.

m-ou-se commented 4 years ago

@kevincox Python errors, backtraces, etc. have no column numbers, only line numbers.

The If True: solution would also accept:

python! {
    x()
else:
    y()
}

So we'll have to check for "dedents" anyway, by remembering the column of the first token.

The current version of inline-python simply uses a checked_sub instead of regular - for subtracting the starting column. If the check fails, it gives this error:

error: Invalid indentation on line 10
  --> inline-python-example/src/main.rs:10:1
   |
10 | else:
   | ^^^^
kevincox commented 4 years ago

Ah, I didn't realize there we no column numbers. This solution definitely wouldn't work if anything touches the first column anyways. So I guess you would still need to check for a complete dedent. Might be worth it if python ever starts reporting Colum numbers but until then your solution is definitely simpler 👍

luser commented 4 years ago

Very cool! This is a really nice write-up on some complex proc macro topics.

If you hadn't seen it before a friend of mine has a project called PyOxidizer that has similar goals for embedding Python in Rust programs, with a focus on building redistributable binaries: https://pyoxidizer.readthedocs.io/en/stable/ . He's solved a lot of tricky engineering problems around embedding a Python interpreter and Python source code in a way that makes the resulting binaries easy to run. You might look into collaborating with him! Being able to embed Python and also write inline Python code with your macro would be a great combination!

tie commented 4 years ago

The following CSS rule breaks layout on Safari for me. It adds enormous amount of empty space before h2 headers in article and the scrolling seems to be almost infinite even after the end of the page.

.post .post-content h2 .anchor .icon-link:before {
  vertical-align: middle;
}
m-ou-se commented 4 years ago

@tie Oh, that's weird. Thanks for debugging! Is it fixed now?

tie commented 4 years ago

@m-ou-se fixed now, thanks!

dmgolembiowski commented 4 years ago

Thanks a bunch for preparing this and spending some extra time to make it immaculate; it really does go a long way.

benwilliam commented 4 years ago

awesome article, thank you Mara

rust-shell-script commented 4 years ago

Thanks for your post! I created a similar project for shell script some time ago: https://github.com/rust-shell-script/rust_cmd_lib and your posts helped me finished the proc_macros implementation.

BTW, why choosing 'a instead of $a for variable names except for highlighting? The later seems more common in the scripting world.

carstimon commented 3 years ago

Thanks for the article. This reads like technical writing rarely does, and has a character that I respected in my best teachers: more like a journey of discovery than an after-the-fact explanation, which makes it accessible (at least enjoyable) even if I've never written a line of rust before. That's hard work, so thanks!