# Add an option to print result of \`python -c\`

**URL:** <https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169>\
**Category:** Ideas\
**Created:** [October 5, 2025, 11:39am UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169 "2025-10-05T11:39:13Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![bswck](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/bswck/32/34363_2.png) [@bswck](https://discuss.python.org/u/bswck)\
**Post date:** [October 5, 2025, 11:39am UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/1 "2025-10-05T11:39:13Z")

</div>

Would you find this small flag useful?

```python
❯ ./python -c 'import sys; sys.version_info'

❯ ./python -pc 'import sys; sys.version_info'
sys.version_info(major=3, minor=15, micro=0, releaselevel='alpha', serial=0)

❯ ./python --help | rg -m 1 -- '-p'
-p : print the result of the program passed in as string (use with -c)

```

It eliminates the need to use `print()` for most common use cases of `-c` by tweaking the internal compilation mode to `"single"`, the same one that is used by the REPL to display results of prompts (via `sys.displayhook`) which may consist of multiple statements.

The interface and the explanation may (and probably should :-)) be a little different, we could add an env var etc.  
For now, I found adding a new flag the easiest.  
A PoC without tests is here: [GitHub - bswck/cpython at b/print-prog-result-option](https://github.com/bswck/cpython/tree/b/print-prog-result-option)

---

<div class="post-metadata">

**Author:** ![bswck](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/bswck/32/34363_2.png) [@bswck](https://discuss.python.org/u/bswck)\
**Post date:** [October 5, 2025, 11:58am UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/2 "2025-10-05T11:58:06Z")

</div>

Small backward compatibility note here: if it’s a good idea, it must be an extra option.

FWIW, most workflows that have a `print` or other void function at the end wouldn’t break, because `displayhook()` avoids writing `None`, but some that don’t and still write to stdout could result in mixed output.

---

<div class="post-metadata">

**Author:** ![Stanfromireland](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/stanfromireland/32/10102_2.png) [@Stanfromireland](https://discuss.python.org/u/Stanfromireland)\
**Post date:** [October 5, 2025, 12:15pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/3 "2025-10-05T12:15:07Z")

</div>

What happens with:

```python
$ python -pc "import sys; sys.version_info; sys.version_info"

```

In the REPL, only the last expression prints, but with your patch both seem to be printed.

---

<div class="post-metadata">

**Author:** ![bswck](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/bswck/32/34363_2.png) [@bswck](https://discuss.python.org/u/bswck)\
**Post date:** [October 5, 2025, 12:36pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/4 "2025-10-05T12:36:55Z")

</div>

Oops, yeah, that makes things harder. The `single` mode prints all expression statements, it seems:

```pycon
>>> exec(compile("import sys; sys.version_info; sys.version_info", "", mode="single"))
sys.version_info(major=3, minor=15, micro=0, releaselevel='alpha', serial=0)
sys.version_info(major=3, minor=15, micro=0, releaselevel='alpha', serial=0)

```

What the REPL does is it walks through separate statements and compiles all to `exec` BUT the last. Only the last one is compiled to `single`:

> <https://github.com/python/cpython/blob/13dc2fde8cec1e8aad04c7635b3da4ff3e3dcb00/Lib/_pyrepl/console.py#L214-L218>

What about the sole idea though? Useful / not useful?

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [October 5, 2025, 12:44pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/5 "2025-10-05T12:44:47Z")

</div>

Yup, it would definitely need to print only final expression.

> [@bswck](#):
>
> What about the sole idea though? Useful / not useful?

I like it. To me it would be very practical convenience for something that I use often.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [October 5, 2025, 1:35pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/6 "2025-10-05T13:35:35Z")

</div>

-0 from me. It’s convenient, but pre-importing `sys` (or `math`, or `random`, …) would _also_ be useful. There’s too much potential for scope creep. And it’s not _that_ hard to write a helper:

```python
function pyx {
    py -c "import sys; exec(compile(sys.argv[1], '-', 'single'))" $args
}

```

This has the same issue as your proof of concept regarding printing _every_ expression. But it can be fixed just as easily here as in the PoC.

And in fact, the package [`pypyp`](https://pypi.org/project/pypyp/) offers all this, and a whole lot more:

```python
❯ uvx pypyp sys.version
3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
❯ uvx pypyp math.pi
3.141592653589793
❯ uvx pypyp "random.random()"
0.07559649122845125

```

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [October 5, 2025, 2:32pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/7 "2025-10-05T14:32:27Z")

</div>

> [@pf\_moore](#):
>
> And in fact, the package [`pypyp`](https://pypi.org/project/pypyp/) offers all this, and a whole lot more

Personally, I am tired depending on external package for every single convenience.

Some things are just nice to come out of the box…

However, I like the first part and I am -0.5 on this after it:

```bash
function pyx() {
python -c "
import math
import random
@lambda c: c()
class p:
    def __rmatmul__ (self, other):
        print(other)
${1}
"
}

pyx "random.random()@p"
# 0.35063726948557183

```

---

<div class="post-metadata">

**Author:** ![bswck](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/bswck/32/34363_2.png) [@bswck](https://discuss.python.org/u/bswck)\
**Post date:** [October 5, 2025, 2:41pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/8 "2025-10-05T14:41:37Z")

</div>

I’ve seen lots and lots of times people writing `print`s in `python -c`, so I thought: why not support it out of the box in Python?

I must admit that I’ve seen pypyp before. I agree that it’s much more powerful and well-suited for perhaps what this idea only partially addresses, as you’ve accurately shown. I didn’t use pypyp because I had thought I would need to install it separately for every Python – but now I have the idea that I’ll just make a Linux-only fork of `pypyp` installed globally that would `execv` itself in the right Python.

Given that `single` mode prints every expression statement, and implementing this feature without that flaw would be unobvious (we would need to deconstruct the input just like the REPL does), I think I’m going to back off from this idea. I’ll just use prints / `pypyp` + `execv`.

Not every idea is a good idea, and this one is “meh” after reconsideration. Good insights as always, thanks a lot everybody!

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [October 5, 2025, 2:54pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/9 "2025-10-05T14:54:39Z")

</div>

> [@dg-pb](#):
>
> Personally, I am tired depending on external package for every single convenience.

I can appreciate this viewpoint. But equally, I’m tired of every “nice to have” convenience being proposed as yet another language or interpreter feature.

Another option is to make this a stdlib module `py -m utils.eval sys.version_info`. But that’s hard to get agreement on, because a significant group of the core devs prefers to have a smaller stdlib, rather than a large “batteries included” one. Personally, I think it’s silly to even _consider_ an interpreter option when a stdlib module would work just fine - adding options because of politics around the role of the stdlib is the wrong approach. We should decide if the functionality is worthwhile and _then_ decide how to implement it. Personally, I think that if this is worth having\[1\], a stdlib module is just fine. If you disagree, what exactly does that say about Python as a language for implementing utility tools in, that you’re willing to argue for a C implementation in the core over a pure Python library module?

That leaves us with “write your own, or use a 3rd party package”. I appreciate that using packages from PyPI can be harder than we’d like it to be, _especially_ for utility applications and scripts, but _again_ that doesn’t mean we should bloat the core - instead we should fix the real problem, which is that distributing 3rd party utilities written in Python isn’t easy enough.

For now, I find it hard to see why:

1. `uvx pypyp`
2. Unpacking the `pypyp` wheel and putting the single `pyp.py` file somewhere on your `PATH`
3. Writing a wrapper script that invokes `compile` and `exec` as we’ve discussed here

are _all_ so difficult that building something into the interpreter is the only viable option.

Personally, I just use `python -c "import sys; print(sys.version_info)"`. I don’t think the proposed functionality is enough of a saving in any case. I’d probably _still_ use the explicit version over a `-p` option, if it was added, if only because at this point it’s in my muscle memory and the benefit is too small to be worth retraining.

* * *

1. Something I’m neutral on.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [October 5, 2025, 3:27pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/10 "2025-10-05T15:27:39Z")

</div>

What about a flag to load `PYTHONSTARTUP` in non-interactive mode?

Would not only be useful for `-c`, but also when simply running a script.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [October 5, 2025, 4:57pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/11 "2025-10-05T16:57:35Z")

</div>

> [@dg-pb](#):
>
> What about a flag to load `PYTHONSTARTUP` in non-interactive mode?

I don’t understand how that would help. What do you have in `PYTHONSTARTUP` that you couldn’t add to your script if the script needed it?

And it doesn’t seem helpful for the OP’s requirement, as that was just to print the last expression - not something `PYTHONSTARTUP` can do. Of course, if you’re thinking about automatically importing things like `sys`, then we’re already extending the scope of the original request, and that’s precisely why I expressed reservations that the feature was a magnet for scope creep 🙂

Having said that, as a general point I would be in favour of proposals that offered more flexible extensions to the basic command line experience. The key here is _flexible_ - rather than providing one very specific behaviour like the proposed `-p`, instead provide a means of invoking your _own_ behaviours, that you can develop as scripts. That’s what the `-m` flag offers, but it’s limited to running installed packages. I’d quite like an option that tells the interpreter to scan `PATH` for the script when invoking `py script.py` - it’s unnecessary on Unix (where you can just use a shebang), but it would be helpful on Windows, where “executable extensions” are a poor substitute. I’m not sure it would get support, though - we’re not typically in the business of patching over poor OS functionality.

But in any case, we’d just be back round to your reluctance to rely on 3rd party code or your own utilities - such a feature would still require you to find or write a script that did the “print the last expression” functionality. I don’t know how we can resolve the problem where the requested functionality only requires a short “convenience” script, but users aren’t willing to write or locate such scripts, instead expecting the interpreter to cover everything they need directly.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [October 5, 2025, 5:36pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/12 "2025-10-05T17:36:25Z")

</div>

Well, it would not exactly address OP’s issue, but personally, I am quite happy with `'sys.version > p'`.

Maybe not as ideal, but given that this benefit would be just a side effect of more general thing, this is good enough for me.

> [@pf\_moore](#):
>
> What do you have in `PYTHONSTARTUP` that you couldn’t add to your script if the script needed it?

> [@pf\_moore](#):
>
> Of course, if you’re thinking about automatically importing things like `sys`, then we’re already extending the scope of the original request

Yes.

> [@pf\_moore](#):
>
> Having said that, as a general point I would be in favour of proposals that offered more flexible extensions to the basic command line experience. The key here is _flexible_

Yes.

Additionally, one specific use case that I have is that I have startup script, which is quite extensive.

I often do initial scribblings in REPL. When I start writing functions, then I move things to a file and start running stuff via `python file.py`. When that gets big enough, I move it to library, etc…

The point is that transition from REPL to script can take a bit more than desirable. Nothing tragic, but given the amount of code that has been written up to that point, the percentage of imports that I need to do is noticeable.

But yeah, this would be a general thing - REPL launches PYTHONSTARTUP. Have an option to load it when doing `python file.py` or `python -c '...'`.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [October 5, 2025, 8:36pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/13 "2025-10-05T20:36:29Z")

</div>

> [@dg-pb](#):
>
> The point is that transition from REPL to script can take a bit more than desirable. Nothing tragic, but given the amount of code that has been written up to that point, the percentage of imports that I need to do is noticeable.

Thanks. I understand your use case a lot better now. But presumably, at _some_ point in the life of a script, unless it’s never going to be anything than a personal utility, you’ll need to decouple it from its dependency on your personal startup code? So a flag such as you propose will delay that point, but not remove it completely.

As an alternative to needing language support, you could add the following boilerplate to the top of your script to execute your `PYTHONSTARTUP` file. IMO, that’s probably a better approach (explicit is better than implicit…):

```python
import os, runpy
startup = os.environ.get("PYTHONSTARTUP")
if startup:
    new_globals = runpy.run_path(startup, run_name=" __main__")
    globals().update(new_globals)

```

I’m not sure that coupling scripts tightly to the user’s local setup (via `PYTHONSTARTUP`) is something that would be supported as a language feature - it’s certainly not something I’d personally use. But if you feel it would be useful, by all means make a proposal (in a different thread - we’ve already highjacked this thread enough!!!)

---

<div class="post-metadata">

**Author:** ![skirpichev](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/skirpichev/32/10996_2.png) [@skirpichev](https://discuss.python.org/u/skirpichev)\
**Post date:** [October 6, 2025, 1:52am UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/14 "2025-10-06T01:52:31Z")

</div>

> [@Stanfromireland](#):
>
> In the REPL, only the last expression prints

It depends. In _old_ REPL - _both_ expressions are printed, e.g.:

```pycon
Python 3.12.11 (tags/v3.12.11:55fee9cf21, Aug 7 2025, 15:54:22) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1;2;3
1
2
3

```

Not sure if this is a bug or feature, I filled issue.

---

<div class="post-metadata">

**Author:** ![tjreedy](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/tjreedy/32/137_2.png) [@tjreedy](https://discuss.python.org/u/tjreedy)\
**Post date:** [October 6, 2025, 8:00pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/15 "2025-10-06T20:00:19Z")

</div>

> [@skirpichev](#):
>
> In _old_ REPL - _both_ expressions are printed, e.g.:

They still are in IDLE 3.14.0rc3. The new behavior seems like a regression bug to me. Someone entering `a;b;c` should get all 3 values.

---

<div class="post-metadata">

**Author:** ![tjreedy](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/tjreedy/32/137_2.png) [@tjreedy](https://discuss.python.org/u/tjreedy)\
**Post date:** [October 6, 2025, 8:12pm UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/16 "2025-10-06T20:12:29Z")

</div>

I am opposed to special-case replacing the 7 chars `print(...)`, which I must remember anyway, with yet another startup option. There are already too many of the latter for me to keep track of.

---

<div class="post-metadata">

**Author:** ![ncoghlan](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ncoghlan/32/14266_2.png) [@ncoghlan](https://discuss.python.org/u/ncoghlan)\
**Post date:** [October 7, 2025, 2:09am UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/17 "2025-10-07T02:09:38Z")

</div>

I’m open to making changes to the way `python -m runpy -c ...` works (I think that’s currently just an error, as I don’t recall ever making it do anything else)

---

<div class="post-metadata">

**Author:** ![skirpichev](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/skirpichev/32/10996_2.png) [@skirpichev](https://discuss.python.org/u/skirpichev)\
**Post date:** [October 7, 2025, 2:10am UTC](https://discuss.python.org/t/add-an-option-to-print-result-of-python-c/104169/18 "2025-10-07T02:10:46Z")

</div>

JFR: [New repl shows output only for last statement from several, separated by ";" · Issue #131217 · python/cpython · GitHub](https://github.com/python/cpython/issues/131217)  
It looks new REPL maintainers rather prefer new behavior, which has own benefits.

(Sorry for some off-topic.)
