[Problem] Excessively verbose output from certain operations
Is there an existing issue for this?
- [X] I have searched the existing issues
Problem description
Some operations, for instance calls to make_text and make_dimension, natter away in the Report tab even when they are fully successful. This can swamp other more useful messages noting exceptional conditions, particularly during an import operation.
These methods need not produce any output on success as this success is self-evident with the created object appearing in the drawing.
Full version info
OS: Windows 10 build 19045
Word size of FreeCAD: 64-bit
Version: 0.22.0dev.35389 +97 (Git)
Build type: Debug
Branch: Issue11394
Hash: fcbd1105d64a945f242b8356fd72119f388b4747
Python 3.8.10, Qt 5.15.2, Coin 4.0.1, Vtk 8.2.0, OCC 7.6.3
Locale: English/Canada (en_CA)
Subproject(s) affected?
None
Anything else?
No response
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
Although the header text that is printed, e.g.
----------------
Linear dimension
only appears if debug is true, the remainder of the message (parameters, etc.) is still passed unconditionally to a _msg call.
In addition, even a production build, where I would expect debug to be false, the above header lines are nevertheless printed because it turns out that debug is not global but is a third parameter to print_header which defaults to True and the calls in places like make_linear_dimension do not supply any value for this parameter.
This should be solved with https://github.com/FreeCAD/FreeCAD/pull/11503
I'm not sure #11503 solves this. Well, actually, that PR doesn't solve it at all because all the make_xxx.py files in Draft are still calling _msg to display their messages, but the question here is whether calling _toolmsg instead (now that it exists) would be an appropriate solution.
I think the messages referenced in #11503 are very different in intent than the ones in this issue. The ones this issue is addressing are very much of the "I'm doing exactly what you asked me to" form, while the ones in #11503 are very much "This is the information I'm waiting for next" prompts.
As such then I might even argue that _toolmsg should be renamed to _toolprompt.
As an AutoCAD user I would very much appreciate having such prompts turned on. In fact, I've run across missing prompts which I'll eventually be posting Issues for. But I very much don't need or want a message telling me a line from ... to ... has been created when that's exactly what I asked for and I can plainly see the result on the screen.
I'm really just trying to figure out if such messages are useful for anyone at all (developers excepted) in which case they should be option-controlled (at the expense of option clutter) or if they are not useful in which case they should just be removed altogether. I'm new as a FreeCAD contributor so I'm trying to avoid stepping on toes here... I could even argue that if they are considered (at times) useful, then all the object-creation code, not just the Draft ones, should issue such messages.
The thing is, basically using the FreeCAD output window still makes it very far from an interactive command prompt. I think if we wanted a command prompt we need maybe some other kind of widget.
That said, you're right, there is more cleaning needed...
I suppose that depends on what sort of input is expected (keyboard vs mouse). In AutoCAD you often have the choice of either, i.e. pick a point with the mouse or enter coordinates. In FreeCAD keyboard coordinate entry takes place through the form that shows up in the Tasks pane which is indeed visually distant from the output window. Although these forms could perhaps be enhanced to give more descriptive prompting, one case where a scrolling text prompting area has an advantage is when you get multiple identical prompts ("Enter next point"), as long as you don't have so many such prompts in a row that they scroll off the area. With the entry form, there is no real visual feedback that you've entered a point because it just prompts "Enter next point" again. Making the prompt dynamic "Enter point number 1", "Enter point number 3", ...) would cure this. The form-input model as it stands is far from ideal for some commands like "Offset" since you must use the mouse to indicate which side to offset on, but the mouse movement prevents you from manually entering a distance with the keyboard. Well, you can type in a distance, but any accidental mouse motion replaces the distance you typed. Offsetting several objects by the same specific distance is tedious, at best. There are several other commands for which the "pick object(s)/start command/prompt to enter parameters" model is not ideal and improving these leads to more prompts (in particular, to pick an object). Although this issue is going off-topic a bit, it does enter the bigger picture of input models and methods.
In any case this all places the code that prints stuff like prompts in the "Draft_Line" gui command, not the make_line method in the Draft module. For that matter, apparently Draft_line doesn't even call make_line to make the line, evidenced by the fact that the messages from make_line do not show up.
Indeed... The Draft workbench is one of the first ones ever done in FreeCAD, and it still suffers from cursed inheritances from my enormous lack of experience in programming at that time :confused: ... Many people have since them worked on it to better things, but some of the mess from the beginnings is still there
In V0.18 there was a Verbose parameter (exposed in the preferences) that would make these messages optional.
How can you check if you have a Debug build?
It can certainly be done in C++ using #ifdef DEBUG; there is likely some way that FreeCAD could expose this in an existing Python class as a method named, for example, isDebugBuild().
It could be in the C++ Application class, exposed in Python as App, implemented in src/App/ApplicationPy.cpp which is part of the FreeCADApp build project. This would mean Python code could check App.isDebugBuild()
I think even for a debug build a developer would want to be able to turn it on or off, so perhaps (in this specific case, controlling messages produced by the Draft module) it could be a property in the Draft module, e.g. Draft.showDebugMessages (or maybe a shorter name would be preferred), which would default to False. Actually that would belong in the draftutils.messages module. Rather than having every bit of code check the flag before calling _msg, there should be a new method _debugMsg(text, end="\n") in draftutils.messages and the debug parameter for utils.print_header should default to this flag rather than True. This could therefore all be controlled by manually entering code on the Python console to change the flag. If the flag defaults to False, the only thing you miss out on is the ability to get the debug messages on program startup, before the Python console is active.
In Python one does not get the benefit of completely removing the cost of debug code for a non-debug build so with that last paragraph I don't really see any need for exposing whether it is a debug build of FreeCAD. Also the build information may already be available if the information in the "About" box is available to the Python code.
I think this can be used:
App.ConfigGet("Debug")
On my system it returns "0". I assume that in a Debug build the return value is "1".
So something like this can work:
def _debug_msg(text, end="\n", debug=App.ConfigGet("Debug")=="1"):
if debug:
# ...
One of the problems is that some commands currently do not have these verbose messages. Silencing them for the commands that have them still leaves us with an inconsistent result. And I wonder if we really need them. After all there is also information in the Python console.
Can't we just remove these messages completely?
Removing the messages entirely was really my original idea, but I wasn't sure if someone else really wanted them to stay.
I've confirmed that App.ConfigGet("Debug") returns '1' on a debug build, so no additional code changes are required should we want to check for a debug build. It is only slightly annoying that this returns a string rather than a boolean (True or False); I suppose if it really gets annoying a method returning a boolean could be added in the future.
AFAICT these verbose messages were introduced in V0.19. The developer who was then very active may have favored them.