SdfLayer.PermissionToSave questions

I’m seeing some behaviour when querying a layer’s permissionToSave that seems to be a bug but perhaps I’m misunderstanding it’s intended use?

We’re using an Asset resolver so maybe that has something to do with it, but I’d appreciate if someone could confirm or deny this test and whether permissionToSave should be returning False in this case?

Open a stage that you know has read-only layers and is using Ar URI’s…

import os
from pxr import Usd

stage = Usd.Stage.Open('your:/uri')
for layer in stage.GetUsedLayers():
    if layer.permissionToSave:
        if not os.access(layer.realPath, os.W_OK):
            print(f"File is not writable: {layer.identifier}")

I did notice that permissionToSave does return False in the case of runtime anonymous layers, but should it also return False in the case of read-only layers?

Just looking at the logic for permissionToSave, does your asset resolver define CanWriteAssetToPath?

bool
SdfLayer::PermissionToSave() const
{
    return _permissionToSave &&
        !IsAnonymous() &&
        Sdf_CanWriteLayerToPath(GetResolvedPath());
}
  1. _permissionToSave in your example would default to true
  2. !IsAnonymous() would also return true since your layer isn’t anonymous`
  3. That would fall to Sdf_CanWriteLayerToPath which has the following definition
bool
Sdf_CanWriteLayerToPath(
    const ArResolvedPath& resolvedPath)
{
    return ArGetResolver().CanWriteAssetToPath(
        resolvedPath, /* whyNot = */ nullptr);
}

I can perhaps see the ArGetResolver() falling through to a different resolver than the one you provided to Stage Open if its not the highest priority resolver in the current context.

Ahh perfect, I’ll take a look at our resolver code tomorrow and confirm.

Much appreciated!

ArResolver does go through the URI-dispatch process for CanWriteAssetToPath(), so it should be all good!

(and/or, since you are passing a resolved path to the method, the currently-bound ArResolverContext should not be relevant)