Why doesn't the command line show all my print() statements?

While developing I use print() statements (with f-strings) but the not all the output is sent to the console.

When I hit ctrl-c and kill the server - I can see all that is printed but when it’s running I don’t always see every statement that should be printing.

I assume there is some sort of timing issue here - is there a way to force the server that comes with Django to print out all the print() statements?

P.S. Yes I know I should be using logging - but the world is not a perfect place.

I’m guessing you’re using manage.py runserver to run your code during development. If so, I’ve also encountered this in the past.

What has worked for me has been to disable output buffering in the python instance by running manage with the -u parameter. In other words, your command would look something like this:
python -u manage.py runserver

Another similar option would be to set the PYTHONUNBUFFERED environment variable to any non-empty string.

(see https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUNBUFFERED)

1 Like

Thank you Ken! I will try that!

For me the python-u manage.py runserver command did not do the trick, but what happens in my case is:

No output:
print(os.getcwd()

Correct output:
print("----", os.getcwd()

I have no explanation why this is the case, but this always does the trick for me.

I think this is a feature of newer Django versions. I would like to know how to switch that off.

What precisely is the “this” that you are referring to here?

Django does provide a wrapper for stdout & stderr for management commands (see django.core.management.base), but the majority of that code was committed in 2013 / 2014, when support for Python 3 was added and the print command was removed in favor of the print function. This doesn’t exactly make it “new”.

Python also checks to see if stdout is associated with a terminal to determine if print output should be buffered or not - which means the print function can act differently depending upon environmental factors.

In the general case, for example using manage.py runserver from a shell, print output shows up in the console log.
For example, this view:

def hello_world(request):
  print("Hello world")
  return HttpResponse("Hello World")

Generates this in the console log:

Hello world
HTTP GET /b/p2/hw/ 200 [0.03, 127.0.0.1:37676]

(And this is without using python -u or any other buffered settings.)

If you have print functions in your code and are not getting output, then it would be worth investigating this in more detail.

There’s a flush keyword argument to print(). Did you try that?

I personally haven’t seen this, and it seems like if you can make a clean reproduction of this this should be treated as a very serious bug. Print debugging is the last defense when everything else fails, that must work.