`Path.Parent()` leading to bad state

Consider this code:

var fsUtil = DOpus.FSUtil();

var path = fsUtil.NewPath("/desktop");  // `Parent()` -> `true`, ""
//var path = fsUtil.NewPath("/thispc");   // `Parent()` -> `true`, "" 
//var path = fsUtil.NewPath("coll://");  // `Parent()` -> `false`, "coll://"
//var path = fsUtil.NewPath("C:\\");  // `Parent()` -> `false`, "C:\\"

DOpus.Output(String(path.Parent()));
DOpus.Output(JSON.stringify(String(path)));

var cmd = DOpus.Create().Command();
cmd.RunCommand('Go PATH="' + path + '"');

I'd expected the Path to return false and stay unchanged after calling Parent() on /desktop. In /thispc, it could yield /desktop; in C:\, /thispc. It should be like when pressing Backspace in a folder.

Even if you don't agree with all of this, I think at least some of those results are wrong.

You could also add a flag letter argument to Parent() that controls whether the chain should stop at the drive root (may still work above drive roots), or whether a drive root can be overcome to yield /thispc, and then also definitely being able to go up the chain above drive roots.

Regarding /desktop, this problem is associated with this bug: PathType() for "/desktop" returns "filesys" instead of "shell". Parent() on /desktop seems to erroneously treat /desktop as a file system path. And the file system path has a parent. That could explain the return value of true.

Regarding my proposal of adding a flag letter argument to Parent(), it's also relevant that, as I said in the other post, ComparePath() says that /thispc is a parent of C:\.

We'll make Path.Parent fail if the result in an empty string.

Note that it just removes the last component of the path. It gives you the parent of the string, not the parent according to the Windows Shell hierarchy.

(I don't think you would really want Parent to behave like backspace. The Shell hierarchy contains infinite cycles and other oddities which would make writing scripts more complex, not less. The Shell hierarchy also changes in OS updates according to Microsoft's whims, to make things worse.)

If you're using aliases and want to get the parent of what the alias points to, you need to call Path.Resolve before Path.Parent.

PathType("/desktop") returns "filesys" because it resolves aliases for you, and Desktop is a virtual folder with a filesystem folder behind it. A common reason for checking PathType is to see if the path is something that normal file operations can work on, which is true for Desktop.

(OTOH, we don't want to make Path.Parent resolve aliases for you as it would mean you lose the alias when removing a subdir from the end of it, and it can have unexpected results like This PC parenting to C:\Users\<username>\Desktop, which is unwanted and creates an infinite loop if you try to loop through the parent folders.)

But does pressing Backspace ever lead to infinite cycles? You could call the function like path.Parent("s"). I was up to behavior like going up in the folder tree. For backwards compatibility alone, you couldn't make this the new default behavior, of course.

If I understand correctly, couldn't infinite cycles only happen when going deeper into the tree and not when going up?

See also https://resource.dopus.com/t/fsutil-resolve-invalidates-shell-paths/54951.