# How to use PythonCall with string literal?

**URL:** <https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907>\
**Category:** General Usage\
**Created:** [October 6, 2025, 6:21am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907 "2025-10-06T06:21:50Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex1/32/11771_2.png) [@Alex1](https://discourse.julialang.org/u/Alex1)\
**Post date:** [October 6, 2025, 6:21am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/1 "2025-10-06T06:21:50Z")

</div>

I’m upgrading from older PyCall to PythonCall, but can’t figure out how make it work.

I prefer to use python code as a sting to evaluate, it has nice syntax highlight, looks like normal python code and easy to copy/paste. Like PyCall does. I don’t want to wrap it into julia proxies. Is it possible?

```julia-auto
using PythonCall

py"""
def add(a, b):
  return a + b
"""

py"add".(2, 3)

```

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [October 6, 2025, 6:33am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/2 "2025-10-06T06:33:09Z")

</div>

There is no string macro in PythonCall for this, you need to use `@pyexec` and `@pyeval`.

The direct equivalent of your code is:

```julia-auto
using PythonCall

@pyexec """
global add
def add(a, b):
  return a + b
"""

@pyeval("add")(2, 3)

```

Although a bit more idiomatic (and efficient) is:

```julia-auto
using PythonCall

@pyexec """
def add(a, b):
  return a + b
""" => add

add(2, 3)

```

The reason for having macros instead of string macros is that it lets us have this nice `=>` syntax for inputs and outputs, which you can’t do with PyCall. In turn this means the code can be executed in local scope (because we can extract the desired result before the scope is destroyed), so you don’t clutter global scope.

---

<div class="post-metadata">

**Author:** ![Alex1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex1/32/11771_2.png) [@Alex1](https://discourse.julialang.org/u/Alex1)\
**Post date:** [October 6, 2025, 6:38am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/3 "2025-10-06T06:38:09Z")

</div>

thanks, is there a way to enable the python syntax highlight inside `@pyexec "..."` in VSCode? Like the `py"..."` does?

And, does it support multiple return, like:

```julia-auto
@pyexec """
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b
""" => add, subtract

```

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [October 6, 2025, 7:11am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/4 "2025-10-06T07:11:38Z")

</div>

I don’t think syntax highlighting these is currently possible but it would be nice to have. This is where it is done for `py"""...` if you want to tackle it: [julia-vscode/syntaxes/julia\_vscode.json at 4b61fb2e3635d98f852de851bdb477e5bd082930 · julia-vscode/julia-vscode · GitHub](https://github.com/julia-vscode/julia-vscode/blob/4b61fb2e3635d98f852de851bdb477e5bd082930/syntaxes/julia_vscode.json#L536)

And yes, multiple inputs and outputs are supported, see the docstring.

---

<div class="post-metadata">

**Author:** ![Alex1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex1/32/11771_2.png) [@Alex1](https://discourse.julialang.org/u/Alex1)\
**Post date:** [October 6, 2025, 7:34am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/6 "2025-10-06T07:34:37Z")

</div>

Too hard to use, removed it and switched back to PyCall. Maybe PythonCall is newer and does complex things better, the problem is it fails to do basic things well.

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [October 6, 2025, 8:15am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/7 "2025-10-06T08:15:24Z")

</div>

Can you be more specific about what you don’t like about PythonCall?

---

<div class="post-metadata">

**Author:** ![icweaver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/icweaver/32/45764_2.png) [@icweaver](https://discourse.julialang.org/u/icweaver)\
**Post date:** [October 8, 2025, 4:16am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/8 "2025-10-08T04:16:16Z")

</div>

> [@cjdoris](#):
>
> Although a bit more idiomatic (and efficient) is:
> 
> ```julia-auto
> using PythonCall
> 
> @pyexec """
> def add(a, b):
> return a + b
> """ => add
> 
> add(2, 3)
> 
> ```

Oooh, I love this, and it even works in separate Pluto cells! Could we add this and maybe a few other common patters to the [FAQ](https://juliapy.github.io/PythonCall.jl/stable/faq/)? I’d be happy to get a PR going. I especially love how nice working with the scoping is

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [October 8, 2025, 12:37pm UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/9 "2025-10-08T12:37:41Z")

</div>

> [@icweaver](#):
>
> Could we add this and maybe a few other common patters to the [FAQ](https://juliapy.github.io/PythonCall.jl/stable/faq/)? I’d be happy to get a PR going.

Yep please do. In fact it might be better in the guide.

---

<div class="post-metadata">

**Author:** ![icweaver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/icweaver/32/45764_2.png) [@icweaver](https://discourse.julialang.org/u/icweaver)\
**Post date:** [October 9, 2025, 4:07am UTC](https://discourse.julialang.org/t/how-to-use-pythoncall-with-string-literal/132907/10 "2025-10-09T04:07:18Z")

</div>

For sure, opened [docs: Add python block usage examples by icweaver · Pull Request #687 · JuliaPy/PythonCall.jl · GitHub](https://github.com/JuliaPy/PythonCall.jl/pull/687)
