Hello,
I’ve spent the last two hours becoming more frustrated with this…
I read a string in from a INI file and it looks like this: 'C:\Temp\Junk\08 Folder\Whatever.3dm'
The \0 is causing so much trouble because I can’t figure out how to get Python to not treat it special - and secondly, convince Rhino to open the file. Mostly the second part. The script also has to deal with folders that start with 01 through 99 so I can’t just hack something together for this special case.
The code below is the closest that I have got - the os module knows it exists but the “open command” completely freaks out.
Can someone offer a suggestion on the proper way to deal with this?
import rhinoscriptsyntax as rs
import os
# This string comes from a INI file - I can't just put an "r" in front of it
A = 'C:\Temp\Junk\08 Folder\Whatever.3dm'
print(A)
A = A.replace('\0', '/0')
A = A.replace('\\', '/')
print(A)
# Python thinks this is OK
print(os.path.exists(A))
result = rs.Command(f'_-Open {A} _Enter')
print(result)
The Rhino result for this looks like:
Command: _-Open
Name of the file to open ( UpdatePromptUpdateBlocks=Yes Browse ): C:/Temp/Junk/08
File C:/Temp/Junk/08.3dm not found, unable to open
Methinks the problem is with the space between 08 and Folder, not escaping the characters. You need to enclose the file path in another set of quotes, otherwise the space is interpreted as an Enter and the path stops there.
Thank you!
Yes, the double quotes were needed. Also, even though the os module can handle forward or backward slashes, Rhino only accepts backslashes. So that needs to be dealt with too.
I’m not sure if my solution will work for all cases, but if anyone stumbles on this post please give this code a try:
import rhinoscriptsyntax as rs
import os
A = 'C:\Temp\Junk\08 Folder\Whatever.3dm'
print(A)
A = A.replace('\0', '/0')
A = A.replace('/', '\\')
print(A)
print(os.path.exists(A))
result = rs.Command(f'_-Open "{A}" _Enter')
print(result)
From python 3.6 undeterminable escape characters have been flagged as deprecation warnings. From 3.12 they are flagged as syntax warnings and from some later version they will be flagged as syntax errors.
In this case you want the string to be treated as raw text (ie backslashes are just backslashes, not escapes) so simply flag it as such with an r prefix:
#! python3
import rhinoscriptsyntax as rs
import Rhino
import os
A = r'C:\Users\Moi\Desktop\My File.3dm'
print(A)
print(os.path.exists(A))
result = rs.Command('_-Open "{}" _Enter'.format(A))
print(result)
and the file will open.
Regards
Jeremy
ps. One thing you can’t do with a raw string is to end it with a single backslash (as you could find in a path to a folder).
Yes, I understand about the raw strings. However as the OP @Henry_Wede indicated, he is reading a string representing a file path from a file - something that is also not unusual. And from some searching I was not able to find a way to convert a ‘normal’ string read in from a file to a raw string inside a script. Looks like @dale has put up a solution to that, albeit complicated.
The raw modifier only applies to string literals, not strings (sorry, my previous wording was sloppy). If you want to read a path string from a file, all you should need to do is this:
where TestPath.ini contains the string shown in the terminal output.
Does this not work for you?
Regards
Jeremy
p.s. If one wants to read parameters from an ini file of anything more than trivial complexity, one is better of using the functionality of the configparser module, or something similar.
In the illustration you provide, A doesn’t come from a file, it’s a string literal where you do need to use the r prefix. Can you show us what result you get if you try reading from a file, in the manner of my last reply to Mitch? No replaces or other tweaks.
The result is very similar. The Rhino command “skips over” parts of the path as it tries to deal with the escaped characters and does not load the file. The \0 seems to be the issue.
I can’t really provide a full example - or maybe I’m too lazy. The path does come from an INI file. Rhino doesn’t like to play with the configparser module and the rs module only provides reading and not writing. So… I just wrote my own config parser to fill the gaps. I have had zero problems with my homemade config parser so I am not willing to throw that under the bus right now.
Maybe Dale’s solution could just be rolled into the Rhino code that deals with paths? It seems pretty complicated for users to have to come up with - unless they stumble on this thread.
Or… there could be a rs.OpenFile() and rs.SaveFile() which seems like a nicer world to live in.
As you can see, I have a \0 in my example path and that works fine. It works for ASCII (code page 1252) and Unicode files. What release of Rhino are you on (I’m on 8.12.24254.14001) and what version of Windows (I’m on 11, 23H2)?