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...
Since I do 98% of my coding in PyCharm, I was also mildly baffled that the Python Window & Notebooks didn't honor the arcpy prints. Now I'm really curious about what's different with the back end of the latter two.
Since it "just works" in an IDE, this leads me to suppose that ESRI might've reinvented the wheel on their built-in coding systems in suboptimal ways. I'd love to see this specific problem addressed, but it also makes me wonder what other similarly weird quirks might still be waiting.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.