Select to view content in your preferred language

Read print() as arcpy.AddMessage() (and vice versa)

230
6
2 weeks ago
Status: Open
AlfredBaldenweck
MVP Regular Contributor

A continuing source of frustration is writing code as a notebook or py file before transferring it into a toolbox and having to find and replace all instances of print() with arcpy.AddMessage(). A similar thing happens in reverse: Sometimes I am copy-pasting code from my toolbox into the Python Window or something and need to change arcpy.AddMessage() to print().

I have seen people get around this by making a prnt(0 function:

def prnt(text):
    arcpy.AddMessage(text)
    print(text)

It would really be better if the python window and notebooks just read arcpy.AddMessage/Error/Warning() as "print()", and if the geoprocessing pane read print() as "AddMessage()" 

6 Comments
GISDepartmentMFM

I agree that this would be a very nice QOL feature. The rout I personally took was to a log function that writes to a file in the project file so I can see the prints regardless of where I am running it however this comes with the draw back of if there are lots of print statements Notepad++ takes a bit to catch back up with the program flow.

DanPatterson

Don't mess with existing python namespace, just create your own

def tweet(msg):
    """Produce a message for both arcpy and python
    : msg - a text message
    """
    m = "{}".format(msg)
    arcpy.AddMessage(m)
    print(m)
AlfredBaldenweck

Yeah, that is the exact thing I don't want to do???

That requires me to copy an extra function into wherever I'm copy-pasting

HaydenWelch

I just override builtins.print:

import builtins

def print(*values: object,
          sep: str = " ",
          end: str = "\n",
          file = None,
          flush: bool = False,
          severity: Literal['INFO', 'WARNING', 'ERROR'] = 'INFO'):
    """ Print a message to the ArcGIS Pro message queue and stdout
    set severity to 'WARNING' or 'ERROR' to print to the ArcGIS Pro message queue with the appropriate severity
    """

    # Print the message to stdout
    builtins.print(*values, sep=sep, end=end, file=file, flush=flush)
    
    end = "" if end == '\n' else end
    message = f"{sep.join(map(str, values))}{end}"
    # Print the message to the ArcGIS Pro message queue with the appropriate severity
    match severity:
        case "WARNING":
            arcpy.AddWarning(f"{message}")
        case "ERROR":
            arcpy.AddError(f"{message}")
        case _:
            arcpy.AddMessage(f"{message}")
    return

 

Allowing this to be imported to shadow `print` should be safe since it maps properly to `print` and would allow existing code that uses print statements to also emit arcpy Messages. Here's a more complete version that implements the proper typing:

import builtins
import arcpy

from _typeshed import SupportsWrite, SupportsFlush, _T_contra
from typing import Protocol, Literal

class _SupportsWriteAndFlush(SupportsWrite[_T_contra], SupportsFlush, Protocol[_T_contra]): ...

def print(*values: object,
          sep: str | None = " ",
          end: str | None = "\n",
          file: _SupportsWriteAndFlush[str] | None = None,
          flush: bool = False,
          severity: Literal['INFO', 'WARNING', 'ERROR'] = 'INFO'):
    """ Print a message to the ArcGIS Pro message queue and stdout
    set severity to 'WARNING' or 'ERROR' to print to the ArcGIS Pro message queue with the appropriate severity
    """

    # Print the message to stdout
    builtins.print(*values, sep=sep, end=end, file=file, flush=flush)
    
    end = "" if end == '\n' else end
    message = f"{sep.join(map(str, values))}{end or ''}"
    # Print the message to the ArcGIS Pro message queue with the appropriate severity
    match severity:
        case "WARNING":
            arcpy.AddWarning(f"{message}")
        case "ERROR":
            arcpy.AddError(f"{message}")
        case _:
            arcpy.AddMessage(f"{message}")
    return
Luke_Pinner

Seems to be an ArcGIS Pro python console and notebook issue/feature... 

Calling arcpy.AddMessage(some_message) in a script or python console from an IDE or terminal will print to stdout.  But not from the ArcGIS Pro python consoles and notebooks.

AlfredBaldenweck

Huh. Not sure how I didn't notice that before, but yeah, AddError/Message/Warning do work just fine in like, PyCharm.

AlfredBaldenweck_0-1751934667783.png

import arcpy
print("One")
arcpy.AddError("Two")
arcpy.AddMessage("Three")
arcpy.AddWarning("Four")
print("Five")

Notebooks, however... 

AlfredBaldenweck_1-1751934922214.png