Guidance for API schema instance names

Hello. For multi-apply API schemas, there don’t appear to be any restrictions in the instance name. For example–

from pxr import Usd
s = Usd.Stage.CreateInMemory()
p = s.DefinePrim("/root")
c = Usd.CollectionAPI.Apply(p, 'name with spaces')
c2 = Usd.CollectionAPI.Apply(p, 'name:with:colons')
print(s.GetRootLayer().ExportToString())

When you create the include or exclude relationship on c, you’ll get an error, as name with spaces isn’t a valid identifier for properties. However, name:with:colons works fine, as it will generate a valid property name.

Do people consider colons in the instance name to be bad practice? Do they complicate user interfaces and tooling that will treat them like namespaces? Do people consider whitespace in the instance name to be bad practice even when the instance name isn’t used to derive property names? Will OpenUSD ever apply restrictions to the instance name?

Thanks for the thoughts!

Although I can’t recall them at the moment, we have definitely discussed some future needs for namespaced multi-apply instance names. I think we should document and validate that instance names must be valid property names… even if there were cases where it made sense to have a multi-apply schema that did not provide any properties, it seems overly confusing to allow more permissive names for just those cases.

Thanks for catching this, @nvmkuruc - would you file an Issue?

Sure thing.

Do you anticipate namespaced instance names having any additional implied semantics?

Just spit-balling: the semantics schema could have namespaced or sub-semantics

  • Materials (wood, metal, cloth)
  • action-semantics (twist, push, pull, switch-on, switch-off, interact)
  • state semantics (open, closed)

I was hoping to be able to use : in CollectionAPI instance names, and although experimentally it mostly seems to work, it does seem possible to create a collision between two instances like so :

stage = Usd.Stage.CreateInMemory( "test" )
prim = stage.DefinePrim( "/Test" )
Usd.CollectionAPI.Apply( prim, "foo" )
Usd.CollectionAPI.Apply( prim, "foo:includes" )
Usd.CollectionAPI.GetAllCollections( prim )

Which yields the following warning :

Warning: in _PropertyTypesMatch at line 257 of /.../primDefinition.cpp -- Cannot compose schema specs: Schema relationship spec at path '/CollectionAPI.collection:__INSTANCE_NAME__:includes' in layer 'anon:0x7f4f19446080' is a different spec type than schema attribute spec at path '/CollectionAPI.collection:__INSTANCE_NAME__' in layer 'anon:0x7f4f19446080'.

I’m guessing this is because the two instances have different opinions on what the foo:includes property type is? The first wants a relationship for the includes and the second wants an opaque attribute to represent the instance itself?

If that’s so, does that mean that the idea of using : in collection names is dead in the water? Or perhaps it is still the aspiration, and this is just a corner case that can be fixed in future?

My interest at present is in round-tripping names from another app through USD and back into the app. So we can always just do a remapping of the name ourselves on export/import if needed. But if the intention is that : should work, then we may just live with the collision corner case for now in favour of simplicity.

Many thanks in advance for any guidance you’re able to provide…

Hi @JohnHaddon , you’re totally clear to use colons in instance names. The warning you’re seeing actually has nothing to do with the instance-name being namespaced, but rather that it contains a property name of the schema, i.e. you’d get the same warning if you applied an instance name of simply “includes”.

We had a reason for that warning, but on further reflection, have come to believe it is incomplete in what it is trying to protect against, and also overly aggressive. If you’d like, would you file an Issue with your example asking to remove the restriction?

Thanks!

Thanks for the reply @spiff! That’s the answer I was hoping for, so we’ll go ahead and use colons in our collection names.

For what it’s worth, that doesn’t seem to be what I’m seeing here. I can make a collection called includes without getting a warning, and I don’t get the warning from foo:includes unless I’ve also made foo. This is with 23.11 though, so perhaps things have changed (we’re in the process of updating to 24.08 so I’ll be able to re-test soonish).

I’ve opened an issue here : Warning when creating `foo` and `foo:includes` collections · Issue #3251 · PixarAnimationStudios/OpenUSD · GitHub. I don’t understand enough to describe it in generic terms, particularly since I may not be seeing what you expect, so I’ve just described the little I know. Hope that’s OK as a starting point.

Many thanks once again for your help…

Perfect - thanks, @JohnHaddon !