Internal error when saving printer.print_stats.filename to disk

Hi all.

A bug or a mistake?

When I do these:

SAVE_VARIABLE VARIABLE=bed_t VALUE={printer.heater_bed.target}

SAVE_VARIABLE VARIABLE=noz_t VALUE={printer.extruder.target}

they work perfectly and save to disk. Moreover An M118 {printer.print_stats.filename} also gives the correct filename which is “deneme.gcode”. Nothing fancy about the file name, no whitespace, etc. But when I do

SAVE_VARIABLE VARIABLE=fname VALUE={printer.print_stats.filename}

this gives an internal error requiring a firmware restart.

Relevant klippy error log is here:

Internal error on command:“SAVE_VARIABLE”
Internal error on command:“POFF”
Traceback (most recent call last):
File “/home/pi/klipper/klippy/gcode.py”, line 198, in _process_commands
handler(gcmd)
File “/home/pi/klipper/klippy/gcode.py”, line 135, in
func = lambda params: origfunc(self._get_extended_params(params))
File “/home/pi/klipper/klippy/extras/gcode_macro.py”, line 186, in cmd
self.template.run_gcode_from_command(kwparams)
File “/home/pi/klipper/klippy/extras/gcode_macro.py”, line 68, in run_gcode_from_command
self.gcode.run_script_from_command(self.render(context))
File “/home/pi/klipper/klippy/gcode.py”, line 213, in run_script_from_command
self._process_commands(script.split(’\n’), need_ack=False)
File “/home/pi/klipper/klippy/gcode.py”, line 198, in _process_commands
handler(gcmd)
File “/home/pi/klipper/klippy/gcode.py”, line 135, in
func = lambda params: origfunc(self._get_extended_params(params))
File “/home/pi/klipper/klippy/extras/save_variables.py”, line 39, in cmd_SAVE_VARIABLE
value = ast.literal_eval(value)
File “/usr/lib/python2.7/ast.py”, line 49, in literal_eval
node_or_string = parse(node_or_string, mode=‘eval’)
File “/usr/lib/python2.7/ast.py”, line 37, in parse
return compile(source, filename, mode, PyCF_ONLY_AST)
File “<unknown>”, line 0

^

SyntaxError: unexpected EOF while parsing
Internal error on command:“POFF”

Can you share the klippy.log? We may see what is programmed around.

Hi.
Sorry for the delay. I did a fresh restart of pi, klipper, etc, removed the variables.cfg file and the error reduced to:
!! Unable to parse 'deneme.gcode' as a literal

Now again
M118 {printer.print_stats.filename}
and even
M118 {printer.virtual_sdcard.file_path} returned correctly.

I don’t know what caused the error in my first post’s log. Maybe interfered with variables.cfg file, which I removed this time before starting to take the log. I may attach the older ones, if required. But this ought to suffice.

Attached is the klippy.log
klippy.log (61.4 KB)

You are using a modified Klipper version. Please check if the same behavior is shown with a pristine current git.

Could be some missing quotes or forcing the variable to be a string.

I mean, I used default KIAUH install, not any sort of fancy mod on klipper’s own directory. I don’t know if KIAUH makes any mods whatsoever. The only changes I made apart from firmware compilation (make menuconfig) are usual config files (printer.cfg and its included macros) to make it work, nothing more.

Anyways, I did a pristine klipper install as you suggested by cloning the default github git and compiled f/w and klippy with all the python environments, etc on another directory (basically via a debian-install.sh) and tried once more, again with the same dismay result. Attached is the log:

klippy.log (60.8 KB)

PS: On my old klipper when I comment out these lines of save_variables.py:

try: value = ast.literal_eval(value) except ValueError as e: raise gcmd.error("Unable to parse '%s' as a literal" % (value,))

This made it successfully save on variables.cfg. But of course all the values were single quoted ie:

abs_c = 'True' instead of abs_c = True and pos_x = '20.0' instead of pos_x = 20.0. I have no idea about intended behaviour here. But then I could at least see fname = 'deneme.gcode' on variables.cfg. So could be a problem around ast.literal_eval()? I just do not have enough python skills to troubleshoot…

Also this is not a default klipper install.
Quite easily identified by commands that klipper does not support, e.g. [gcode_shell_command backlash] and Klipper’s startup information:
v0.10.0-391-g722ad4a1-dirty-20220503_184048-fluiddpi
If it mentions “dirty” then it is from modified sources.

Also it would make sense to reduce the cfg to a bare minimum that shows the error.

Ah, I thought Arksine’s own gcode_shell_command.py does not matter that much, an irrelevant piece of code. Anyways, after a long struggle (and lots of hair pulls) I did fulfill your requirements. It is quite interesting that even changing install-debian.sh contents “taints” it. And one has to compile f/w from start since it has a contamination of “dirty” tag.

…and still the same error. Log is your friend:
klippy.log (4.7 KB)

@Arksine surely knows what he is doing and delivers great, high quality contributions.
In terms of error assessment it is just impossible to see from the outside, which modifications might have been done.
Thus you will most likely not find any dev looking into such a topic if there is the dirty flag, since it might turn out being a complete waste of time.

Edit:

You could try something like

{% set temp = printer.print_stats.filename | string %}
SAVE_VARIABLE VARIABLE=fname VALUE="{temp}"

I see. Then I appreciate you guys’ scrutiny around Klipper. The code (and configs) are extremely picky and alarmist indeed which by this way easening the life of developers.

I tried both single and double quotes with a lack of luck again:
klippy.log (9.7 KB)

PS: A naive hypothesis of code may confuse “deneme.gcode” construct with a “0.0” style floating number made me to test just “deneme” without file extension and still the same error.

The likely issue here is that printer.print_stats.filename will be an empty string if no file is loaded. The ast.literal_eval method cannot evaluate an empty string.

You could try something like this:

{% if printer.print_stats.filename %}
SAVE_VARIABLE VARIABLE=fname VALUE={printer.print_stats.filename}
{% endif %}

Also keep in mind that if the file name contains spaces or quotation marks it might cause an issue. It isn’t a bad idea to escape them before saving, then unescape when restoring…however it isn’t necessary as long as you know the limitations and are careful about how you name your gcode files.

Edit: After looking at the log I see you are having a problem evaluating the string. Try the following:

SAVE_VARIABLE VARIABLE=fname VALUE="\"{temp}\""
2 Likes

Omg Arksine you rule dude! Yeah escaping with a backslash made it and after doing a:
SAVE_VARIABLE VARIABLE=fname VALUE="\"{printer.print_stats.filename}\""
Now I can see finally
fname = 'deneme.gcode' in variables.cfg file.

I know there are exotic filenames out there but mine was a dead simple latin named file created by just a linux touch deneme.gcode command, selected with an M23 deneme.gcode, which is then verified with a cat /tmp/printer. As I already stated in my earlier posts, for an M118 {printer.print_stats.filename} it just echoes correctly without any need for escaping.

Against empty fname strings programatically there should be a check beforehand, but still then this is a simple string saver to disk, how hard it should be to save ‘as is’ just like any other variable IMHO.

Anyways. Since I found at least one solution to make it work, I deem this as solved.
Thanks a lot again dudes. You saved my day.