DOI-USGS / gems-tools-arcmap

Tools for working with the GeMS geologic map database schema in ArcGIS
Creative Commons Zero v1.0 Universal
42 stars 21 forks source link

FGDC metadata, step 2 (v1.6.9); "IOError: [Errno 9] Bad file descriptor" #78

Open alwunder opened 3 years ago

alwunder commented 3 years ago

This is an issue and (I think) a solution all in one!

I kept receiving this error over and over when executing the FGDC Metadata Step 2 script: "IOError: [Errno 9] Bad file descriptor" following an error with the print msg line in the addMsgAndPrint() function of GeMS_UtilityFunctions.py.

See screenshot: image

I tried editing the database, thinking that I had an offending item in the particular feature class the script was failing on. But then the script failed repeatedly at another database location... oh boy...

A little research into the error uncovered that this is a well-known problem with older versions of Python (pre-Python 3) and the old print to sys.stdout (or the console display) that causes this memory issue (buffer overrun) and a crash. See discussion in this article: https://bugs.python.org/issue706263#msg191902

This is particularly frustrating for users who are executing scripts from ArcToolbox, as the console isn't even being used and the "print" messages have nothing to do with the functionality of the main script.

So, I have edited my copy of the GeMS_UtilityFunctions.py script as follows to correct the error:

At the beginning of the script with the import statements:

# TRYING TO FIX THE CONSOLE PRINT IO ERROR:
# Added the "from __future__" call below to implement Python 3+ style print() function
# https://bugs.python.org/issue706263#msg191902
# See addMsgAndPrint() function below for the rest of the code
from __future__ import print_function  # <== this is the new code
import arcpy
import os.path
import time
import glob
import requests
import sys

And in the addMsgAndPrint() function:

def addMsgAndPrint(msg, severity=0):
    # prints msg to screen (console) and adds msg to the geoprocessor (in case this is run as a tool)

    # TRYING TO FIX THE CONSOLE PRINT IO ERROR:
    # An error "IOError: [Errno 9] Bad file descriptor" kept happening at the "print" statement below.
    # The exception is raised after printing 4096 bytes. The exception is rather obscure but the byte
    # count suggests a buffer overflow. This is particularly frustrating, as users of the tool working
    # from ArcToolbox will have the process fail even though they have no need for the "print" function.
    # Commenting the "print" statement out works when running the script as a tool, since the messages
    # are sent to the geoprocessing window by the code that follows, but there will be no messages if
    # the script is run from the console.  Code below keeps script from failing when run as a tool but
    # has not been tested in the console.
    # https://bugs.python.org/issue706263#msg191902

    # Original syntax:
    #print msg

    # New function style:
    if sys.executable.endswith("pythonw.exe"):   # <== this is the new code
        sys.stdout = sys.stdout = None           # <== this is the new code
        print(msg)                               # <== this is the new code

    # Adds messages to the geoprocessing window:
    try:
        for string in msg.split('\n'):
            # Add appropriate geoprocessing message 
            if severity == 0:
                arcpy.AddMessage(string)
            elif severity == 1:
                arcpy.AddWarning(string)
            elif severity == 2:
                arcpy.AddError(string)
    except:
        pass

The bonus here is that since the edit is made in the GeMS_UtilityFunctions.py script, it should (hopefully) remove the potential for this error across all the GeMS scripts!

Screenshot after edits: image

I've run the edited script on a couple different databases and haven't had the error recur.

Hope this helps others if they run into the same problem.

ethoms-usgs commented 3 years ago

I had not run into that problem before, but thank you for looking into it. I like your solution and will try to update the tool soon. Thanks again!