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()"
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.
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)
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
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
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.
Huh. Not sure how I didn't notice that before, but yeah, AddError/Message/Warning do work just fine in like, PyCharm.
import arcpy
print("One")
arcpy.AddError("Two")
arcpy.AddMessage("Three")
arcpy.AddWarning("Four")
print("Five")
Notebooks, however...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.