Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8646585
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T12:51:01+00:00 2026-06-12T12:51:01+00:00

NB: I have not attempted to reproduce the problem described below under Windows, or

  • 0

NB: I have not attempted to reproduce the problem described below under Windows, or with versions of Python other than 2.7.3.

The most reliable way to elicit the problem in question is to pipe the output of the following test script through : (under bash):

try:
    for n in range(20):
        print n
except:
    pass

I.e.:

% python testscript.py | :
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr

My question is:

How can I modify the test script above to avoid the error message when the script is run as shown (under Unix/bash)?

(As the test script shows, the error cannot be trapped with a try-except.)

The example above is, admittedly, highly artificial, but I’m running into the same problem sometimes when the output of a script of mine is piped through some 3rd party software.

The error message is certainly harmless, but it is disconcerting to end-users, so I would like to silence it.

EDIT: The following script, which differs from the original one above only in that it redefines sys.excepthook, behaves exactly like the one given above.

import sys
STDERR = sys.stderr
def excepthook(*args):
    print >> STDERR, 'caught'
    print >> STDERR, args

sys.excepthook = excepthook

try:
    for n in range(20):
        print n
except:
    pass
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T12:51:03+00:00Added an answer on June 12, 2026 at 12:51 pm

    How can I modify the test script above to avoid the error message when the script is run as shown (under Unix/bash)?

    You will need to prevent the script from writing anything to standard output. That means removing any print statements and any use of sys.stdout.write, as well as any code that calls those.

    The reason this is happening is that you’re piping a nonzero amount of output from your Python script to something which never reads from standard input. This is not unique to the : command; you can get the same result by piping to any command which doesn’t read standard input, such as

    python testscript.py | cd .
    

    Or for a simpler example, consider a script printer.py containing nothing more than

    print 'abcde'
    

    Then

    python printer.py | python printer.py
    

    will produce the same error.

    When you pipe the output of one program into another, the output produced by the writing program gets backed up in a buffer, and waits for the reading program to request that data from the buffer. As long as the buffer is nonempty, any attempt to close the writing file object is supposed to fail with an error. This is the root cause of the messages you’re seeing.

    The specific code that triggers the error is in the C language implementation of Python, which explains why you can’t catch it with a try/except block: it runs after the contents of your script has finished processing. Basically, while Python is shutting itself down, it attempts to close stdout, but that fails because there is still buffered output waiting to be read. So Python tries to report this error as it would normally, but sys.excepthook has already been removed as part of the finalization procedure, so that fails. Python then tries to print a message to sys.stderr, but that has already been deallocated so again, it fails. The reason you see the messages on the screen is that the Python code does contain a contingency fprintf to write out some output to the file pointer directly, even if Python’s output object doesn’t exist.

    Technical details

    For those interested in the details of this procedure, let’s take a look at the Python interpreter’s shutdown sequence, which is implemented in the Py_Finalize function of pythonrun.c.

    1. After invoking exit hooks and shutting down threads, the finalization code calls PyImport_Cleanup to finalize and deallocate all imported modules. The next-to-last task performed by this function is removing the sys module, which mainly consists of calling _PyModule_Clear to clear all the entries in the module’s dictionary – including, in particular, the standard stream objects (the Python objects) such as stdout and stderr.
    2. When a value is removed from a dictionary or replaced by a new value, its reference count is decremented using the Py_DECREF macro. Objects whose reference count reaches zero become eligible for deallocation. Since the sys module holds the last remaining references to the standard stream objects, when those references are unset by _PyModule_Clear, they are then ready to be deallocated.1
    3. Deallocation of a Python file object is accomplished by the file_dealloc function in fileobject.c. This first invokes the Python file object’s close method using the aptly-named close_the_file function:

      ret = close_the_file(f);
      

      For a standard file object, close_the_file(f) delegates to the C fclose function, which sets an error condition if there is still data to be written to the file pointer. file_dealloc then checks for that error condition and prints the first message you see:

      if (!ret) {
          PySys_WriteStderr("close failed in file object destructor:\n");
          PyErr_Print();
      }
      else {
          Py_DECREF(ret);
      }
      
    4. After printing that message, Python then attempts to display the exception using PyErr_Print. That delegates to PyErr_PrintEx, and as part of its functionality, PyErr_PrintEx attempts to access the Python exception printer from sys.excepthook.

      hook = PySys_GetObject("excepthook");
      

      This would be fine if done in the normal course of a Python program, but in this situation, sys.excepthook has already been cleared.2 Python checks for this error condition and prints the second message as a notification.

      if (hook && hook != Py_None) {
          ...
      } else {
          PySys_WriteStderr("sys.excepthook is missing\n");
          PyErr_Display(exception, v, tb);
      }
      
    5. After notifying us about the missing excepthook, Python then falls back to printing the exception info using PyErr_Display, which is the default method for displaying a stack trace. The very first thing this function does is try to access sys.stderr.

      PyObject *f = PySys_GetObject("stderr");
      

      In this case, that doesn’t work because sys.stderr has already been cleared and is inaccessible.3 So the code invokes fprintf directly to send the third message to the C standard error stream.

      if (f == NULL || f == Py_None)
          fprintf(stderr, "lost sys.stderr\n");
      

    Interestingly, the behavior is a little different in Python 3.4+ because the finalization procedure now explicitly flushes the standard output and error streams before builtin modules are cleared. This way, if you have data waiting to be written, you get an error that explicitly signals that condition, rather than an “accidental” failure in the normal finalization procedure. Also, if you run

    python printer.py | python printer.py
    

    using Python 3.4 (after putting parentheses on the print statement of course), you don’t get any error at all. I suppose the second invocation of Python may be consuming standard input for some reason, but that’s a whole separate issue.


    1Actually, that’s a lie. Python’s import mechanism caches a copy of each imported module’s dictionary, which is not released until _PyImport_Fini runs, later in the implementation of Py_Finalize, and that’s when the last references to the standard stream objects disappear. Once the reference count reaches zero, Py_DECREF deallocates the objects immediately. But all that matters for the main answer is that the references are removed from the sys module’s dictionary and then deallocated sometime later.

    2Again, this is because the sys module’s dictionary is cleared completely before anything is really deallocated, thanks to the attribute caching mechanism. You can run Python with the -vv option to see all the module’s attributes being unset before you get the error message about closing the file pointer.

    3This particular piece of behavior is the only part that doesn’t make sense unless you know about the attribute caching mechanism mentioned in previous footnotes.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I attempted the two commonly mentioned methods below, and they have not worked -
have not tested on windows. but in ubuntu when u disconnect from the network,
I have a strange problem where MonoTouch seems to be either not compiling methods
I have not had to do something like this in the past and am
I have not started creating the code so I don't have anything to show,
I have not worked with parameters in ADO.Net very much. I'm writing a custom
I have not changed any of the configuration options for sessions in my php.ini.
I have not used jquery much yet and not very familiar with it. Trying
We have not purchased an SSL certificate so the user of our website has
I have not been able to find any definitive answers to this question: Can

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.