1#!/pxrpythonsubst 2# 3# Copyright 2020 Pixar 4# 5# Licensed under the Apache License, Version 2.0 (the "Apache License") 6# with the following modification; you may not use this file except in 7# compliance with the Apache License and the following modification to it: 8# Section 6. Trademarks. is deleted and replaced with: 9# 10# 6. Trademarks. This License does not grant permission to use the trade 11# names, trademarks, service marks, or product names of the Licensor 12# and its affiliates, except as required to comply with Section 4(c) of 13# the License and to reproduce the content of the NOTICE file. 14# 15# You may obtain a copy of the Apache License at 16# 17# http://www.apache.org/licenses/LICENSE-2.0 18# 19# Unless required by applicable law or agreed to in writing, software 20# distributed under the Apache License with the above modification is 21# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 22# KIND, either express or implied. See the Apache License for the specific 23# language governing permissions and limitations under the Apache License. 24 25import os, unittest 26from pxr import Plug, Sdf, Usd, Vt, Tf 27 28class TestUsdAppliedAPISchemas(unittest.TestCase): 29 @classmethod 30 def setUpClass(cls): 31 pr = Plug.Registry() 32 testPlugins = pr.RegisterPlugins(os.path.abspath("resources")) 33 assert len(testPlugins) == 1, \ 34 "Failed to load expected test plugin" 35 assert testPlugins[0].name == "testUsdAppliedAPISchemas", \ 36 "Failed to load expected test plugin" 37 cls.SingleApplyAPIType = \ 38 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestSingleApplyAPI") 39 cls.MultiApplyAPIType = \ 40 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestMultiApplyAPI") 41 cls.SingleCanApplyAPIType = \ 42 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestSingleCanApplyAPI") 43 cls.MultiCanApplyAPIType = \ 44 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestMultiCanApplyAPI") 45 cls.NestedInnerSingleApplyAPIType = \ 46 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestNestedInnerSingleApplyAPI") 47 cls.NestedOuterSingleApplyAPIType = \ 48 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestNestedOuterSingleApplyAPI") 49 cls.NestedCycle1APIType = \ 50 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestNestedCycle1API") 51 cls.NestedCycle2APIType = \ 52 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestNestedCycle2API") 53 cls.NestedCycle3APIType = \ 54 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestNestedCycle3API") 55 cls.AutoAppliedToAPIType = \ 56 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestAutoAppliedToAPI") 57 cls.NestedAutoAppliedToAPIType = \ 58 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestNestedAutoAppliedToAPI") 59 cls.NestedAutoAppliedToAPIAppliedToPrimType = \ 60 Tf.Type(Usd.SchemaBase).FindDerivedByName("TestNestedAutoAppliedToAPIAppliedToPrim") 61 62 def test_SimpleTypedSchemaPrimDefinition(self): 63 """ 64 Tests the prim definition for a simple typed schema that has no 65 built-in API schemas 66 """ 67 primDef = Usd.SchemaRegistry().FindConcretePrimDefinition( 68 "TestTypedSchema") 69 self.assertTrue(primDef) 70 self.assertEqual(primDef.GetPropertyNames(), ["testAttr", "testRel"]) 71 self.assertEqual(primDef.GetAppliedAPISchemas(), []) 72 self.assertEqual(primDef.GetDocumentation(), "Testing typed schema") 73 74 # Verify property specs for named properties. 75 for propName in primDef.GetPropertyNames(): 76 self.assertTrue(primDef.GetSchemaPropertySpec(propName)) 77 78 # Verify the attribute spec and its fallback value and type 79 testAttr = primDef.GetSchemaAttributeSpec("testAttr") 80 self.assertEqual(testAttr.default, "foo") 81 self.assertEqual(testAttr.typeName.cppTypeName, "std::string") 82 83 # Verify the relationship spec 84 self.assertTrue(primDef.GetSchemaRelationshipSpec("testRel")) 85 86 def test_TypedSchemaWithBuiltinAPISchemas(self): 87 """ 88 Tests the prim definition for schema prim type that has API schemas 89 applied to it in its generated schema. 90 """ 91 92 # Find the prim definition for the test single apply schema. It has 93 # some properties defined. 94 singleApplyAPIDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition( 95 "TestSingleApplyAPI") 96 self.assertTrue(singleApplyAPIDef) 97 self.assertEqual(singleApplyAPIDef.GetAppliedAPISchemas(), 98 ["TestSingleApplyAPI"]) 99 self.assertEqual(singleApplyAPIDef.GetPropertyNames(), [ 100 "single:bool_attr", "single:token_attr", "single:relationship"]) 101 self.assertEqual(singleApplyAPIDef.GetDocumentation(), 102 "Test single apply API schema") 103 104 # Find the prim definition for the test multi apply schema. It has 105 # some properties defined. Note that the properties in the multi apply 106 # definition are not prefixed yet. 107 multiApplyAPIDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition( 108 "TestMultiApplyAPI") 109 self.assertTrue(multiApplyAPIDef) 110 self.assertEqual(multiApplyAPIDef.GetAppliedAPISchemas(), []) 111 self.assertEqual(multiApplyAPIDef.GetPropertyNames(), [ 112 "bool_attr", "token_attr", "relationship"]) 113 self.assertEqual(multiApplyAPIDef.GetDocumentation(), 114 "Test multi-apply API schema") 115 116 # Find the prim definition for the concrete prim type with built-in 117 # API schemas. You can query its API schemas and it will have properties 118 # from those schemas already. 119 primDef = Usd.SchemaRegistry().FindConcretePrimDefinition( 120 "TestWithBuiltinAppliedSchema") 121 self.assertTrue(primDef) 122 self.assertEqual(primDef.GetAppliedAPISchemas(), [ 123 "TestSingleApplyAPI", "TestMultiApplyAPI:builtin"]) 124 self.assertEqual(sorted(primDef.GetPropertyNames()), [ 125 "multi:builtin:bool_attr", 126 "multi:builtin:relationship", 127 "multi:builtin:token_attr", 128 "single:bool_attr", 129 "single:relationship", 130 "single:token_attr", 131 "testAttr", 132 "testRel"]) 133 # Note that prim def documentation does not come from the built-in API 134 # schemas. 135 self.assertEqual(primDef.GetDocumentation(), 136 "Test with built-in API schemas") 137 138 # Verify property specs for all named properties. 139 for propName in primDef.GetPropertyNames(): 140 self.assertTrue(primDef.GetSchemaPropertySpec(propName)) 141 142 # Verify fallback value and type for properties defined in the 143 # concrete prim 144 testAttr = primDef.GetSchemaAttributeSpec("testAttr") 145 self.assertEqual(testAttr.default, "foo") 146 self.assertEqual(testAttr.typeName.cppTypeName, "std::string") 147 148 self.assertTrue(primDef.GetSchemaRelationshipSpec("testRel")) 149 150 # Verify fallback value and type for properties from the single applied 151 # schema. These properties will return the same property spec as the 152 # API schema prim definition. 153 singleBoolAttr = primDef.GetSchemaAttributeSpec("single:bool_attr") 154 self.assertEqual(singleBoolAttr, 155 singleApplyAPIDef.GetSchemaAttributeSpec("single:bool_attr")) 156 self.assertEqual(singleBoolAttr.default, True) 157 self.assertEqual(singleBoolAttr.typeName.cppTypeName, "bool") 158 159 singleTokenAttr = primDef.GetSchemaAttributeSpec("single:token_attr") 160 self.assertEqual(singleTokenAttr, 161 singleApplyAPIDef.GetSchemaAttributeSpec("single:token_attr")) 162 self.assertEqual(singleTokenAttr.default, "bar") 163 self.assertEqual(singleTokenAttr.typeName.cppTypeName, "TfToken") 164 165 singleRelationship = primDef.GetSchemaRelationshipSpec( 166 "single:relationship") 167 self.assertTrue(singleRelationship) 168 self.assertEqual(singleRelationship, 169 singleApplyAPIDef.GetSchemaRelationshipSpec("single:relationship")) 170 171 # Verify fallback value and type for properties from the multi applied 172 # schema. These properties will return the same property spec as the 173 # API schema prim definition even the properties on the concrete prim 174 # definion are namespace prefixed. 175 multiTokenAttr = primDef.GetSchemaAttributeSpec( 176 "multi:builtin:token_attr") 177 self.assertEqual(multiTokenAttr, 178 multiApplyAPIDef.GetSchemaAttributeSpec("token_attr")) 179 self.assertEqual(multiTokenAttr.default, "foo") 180 self.assertEqual(multiTokenAttr.typeName.cppTypeName, "TfToken") 181 182 multiRelationship = primDef.GetSchemaRelationshipSpec( 183 "multi:builtin:relationship") 184 self.assertTrue(multiRelationship) 185 self.assertEqual(multiRelationship, 186 multiApplyAPIDef.GetSchemaRelationshipSpec("relationship")) 187 188 # Verify the case where the concrete type overrides a property from 189 # one of its applied API schemas. In this case the property spec from 190 # the concrete prim is returned instead of the property spec from the 191 # API schema. 192 multiBoolAttr = primDef.GetSchemaAttributeSpec( 193 "multi:builtin:bool_attr") 194 apiBoolAttr = multiApplyAPIDef.GetSchemaAttributeSpec("bool_attr") 195 self.assertNotEqual(multiBoolAttr, apiBoolAttr) 196 self.assertEqual(multiBoolAttr.default, False) 197 self.assertEqual(apiBoolAttr.default, True) 198 self.assertEqual(multiBoolAttr.typeName.cppTypeName, "bool") 199 self.assertEqual(apiBoolAttr.typeName.cppTypeName, "bool") 200 201 def test_UntypedPrimOnStage(self): 202 """ 203 Tests the fallback properties of untyped prims on a stage when API 204 schemas are applied 205 """ 206 stage = Usd.Stage.CreateInMemory() 207 208 # Add a prim with no type. It has no applied schemas or properties. 209 untypedPrim = stage.DefinePrim("/Untyped") 210 self.assertEqual(untypedPrim.GetTypeName(), '') 211 self.assertEqual(untypedPrim.GetAppliedSchemas(), []) 212 self.assertEqual(untypedPrim.GetPrimTypeInfo().GetTypeName(), '') 213 self.assertEqual(untypedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 214 []) 215 self.assertEqual(untypedPrim.GetPropertyNames(), []) 216 217 # Add an api schema to the prim's metadata. 218 untypedPrim.ApplyAPI(self.SingleApplyAPIType) 219 220 # Prim still has no type but does have applied schemas 221 self.assertEqual(untypedPrim.GetTypeName(), '') 222 self.assertEqual(untypedPrim.GetAppliedSchemas(), ["TestSingleApplyAPI"]) 223 self.assertEqual(untypedPrim.GetPrimTypeInfo().GetTypeName(), '') 224 self.assertEqual(untypedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 225 ["TestSingleApplyAPI"]) 226 self.assertTrue(untypedPrim.HasAPI(self.SingleApplyAPIType)) 227 228 # The prim has properties from the applied schema and value resolution 229 # returns the applied schema's property fallback value. 230 self.assertEqual(untypedPrim.GetPropertyNames(), [ 231 "single:bool_attr", "single:relationship", "single:token_attr"]) 232 self.assertEqual(untypedPrim.GetAttribute("single:token_attr").Get(), 233 "bar") 234 235 # Applied schemas are unable to define fallback metadata values for 236 # prims. Just verifying that no fallback exists for "hidden" here as 237 # a contrast to the other cases below where this metadata fallback will 238 # be defined. 239 self.assertFalse("hidden" in untypedPrim.GetAllMetadata()) 240 self.assertIsNone(untypedPrim.GetMetadata("hidden")) 241 self.assertFalse(untypedPrim.HasAuthoredMetadata("hidden")) 242 243 # Untyped prim still has no documentation even with API schemas applied. 244 self.assertIsNone(untypedPrim.GetMetadata("documentation")) 245 246 def test_TypedPrimOnStage(self): 247 """ 248 Tests the fallback properties of typed prims on a stage when API 249 schemas are applied when the prim type does not start with API schemas. 250 """ 251 stage = Usd.Stage.CreateInMemory() 252 253 # Add a typed prim. It has no API schemas but has properties from its 254 # type schema. 255 typedPrim = stage.DefinePrim("/TypedPrim", "TestTypedSchema") 256 self.assertEqual(typedPrim.GetTypeName(), 'TestTypedSchema') 257 self.assertEqual(typedPrim.GetAppliedSchemas(), []) 258 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 259 'TestTypedSchema') 260 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 261 262 self.assertEqual(typedPrim.GetPropertyNames(), ["testAttr", "testRel"]) 263 264 # Add an api schemas to the prim's metadata. 265 typedPrim.ApplyAPI(self.SingleApplyAPIType) 266 typedPrim.ApplyAPI(self.MultiApplyAPIType, "garply") 267 268 # Prim has the same type and now has API schemas. The properties have 269 # been expanded to include properties from the API schemas 270 self.assertEqual(typedPrim.GetTypeName(), 'TestTypedSchema') 271 self.assertEqual(typedPrim.GetAppliedSchemas(), 272 ["TestSingleApplyAPI", "TestMultiApplyAPI:garply"]) 273 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 274 'TestTypedSchema') 275 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 276 ["TestSingleApplyAPI", "TestMultiApplyAPI:garply"]) 277 278 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 279 self.assertTrue(typedPrim.HasAPI(self.MultiApplyAPIType)) 280 self.assertEqual(typedPrim.GetPropertyNames(), [ 281 "multi:garply:bool_attr", 282 "multi:garply:relationship", 283 "multi:garply:token_attr", 284 "single:bool_attr", 285 "single:relationship", 286 "single:token_attr", 287 "testAttr", 288 "testRel"]) 289 290 # Property fallback comes from TestSingleApplyAPI 291 attr = typedPrim.GetAttribute("single:token_attr") 292 self.assertEqual(attr.Get(), "bar") 293 self.assertEqual(attr.GetResolveInfo().GetSource(), 294 Usd.ResolveInfoSourceFallback) 295 # Property fallback comes from TestMultiApplyAPI 296 attr = typedPrim.GetAttribute("multi:garply:bool_attr") 297 self.assertEqual(attr.Get(), True) 298 self.assertEqual(attr.GetResolveInfo().GetSource(), 299 Usd.ResolveInfoSourceFallback) 300 # Property fallback comes from TestTypedSchema 301 attr = typedPrim.GetAttribute("testAttr") 302 self.assertEqual(attr.Get(), "foo") 303 self.assertEqual(attr.GetResolveInfo().GetSource(), 304 Usd.ResolveInfoSourceFallback) 305 306 # Metadata "hidden" has a fallback value defined in TestTypedSchema. It 307 # will be returned by GetMetadata and GetAllMetadata but will return 308 # false for queries about whether it's authored 309 self.assertEqual(typedPrim.GetAllMetadata()["hidden"], True) 310 self.assertEqual(typedPrim.GetMetadata("hidden"), True) 311 self.assertFalse(typedPrim.HasAuthoredMetadata("hidden")) 312 self.assertFalse("hidden" in typedPrim.GetAllAuthoredMetadata()) 313 314 # Documentation metadata comes from prim type definition even with API 315 # schemas applied. 316 self.assertEqual(typedPrim.GetMetadata("documentation"), 317 "Testing typed schema") 318 319 def test_TypedPrimsOnStageWithBuiltinAPISchemas(self): 320 """ 321 Tests the fallback properties of typed prims on a stage when new API 322 schemas are applied to a prim whose type already has built-in applied 323 API schemas. 324 """ 325 stage = Usd.Stage.CreateInMemory() 326 327 # Add a typed prim. It has API schemas already from its prim definition 328 # and has properties from both its type and its APIs. 329 typedPrim = stage.DefinePrim("/TypedPrim", "TestWithBuiltinAppliedSchema") 330 self.assertEqual(typedPrim.GetTypeName(), 'TestWithBuiltinAppliedSchema') 331 self.assertEqual(typedPrim.GetAppliedSchemas(), 332 ["TestSingleApplyAPI", "TestMultiApplyAPI:builtin"]) 333 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 334 'TestWithBuiltinAppliedSchema') 335 # Note that prim type info does NOT contain the built-in applied API 336 # schemas from the concrete type's prim definition as these are not part 337 # of the type identity. 338 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 339 340 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 341 self.assertTrue(typedPrim.HasAPI(self.MultiApplyAPIType)) 342 self.assertEqual(typedPrim.GetPropertyNames(), [ 343 "multi:builtin:bool_attr", 344 "multi:builtin:relationship", 345 "multi:builtin:token_attr", 346 "single:bool_attr", 347 "single:relationship", 348 "single:token_attr", 349 "testAttr", 350 "testRel"]) 351 352 # Add a new api schemas to the prim's metadata. 353 typedPrim.ApplyAPI(self.MultiApplyAPIType, "garply") 354 355 # Prim has the same type and now has both its original API schemas and 356 # the new one. Note that the new schema was added using an explicit 357 # list op but was still prepended to the original list. Built-in API 358 # schemas cannot be deleted and any authored API schemas will always be 359 # prepended to the built-ins. 360 self.assertEqual(typedPrim.GetTypeName(), 'TestWithBuiltinAppliedSchema') 361 self.assertEqual(typedPrim.GetAppliedSchemas(), 362 ["TestMultiApplyAPI:garply", 363 "TestSingleApplyAPI", "TestMultiApplyAPI:builtin"]) 364 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 365 'TestWithBuiltinAppliedSchema') 366 # Note that prim type info does NOT contain the built-in applied API 367 # schemas from the concrete type's prim definition as these are not part 368 # of the type identity. 369 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 370 ["TestMultiApplyAPI:garply"]) 371 372 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 373 self.assertTrue(typedPrim.HasAPI(self.MultiApplyAPIType)) 374 375 # Properties have been expanded to include the new API schema 376 self.assertEqual(typedPrim.GetPropertyNames(), [ 377 "multi:builtin:bool_attr", 378 "multi:builtin:relationship", 379 "multi:builtin:token_attr", 380 "multi:garply:bool_attr", 381 "multi:garply:relationship", 382 "multi:garply:token_attr", 383 "single:bool_attr", 384 "single:relationship", 385 "single:token_attr", 386 "testAttr", 387 "testRel"]) 388 389 # Property fallback comes from TestSingleApplyAPI 390 attr = typedPrim.GetAttribute("single:token_attr") 391 self.assertEqual(attr.Get(), "bar") 392 self.assertEqual(attr.GetResolveInfo().GetSource(), 393 Usd.ResolveInfoSourceFallback) 394 # Property fallback comes from TestMultiApplyAPI 395 attr = typedPrim.GetAttribute("multi:garply:bool_attr") 396 self.assertEqual(attr.Get(), True) 397 self.assertEqual(attr.GetResolveInfo().GetSource(), 398 Usd.ResolveInfoSourceFallback) 399 # Property fallback actually comes from TestWithBuiltinAppliedSchema as 400 # the typed schema overrides this property from its built-in API schema. 401 attr = typedPrim.GetAttribute("multi:builtin:bool_attr") 402 self.assertEqual(attr.Get(), False) 403 self.assertEqual(attr.GetResolveInfo().GetSource(), 404 Usd.ResolveInfoSourceFallback) 405 # Property fallback comes from TestWithBuiltinAppliedSchema 406 attr = typedPrim.GetAttribute("testAttr") 407 self.assertEqual(attr.Get(), "foo") 408 self.assertEqual(attr.GetResolveInfo().GetSource(), 409 Usd.ResolveInfoSourceFallback) 410 411 # Metadata "hidden" has a fallback value defined in 412 # TestWithBuiltinAppliedSchema. It will be returned by GetMetadata and 413 # GetAllMetadata but will return false for queries about whether it's 414 # authored 415 self.assertEqual(typedPrim.GetAllMetadata()["hidden"], False) 416 self.assertEqual(typedPrim.GetMetadata("hidden"), False) 417 self.assertFalse(typedPrim.HasAuthoredMetadata("hidden")) 418 self.assertFalse("hidden" in typedPrim.GetAllAuthoredMetadata()) 419 420 # Documentation metadata comes from prim type definition even with API 421 # schemas applied. 422 self.assertEqual(typedPrim.GetMetadata("documentation"), 423 "Test with built-in API schemas") 424 425 def test_TypedPrimsOnStageWithBuiltinReapply(self): 426 """ 427 Tests the fallback properties of typed prims on a stage when the same 428 API schemas are applied again to a prim whose type already has applied 429 API schemas. 430 """ 431 stage = Usd.Stage.CreateInMemory() 432 433 # Add a typed prim. It has API schemas already from its prim definition 434 # and has properties from both its type and its APIs. 435 typedPrim = stage.DefinePrim("/TypedPrim", "TestWithBuiltinAppliedSchema") 436 self.assertEqual(typedPrim.GetTypeName(), 'TestWithBuiltinAppliedSchema') 437 self.assertEqual(typedPrim.GetAppliedSchemas(), 438 ["TestSingleApplyAPI", "TestMultiApplyAPI:builtin"]) 439 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 440 'TestWithBuiltinAppliedSchema') 441 # Note that prim type info does NOT contain the built-in applied API 442 # schemas from the concrete type's prim definition as these are not part 443 # of the type identity. 444 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 445 446 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 447 self.assertTrue(typedPrim.HasAPI(self.MultiApplyAPIType)) 448 self.assertEqual(typedPrim.GetPropertyNames(), [ 449 "multi:builtin:bool_attr", 450 "multi:builtin:relationship", 451 "multi:builtin:token_attr", 452 "single:bool_attr", 453 "single:relationship", 454 "single:token_attr", 455 "testAttr", 456 "testRel"]) 457 # Property fallback comes from TestSingleApplyAPI 458 attr = typedPrim.GetAttribute("single:token_attr") 459 self.assertEqual(attr.Get(), "bar") 460 self.assertEqual(attr.GetResolveInfo().GetSource(), 461 Usd.ResolveInfoSourceFallback) 462 # Property fallback actually comes from TestTypedSchema as the typed 463 # schema overrides this property from its built-in API schema. 464 attr = typedPrim.GetAttribute("multi:builtin:bool_attr") 465 self.assertEqual(attr.Get(), False) 466 self.assertEqual(attr.GetResolveInfo().GetSource(), 467 Usd.ResolveInfoSourceFallback) 468 # Property fallback comes from TestTypedSchema 469 attr = typedPrim.GetAttribute("testAttr") 470 self.assertEqual(attr.Get(), "foo") 471 self.assertEqual(attr.GetResolveInfo().GetSource(), 472 Usd.ResolveInfoSourceFallback) 473 474 # Add the built-in api schemas again to the prim's metadata. 475 typedPrim.ApplyAPI(self.MultiApplyAPIType, "builtin") 476 typedPrim.ApplyAPI(self.SingleApplyAPIType) 477 478 # Prim has the same type and now has both its original API schemas and 479 # plus the same schemas again appended to the list (i.e. both schemas 480 # now show up twice). 481 self.assertEqual(typedPrim.GetTypeName(), 'TestWithBuiltinAppliedSchema') 482 self.assertEqual(typedPrim.GetAppliedSchemas(), 483 ["TestMultiApplyAPI:builtin", "TestSingleApplyAPI", 484 "TestSingleApplyAPI", "TestMultiApplyAPI:builtin"]) 485 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 486 'TestWithBuiltinAppliedSchema') 487 # Note that prim type info does NOT contain the built-in applied API 488 # schemas from the concrete type's prim definition as these are not part 489 # of the type identity. 490 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 491 ["TestMultiApplyAPI:builtin", "TestSingleApplyAPI"]) 492 493 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 494 self.assertTrue(typedPrim.HasAPI(self.MultiApplyAPIType)) 495 496 # The list of properties hasn't changed as there are no "new" schemas, 497 # however the defaults may have changed. 498 self.assertEqual(typedPrim.GetPropertyNames(), [ 499 "multi:builtin:bool_attr", 500 "multi:builtin:relationship", 501 "multi:builtin:token_attr", 502 "single:bool_attr", 503 "single:relationship", 504 "single:token_attr", 505 "testAttr", 506 "testRel"]) 507 508 # Property fallback comes from TestSingleApplyAPI - no change 509 attr = typedPrim.GetAttribute("single:token_attr") 510 self.assertEqual(attr.Get(), "bar") 511 self.assertEqual(attr.GetResolveInfo().GetSource(), 512 Usd.ResolveInfoSourceFallback) 513 # Property fallback has now changed from False to True as the 514 # TestTypedSchema originally overrode the fallback from 515 # TestMultiApplyAPI. But by applying TestMultiApplyAPI again with the 516 # same instance, we've re-overridden the attribute getting the default 517 # from the applied schema. 518 attr = typedPrim.GetAttribute("multi:builtin:bool_attr") 519 self.assertEqual(attr.Get(), True) 520 self.assertEqual(attr.GetResolveInfo().GetSource(), 521 Usd.ResolveInfoSourceFallback) 522 # Property fallback comes from TestTypedSchema - no change 523 attr = typedPrim.GetAttribute("testAttr") 524 self.assertEqual(attr.Get(), "foo") 525 self.assertEqual(attr.GetResolveInfo().GetSource(), 526 Usd.ResolveInfoSourceFallback) 527 528 # Prim metadata is unchanged from the case above as there is still 529 # no way for applied API schemas to impart prim metadata defaults. 530 self.assertEqual(typedPrim.GetAllMetadata()["hidden"], False) 531 self.assertEqual(typedPrim.GetMetadata("hidden"), False) 532 self.assertFalse(typedPrim.HasAuthoredMetadata("hidden")) 533 self.assertFalse("hidden" in typedPrim.GetAllAuthoredMetadata()) 534 535 # Documentation metadata comes from prim type definition even with API 536 # schemas applied. 537 self.assertEqual(typedPrim.GetMetadata("documentation"), 538 "Test with built-in API schemas") 539 540 @unittest.skipIf(Tf.GetEnvSetting('USD_DISABLE_AUTO_APPLY_API_SCHEMAS'), 541 "Auto apply API schemas are disabled") 542 def test_TypedPrimsOnStageWithAutoAppliedAPIs(self): 543 """ 544 Tests the fallback properties of typed prims on a stage where API 545 schemas are auto applied. 546 """ 547 stage = Usd.Stage.CreateInMemory() 548 549 # Add a typed prim that has two types of built-in applied schemas. 550 # TestMultiApplyAPI:builtin comes from the apiSchemas metadata defined 551 # in TestTypedSchemaForAutoApply's schema definition. 552 # TestSingleApplyAPI and TestMultiApplyAPI:autoFoo come from 553 # TestTypedSchemaForAutoApply being listed in the "AutoApplyAPISchemas" 554 # plugInfo metadata for both API schemas. 555 # The built-in applied schemas that come from the apiSchemas metadata 556 # will always be listed before (and be stronger than) any applied 557 # schemas that come from apiSchemaAutoApplyTo. 558 typedPrim = stage.DefinePrim("/TypedPrim", "TestTypedSchemaForAutoApply") 559 self.assertEqual(typedPrim.GetTypeName(), 'TestTypedSchemaForAutoApply') 560 self.assertEqual(typedPrim.GetAppliedSchemas(), 561 ["TestMultiApplyAPI:builtin", 562 "TestMultiApplyAPI:autoFoo", 563 "TestSingleApplyAPI"]) 564 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 565 'TestTypedSchemaForAutoApply') 566 # Note that prim type info does NOT contain the applied API 567 # schemas from the concrete type's prim definition as these are not part 568 # of the type identity. 569 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 570 571 self.assertTrue(typedPrim.HasAPI(self.MultiApplyAPIType)) 572 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 573 self.assertEqual(typedPrim.GetPropertyNames(), [ 574 "multi:autoFoo:bool_attr", 575 "multi:autoFoo:relationship", 576 "multi:autoFoo:token_attr", 577 "multi:builtin:bool_attr", 578 "multi:builtin:relationship", 579 "multi:builtin:token_attr", 580 "single:bool_attr", 581 "single:relationship", 582 "single:token_attr", 583 "testAttr", 584 "testRel"]) 585 586 # Add a concrete typed prim which receives an auto applied API schema. 587 # TestSingleApplyAPI comes from TestTypedSchemaForAutoApplyConcreteBase 588 # being listed in TestSingleApplyAPI's apiSchemaAutoApplyTo data. 589 typedPrim.SetTypeName("TestTypedSchemaForAutoApplyConcreteBase") 590 self.assertEqual(typedPrim.GetTypeName(), 591 'TestTypedSchemaForAutoApplyConcreteBase') 592 self.assertEqual(typedPrim.GetAppliedSchemas(), 593 ["TestSingleApplyAPI"]) 594 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 595 'TestTypedSchemaForAutoApplyConcreteBase') 596 # Note that prim type info does NOT contain the auto applied API 597 # schemas from the concrete type's prim definition as these are not part 598 # of the type identity. 599 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 600 601 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 602 self.assertEqual(typedPrim.GetPropertyNames(), [ 603 "single:bool_attr", 604 "single:relationship", 605 "single:token_attr", 606 "testAttr", 607 "testRel"]) 608 609 # Add a concrete typed prim which receives an auto applied API schema 610 # because it is derived from a base class type that does. 611 # TestSingleApplyAPI comes from the base class of this type, 612 # TestTypedSchemaForAutoApplyConcreteBase, being listed in 613 # TestSingleApplyAPI's apiSchemaAutoApplyTo data. 614 typedPrim.SetTypeName("TestDerivedTypedSchemaForAutoApplyConcreteBase") 615 self.assertEqual(typedPrim.GetTypeName(), 616 'TestDerivedTypedSchemaForAutoApplyConcreteBase') 617 self.assertEqual(typedPrim.GetAppliedSchemas(), 618 ["TestSingleApplyAPI"]) 619 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 620 'TestDerivedTypedSchemaForAutoApplyConcreteBase') 621 # Note that prim type info does NOT contain the auto applied API 622 # schemas from the concrete type's prim definition as these are not part 623 # of the type identity. 624 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 625 626 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 627 self.assertEqual(typedPrim.GetPropertyNames(), [ 628 "single:bool_attr", 629 "single:relationship", 630 "single:token_attr", 631 "testAttr", 632 "testRel"]) 633 634 # Add a concrete typed prim which receives an auto applied API schema 635 # because it is derived from a base class type that does. 636 # TestSingleApplyAPI comes from the base class of this type, 637 # TestTypedSchemaForAutoApplyAbstractBase, being listed in 638 # TestSingleApplyAPI's apiSchemaAutoApplyTo data. This is different 639 # from case above in that the base class is an abstract type and cannot 640 # be instantiated as a prim type, but API schemas can still be 641 # designated to auto apply to abstract types to have the API applied 642 # to prims of all derived types. 643 typedPrim.SetTypeName("TestDerivedTypedSchemaForAutoApplyAbstractBase") 644 self.assertEqual(typedPrim.GetTypeName(), 645 'TestDerivedTypedSchemaForAutoApplyAbstractBase') 646 self.assertEqual(typedPrim.GetAppliedSchemas(), ['TestSingleApplyAPI']) 647 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 648 'TestDerivedTypedSchemaForAutoApplyAbstractBase') 649 # Note that prim type info does NOT contain the auto applied API 650 # schemas from the concrete type's prim definition as these are not part 651 # of the type identity. 652 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 653 654 self.assertTrue(typedPrim.HasAPI(self.SingleApplyAPIType)) 655 self.assertEqual(typedPrim.GetPropertyNames(), [ 656 "single:bool_attr", 657 "single:relationship", 658 "single:token_attr", 659 "testAttr", 660 "testRel"]) 661 662 # Verify that we can get the value of the auto apply API metadata for 663 # TestSingleApplyAPI from the schema registry. 664 self.assertEqual( 665 Usd.SchemaRegistry.GetAutoApplyAPISchemas()['TestSingleApplyAPI'], 666 ['TestTypedSchemaForAutoApplyConcreteBase', 667 'TestTypedSchemaForAutoApplyAbstractBase', 668 'TestAutoAppliedToAPI', 669 'TestTypedSchemaForAutoApply']) 670 671 @unittest.skipIf(not Tf.GetEnvSetting('USD_DISABLE_AUTO_APPLY_API_SCHEMAS'), 672 "Auto apply API schemas are not disabled") 673 def test_TypedPrimsOnStageWithAutoAppliedAPIs_AutoApplyDisabled(self): 674 """ 675 Tests the disabling of auto apply schemas through the environment 676 variable USD_DISABLE_AUTO_APPLY_API_SCHEMAS. 677 """ 678 stage = Usd.Stage.CreateInMemory() 679 680 # Add a typed prim that has two types of built-in applied schemas. 681 # TestMultiApplyAPI:builtin comes from the apiSchemas metadata defined 682 # in TestTypedSchemaForAutoApply's schema definition and is NOT affected 683 # by disabling auto apply API schemas. 684 # 685 # TestSingleApplyAPI and TestMultiApplyAPI:autoFoo would come from 686 # TestTypedSchemaForAutoApply being listed in the "AutoApplyAPISchemas" 687 # plugInfo metadata for both API schemas, but with auto apply disabled, 688 # they are not applied to this type. 689 typedPrim = stage.DefinePrim("/TypedPrim", "TestTypedSchemaForAutoApply") 690 self.assertEqual(typedPrim.GetTypeName(), 691 'TestTypedSchemaForAutoApply') 692 self.assertEqual(typedPrim.GetAppliedSchemas(), 693 ["TestMultiApplyAPI:builtin"]) 694 695 self.assertTrue(typedPrim.HasAPI(self.MultiApplyAPIType, 'builtin')) 696 self.assertFalse(typedPrim.HasAPI(self.MultiApplyAPIType, 'autoFoo')) 697 self.assertFalse(typedPrim.HasAPI(self.SingleApplyAPIType)) 698 self.assertEqual(typedPrim.GetPropertyNames(), [ 699 "multi:builtin:bool_attr", 700 "multi:builtin:relationship", 701 "multi:builtin:token_attr", 702 "testAttr", 703 "testRel"]) 704 705 # Add a concrete typed prim which receives an auto applied API schema. 706 # TestSingleApplyAPI would be auto applied to this type, but with auto 707 # apply disable, this type has no applied API schemas. 708 typedPrim.SetTypeName("TestTypedSchemaForAutoApplyConcreteBase") 709 self.assertEqual(typedPrim.GetTypeName(), 710 'TestTypedSchemaForAutoApplyConcreteBase') 711 self.assertEqual(typedPrim.GetAppliedSchemas(), []) 712 713 self.assertFalse(typedPrim.HasAPI(self.SingleApplyAPIType)) 714 self.assertEqual(typedPrim.GetPropertyNames(), [ 715 "testAttr", 716 "testRel"]) 717 718 # Verify that the auto apply API schema dictionary is empty when auto 719 # apply is disabled.. 720 self.assertEqual(Usd.SchemaRegistry.GetAutoApplyAPISchemas(), {}) 721 722 def test_ApplyRemoveAPI(self): 723 """ 724 Tests the detail of the Apply and Remove API for API schemas. 725 """ 726 stage = Usd.Stage.CreateInMemory() 727 rootLayer = stage.GetRootLayer() 728 sessionLayer = stage.GetSessionLayer() 729 self.assertTrue(rootLayer) 730 self.assertTrue(sessionLayer) 731 732 # Add a basic prim with no type. It has no applied schemas or properties. 733 prim = stage.DefinePrim("/Prim") 734 self.assertEqual(prim.GetAppliedSchemas(), []) 735 self.assertEqual(prim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 736 737 # Helper function for verifying the state of the 'apiSchemas' list op 738 # field in the prim spec for the test prim on the specified layer. 739 def _VerifyListOp(layer, explicit = [], prepended = [], 740 appended = [], deleted = []): 741 spec = layer.GetPrimAtPath('/Prim') 742 listOp = spec.GetInfo('apiSchemas') 743 self.assertEqual(listOp.explicitItems, explicit) 744 self.assertEqual(listOp.prependedItems, prepended) 745 self.assertEqual(listOp.appendedItems, appended) 746 self.assertEqual(listOp.deletedItems, deleted) 747 748 # Apply a single api schema withe default edit target. Adds to the end 749 # prepend list. 750 prim.ApplyAPI(self.SingleApplyAPIType) 751 self.assertEqual(prim.GetAppliedSchemas(), ["TestSingleApplyAPI"]) 752 self.assertTrue(prim.HasAPI(self.SingleApplyAPIType)) 753 _VerifyListOp(rootLayer, prepended = ["TestSingleApplyAPI"]) 754 755 # Apply the same API schema again. This will not update the list. 756 prim.ApplyAPI(self.SingleApplyAPIType) 757 self.assertEqual(prim.GetAppliedSchemas(), ["TestSingleApplyAPI"]) 758 self.assertTrue(prim.HasAPI(self.SingleApplyAPIType)) 759 _VerifyListOp(rootLayer, prepended = ["TestSingleApplyAPI"]) 760 761 # Remove the API schema. This removes the schema from the prepend and 762 # puts in it the deleted list. 763 prim.RemoveAPI(self.SingleApplyAPIType) 764 self.assertEqual(prim.GetAppliedSchemas(), []) 765 _VerifyListOp(rootLayer, deleted = ["TestSingleApplyAPI"]) 766 767 # Remove the same API again. This is a no op. 768 prim.RemoveAPI(self.SingleApplyAPIType) 769 self.assertEqual(prim.GetAppliedSchemas(), []) 770 _VerifyListOp(rootLayer, deleted = ["TestSingleApplyAPI"]) 771 772 # Remove a multi apply schema which is not currently in the list. The 773 # This schema instance name is still added to the deleted list. 774 prim.RemoveAPI(self.MultiApplyAPIType, "foo") 775 self.assertEqual(prim.GetAppliedSchemas(), []) 776 _VerifyListOp(rootLayer, 777 deleted = ["TestSingleApplyAPI", "TestMultiApplyAPI:foo"]) 778 779 # Apply the same instance of the multi-apply schema we just deleted. It 780 # is added to the prepended but is NOT removed from the deleted list. 781 # It still ends up in the composed API schemas since deletes are 782 # processed before prepends in the same list op. 783 prim.ApplyAPI(self.MultiApplyAPIType, "foo") 784 self.assertEqual(prim.GetAppliedSchemas(), ["TestMultiApplyAPI:foo"]) 785 _VerifyListOp(rootLayer, 786 prepended = ["TestMultiApplyAPI:foo"], 787 deleted = ["TestSingleApplyAPI", "TestMultiApplyAPI:foo"]) 788 789 # Apply a different instance of the multi-apply schema. Its is added to 790 # the end of the prepends list. 791 prim.ApplyAPI(self.MultiApplyAPIType, "bar") 792 self.assertEqual(prim.GetAppliedSchemas(), 793 ["TestMultiApplyAPI:foo", "TestMultiApplyAPI:bar"]) 794 _VerifyListOp(rootLayer, 795 prepended = ["TestMultiApplyAPI:foo", "TestMultiApplyAPI:bar"], 796 deleted = ["TestSingleApplyAPI", "TestMultiApplyAPI:foo"]) 797 798 # Remove the "bar" instance of the multi-apply schema on the session 799 # layer. The schema is added to the deleted list on the session layer 800 # and root layer remains the same. It does not show up in the composed 801 # API schemas after composition 802 with Usd.EditContext(stage, sessionLayer): 803 prim.RemoveAPI(self.MultiApplyAPIType, "bar") 804 self.assertEqual(prim.GetAppliedSchemas(), ["TestMultiApplyAPI:foo"]) 805 _VerifyListOp(rootLayer, 806 prepended = ["TestMultiApplyAPI:foo", "TestMultiApplyAPI:bar"], 807 deleted = ["TestSingleApplyAPI", "TestMultiApplyAPI:foo"]) 808 _VerifyListOp(sessionLayer, 809 deleted = ["TestMultiApplyAPI:bar"]) 810 811 # Re-apply the "bar" instance of the multi-apply schema on the session 812 # layer. It is added to the prepend list in the session layer but still 813 # remains in the delete list. Note that the "bar" instance is back in 814 # the composed API schemas list but now it is first instead of second 815 # like it was before as it get deleted and prepended by the session 816 # layer. 817 with Usd.EditContext(stage, sessionLayer): 818 prim.ApplyAPI(self.MultiApplyAPIType, "bar") 819 self.assertEqual(prim.GetAppliedSchemas(), 820 ["TestMultiApplyAPI:bar", "TestMultiApplyAPI:foo"]) 821 _VerifyListOp(rootLayer, 822 prepended = ["TestMultiApplyAPI:foo", "TestMultiApplyAPI:bar"], 823 deleted = ["TestSingleApplyAPI", "TestMultiApplyAPI:foo"]) 824 _VerifyListOp(sessionLayer, 825 prepended = ["TestMultiApplyAPI:bar"], 826 deleted = ["TestMultiApplyAPI:bar"]) 827 828 # These next few cases verifies the behavior when the list op has 829 # appends or explicit entries. (Note that we don't define behaviors for 830 # add or reorder). 831 # Update the session layer to have an appended API schema. 832 with Usd.EditContext(stage, sessionLayer): 833 appendedListOp = Sdf.TokenListOp() 834 appendedListOp.appendedItems = ["TestMultiApplyAPI:bar"] 835 prim.SetMetadata('apiSchemas', appendedListOp) 836 # Update the root layer to have an explicit list op. 837 explicitListOp = Sdf.TokenListOp() 838 explicitListOp.explicitItems = ["TestMultiApplyAPI:foo"] 839 prim.SetMetadata('apiSchemas', explicitListOp) 840 # Verify the initial authored and composed lists. 841 self.assertEqual(prim.GetAppliedSchemas(), 842 ["TestMultiApplyAPI:foo", "TestMultiApplyAPI:bar"]) 843 _VerifyListOp(rootLayer, 844 explicit = ["TestMultiApplyAPI:foo"]) 845 _VerifyListOp(sessionLayer, 846 appended = ["TestMultiApplyAPI:bar"]) 847 848 # On the session and root layers, try to apply the API schema that 849 # is already in each respective list. This will be a no op even though 850 # the schemas aren't in the prepended lists. 851 with Usd.EditContext(stage, sessionLayer): 852 prim.ApplyAPI(self.MultiApplyAPIType, "bar") 853 prim.ApplyAPI(self.MultiApplyAPIType, "foo") 854 self.assertEqual(prim.GetAppliedSchemas(), 855 ["TestMultiApplyAPI:foo", "TestMultiApplyAPI:bar"]) 856 _VerifyListOp(rootLayer, 857 explicit = ["TestMultiApplyAPI:foo"]) 858 _VerifyListOp(sessionLayer, 859 appended = ["TestMultiApplyAPI:bar"]) 860 861 # Apply the single apply schema to both layers. The root layer adds it 862 # to the end of its explicit list while the session layer will add it 863 # the prepends. The composed API schemas will only contain the schema 864 # once with the prepend from the stronger session layer winning for 865 # ordering. 866 with Usd.EditContext(stage, sessionLayer): 867 prim.ApplyAPI(self.SingleApplyAPIType) 868 prim.ApplyAPI(self.SingleApplyAPIType) 869 self.assertEqual(prim.GetAppliedSchemas(), 870 ["TestSingleApplyAPI", "TestMultiApplyAPI:foo", 871 "TestMultiApplyAPI:bar"]) 872 _VerifyListOp(rootLayer, 873 explicit = ["TestMultiApplyAPI:foo", "TestSingleApplyAPI"]) 874 _VerifyListOp(sessionLayer, 875 prepended = ["TestSingleApplyAPI"], 876 appended = ["TestMultiApplyAPI:bar"]) 877 878 # Remove the starting API schemas from the root and session layers. In 879 # the root layer it is just removed from the explicit list. In the 880 # session layer it is removed from appends and added to the deletes. 881 with Usd.EditContext(stage, sessionLayer): 882 prim.RemoveAPI(self.MultiApplyAPIType, "bar") 883 prim.RemoveAPI(self.MultiApplyAPIType, "foo") 884 self.assertEqual(prim.GetAppliedSchemas(), 885 ["TestSingleApplyAPI"]) 886 _VerifyListOp(rootLayer, 887 explicit = ["TestSingleApplyAPI"]) 888 _VerifyListOp(sessionLayer, 889 prepended = ["TestSingleApplyAPI"], 890 deleted = ["TestMultiApplyAPI:bar"]) 891 892 # Clear the apiSchemas in both layers for the next tests. 893 # XXX: Should we have additional API for clearing the list op like we 894 # do for other list op fields? 895 with Usd.EditContext(stage, sessionLayer): 896 prim.SetMetadata('apiSchemas', Sdf.TokenListOp()) 897 prim.SetMetadata('apiSchemas', Sdf.TokenListOp()) 898 self.assertEqual(prim.GetAppliedSchemas(), []) 899 _VerifyListOp(rootLayer) 900 _VerifyListOp(sessionLayer) 901 902 # Trying to apply or remove a multi-apply schema with no instance name 903 # is an error. 904 with self.assertRaises(Tf.ErrorException): 905 prim.ApplyAPI(self.MultiApplyAPIType) 906 self.assertEqual(prim.GetAppliedSchemas(), []) 907 _VerifyListOp(rootLayer) 908 with self.assertRaises(Tf.ErrorException): 909 prim.RemoveAPI(self.MultiApplyAPIType) 910 self.assertEqual(prim.GetAppliedSchemas(), []) 911 _VerifyListOp(rootLayer) 912 913 # Trying to apply or remove a single apply schema with an instance name 914 # is an error. 915 with self.assertRaises(Tf.ErrorException): 916 prim.ApplyAPI(self.SingleApplyAPIType, "foo") 917 self.assertEqual(prim.GetAppliedSchemas(), []) 918 _VerifyListOp(rootLayer) 919 with self.assertRaises(Tf.ErrorException): 920 prim.RemoveAPI(self.SingleApplyAPIType, "foo") 921 self.assertEqual(prim.GetAppliedSchemas(), []) 922 _VerifyListOp(rootLayer) 923 924 # Trying to apply or remove a no apply schema is an error. 925 with self.assertRaises(Tf.ErrorException): 926 prim.ApplyAPI(Usd.ModelAPI) 927 self.assertEqual(prim.GetAppliedSchemas(), []) 928 _VerifyListOp(rootLayer) 929 with self.assertRaises(Tf.ErrorException): 930 prim.RemoveAPI(Usd.ModelAPI) 931 self.assertEqual(prim.GetAppliedSchemas(), []) 932 _VerifyListOp(rootLayer) 933 934 # AddAPITypeName will just add by schema type name with no validity 935 # checks. But it still won't add duplicates. 936 # 937 # Valid type names 938 prim.AddAppliedSchema("TestSingleApplyAPI") 939 prim.AddAppliedSchema("TestMultiApplyAPI:bar") 940 # Invalid type names. 941 prim.AddAppliedSchema("BogusTypeName") 942 prim.AddAppliedSchema("TestMultiApplyAPI") 943 # Duplicate. 944 prim.AddAppliedSchema("TestSingleApplyAPI") 945 # Even though invalid type names get added to the apiSchemas metadata, 946 # they won't show up in GetAppliedSchemas as they won't be composed into 947 # the prim's UsdPrimDefinition. 948 self.assertEqual(prim.GetAppliedSchemas(), 949 ["TestSingleApplyAPI", "TestMultiApplyAPI:bar"]) 950 _VerifyListOp(rootLayer, 951 prepended = ["TestSingleApplyAPI", "TestMultiApplyAPI:bar", 952 "BogusTypeName", "TestMultiApplyAPI"]) 953 954 # RemoveAPITypeName will just delete by schema type name with no 955 # validity checks. But it still won't add duplicate delete entries. 956 # 957 # Valid type names 958 prim.RemoveAppliedSchema("TestSingleApplyAPI") 959 prim.RemoveAppliedSchema("TestMultiApplyAPI:bar") 960 # Invalid type names. 961 prim.RemoveAppliedSchema("BogusTypeName") 962 prim.RemoveAppliedSchema("TestMultiApplyAPI") 963 # Duplicate. 964 prim.RemoveAppliedSchema("TestSingleApplyAPI") 965 self.assertEqual(prim.GetAppliedSchemas(), []) 966 _VerifyListOp(rootLayer, 967 deleted = ["TestSingleApplyAPI", "TestMultiApplyAPI:bar", 968 "BogusTypeName", "TestMultiApplyAPI"]) 969 970 def test_CanApplyAPI(self): 971 """ 972 Tests the details of the Usd.Prim.CanApplyAPI. 973 """ 974 stage = Usd.Stage.CreateInMemory() 975 rootLayer = stage.GetRootLayer() 976 sessionLayer = stage.GetSessionLayer() 977 self.assertTrue(rootLayer) 978 self.assertTrue(sessionLayer) 979 980 # Add prims of various types to test CanApplyAPI. 981 prim = stage.DefinePrim( 982 "/Prim") 983 prim2 = stage.DefinePrim( 984 "/Prim2", "TestTypedSchema") 985 prim3 = stage.DefinePrim( 986 "/Prim3", "TestTypedSchemaForAutoApply") 987 prim4 = stage.DefinePrim( 988 "/Prim4", "TestDerivedTypedSchemaForAutoApplyConcreteBase") 989 prim5 = stage.DefinePrim( 990 "/Prim5", "TestDerivedTypedSchemaForAutoApplyAbstractBase") 991 992 # Single apply schema with no specified "apiSchemaCanOnlyApplyTo" 993 # metadata. Can apply to all prims. 994 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 995 "TestSingleApplyAPI"), []) 996 self.assertTrue(prim.CanApplyAPI(self.SingleApplyAPIType)) 997 self.assertTrue(prim2.CanApplyAPI(self.SingleApplyAPIType)) 998 self.assertTrue(prim3.CanApplyAPI(self.SingleApplyAPIType)) 999 self.assertTrue(prim4.CanApplyAPI(self.SingleApplyAPIType)) 1000 self.assertTrue(prim5.CanApplyAPI(self.SingleApplyAPIType)) 1001 1002 # Multiple apply schema with no specified "apiSchemaCanOnlyApplyTo" 1003 # metadata and no "allowedInstanceNames". Can apply to all prims with 1004 # all instance names (with the notable exception of instance names that 1005 # match a property name from the schema). 1006 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1007 "TestMultiApplyAPI", "foo"), []) 1008 self.assertTrue(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1009 "TestMultiApplyAPI", "foo")) 1010 self.assertTrue(prim.CanApplyAPI(self.MultiApplyAPIType, "foo")) 1011 self.assertTrue(prim2.CanApplyAPI(self.MultiApplyAPIType, "foo")) 1012 self.assertTrue(prim3.CanApplyAPI(self.MultiApplyAPIType, "foo")) 1013 self.assertTrue(prim4.CanApplyAPI(self.MultiApplyAPIType, "foo")) 1014 self.assertTrue(prim5.CanApplyAPI(self.MultiApplyAPIType, "foo")) 1015 1016 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1017 "TestMultiApplyAPI", "bar"), []) 1018 self.assertTrue(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1019 "TestMultiApplyAPI", "bar")) 1020 self.assertTrue(prim.CanApplyAPI(self.MultiApplyAPIType, "bar")) 1021 self.assertTrue(prim2.CanApplyAPI(self.MultiApplyAPIType, "bar")) 1022 self.assertTrue(prim3.CanApplyAPI(self.MultiApplyAPIType, "bar")) 1023 self.assertTrue(prim4.CanApplyAPI(self.MultiApplyAPIType, "bar")) 1024 self.assertTrue(prim5.CanApplyAPI(self.MultiApplyAPIType, "bar")) 1025 1026 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1027 "TestMultiApplyAPI", "baz"), []) 1028 self.assertTrue(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1029 "TestMultiApplyAPI", "baz")) 1030 self.assertTrue(prim.CanApplyAPI(self.MultiApplyAPIType, "baz")) 1031 self.assertTrue(prim2.CanApplyAPI(self.MultiApplyAPIType, "baz")) 1032 self.assertTrue(prim3.CanApplyAPI(self.MultiApplyAPIType, "baz")) 1033 self.assertTrue(prim4.CanApplyAPI(self.MultiApplyAPIType, "baz")) 1034 self.assertTrue(prim5.CanApplyAPI(self.MultiApplyAPIType, "baz")) 1035 1036 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1037 "TestMultiApplyAPI", "Bar"), []) 1038 self.assertTrue(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1039 "TestMultiApplyAPI", "Bar")) 1040 self.assertTrue(prim.CanApplyAPI(self.MultiApplyAPIType, "Bar")) 1041 self.assertTrue(prim2.CanApplyAPI(self.MultiApplyAPIType, "Bar")) 1042 self.assertTrue(prim3.CanApplyAPI(self.MultiApplyAPIType, "Bar")) 1043 self.assertTrue(prim4.CanApplyAPI(self.MultiApplyAPIType, "Bar")) 1044 self.assertTrue(prim5.CanApplyAPI(self.MultiApplyAPIType, "Bar")) 1045 1046 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1047 "TestMultiApplyAPI", "qux"), []) 1048 self.assertTrue(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1049 "TestMultiApplyAPI", "qux")) 1050 self.assertTrue(prim.CanApplyAPI(self.MultiApplyAPIType, "qux")) 1051 self.assertTrue(prim2.CanApplyAPI(self.MultiApplyAPIType, "qux")) 1052 self.assertTrue(prim3.CanApplyAPI(self.MultiApplyAPIType, "qux")) 1053 self.assertTrue(prim4.CanApplyAPI(self.MultiApplyAPIType, "qux")) 1054 self.assertTrue(prim5.CanApplyAPI(self.MultiApplyAPIType, "qux")) 1055 1056 # As mentioned above, property names of the API schema are not valid 1057 # instance names and will return false for CanApplyAPI 1058 self.assertFalse(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1059 "TestMultiApplyAPI", "bool_attr")) 1060 self.assertFalse(prim.CanApplyAPI(self.MultiApplyAPIType, "bool_attr")) 1061 self.assertFalse(prim2.CanApplyAPI(self.MultiApplyAPIType, "bool_attr")) 1062 self.assertFalse(prim3.CanApplyAPI(self.MultiApplyAPIType, "bool_attr")) 1063 self.assertFalse(prim4.CanApplyAPI(self.MultiApplyAPIType, "bool_attr")) 1064 self.assertFalse(prim5.CanApplyAPI(self.MultiApplyAPIType, "bool_attr")) 1065 1066 self.assertFalse(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1067 "TestMultiApplyAPI", "relationship")) 1068 self.assertFalse(prim.CanApplyAPI(self.MultiApplyAPIType, "relationship")) 1069 self.assertFalse(prim2.CanApplyAPI(self.MultiApplyAPIType, "relationship")) 1070 self.assertFalse(prim3.CanApplyAPI(self.MultiApplyAPIType, "relationship")) 1071 self.assertFalse(prim4.CanApplyAPI(self.MultiApplyAPIType, "relationship")) 1072 self.assertFalse(prim5.CanApplyAPI(self.MultiApplyAPIType, "relationship")) 1073 1074 # Single apply API schema that does specify an "apiSchemaCanOnlyApplyTo" 1075 # list. prim3 is a type in the list and prim4 derives from a type in the 1076 # list so only these return true. 1077 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1078 "TestSingleCanApplyAPI"), 1079 ["TestTypedSchemaForAutoApply", 1080 "TestTypedSchemaForAutoApplyConcreteBase"]) 1081 self.assertFalse(prim.CanApplyAPI(self.SingleCanApplyAPIType)) 1082 self.assertFalse(prim2.CanApplyAPI(self.SingleCanApplyAPIType)) 1083 self.assertTrue(prim3.CanApplyAPI(self.SingleCanApplyAPIType)) 1084 self.assertTrue(prim4.CanApplyAPI(self.SingleCanApplyAPIType)) 1085 self.assertFalse(prim5.CanApplyAPI(self.SingleCanApplyAPIType)) 1086 1087 # Multiple apply API schema that specifies allow instance names 1088 # "foo", "bar", and "baz". All other instance names aren't allowed 1089 # and will return false. 1090 self.assertFalse(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1091 "TestMultiCanApplyAPI", "Bar")) 1092 self.assertFalse(prim.CanApplyAPI(self.MultiCanApplyAPIType, "Bar")) 1093 self.assertFalse(prim2.CanApplyAPI(self.MultiCanApplyAPIType, "Bar")) 1094 self.assertFalse(prim3.CanApplyAPI(self.MultiCanApplyAPIType, "Bar")) 1095 self.assertFalse(prim4.CanApplyAPI(self.MultiCanApplyAPIType, "Bar")) 1096 self.assertFalse(prim5.CanApplyAPI(self.MultiCanApplyAPIType, "Bar")) 1097 1098 self.assertFalse(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1099 "TestMultiCanApplyAPI", "qux")) 1100 self.assertFalse(prim.CanApplyAPI(self.MultiCanApplyAPIType, "qux")) 1101 self.assertFalse(prim2.CanApplyAPI(self.MultiCanApplyAPIType, "qux")) 1102 self.assertFalse(prim3.CanApplyAPI(self.MultiCanApplyAPIType, "qux")) 1103 self.assertFalse(prim4.CanApplyAPI(self.MultiCanApplyAPIType, "qux")) 1104 self.assertFalse(prim5.CanApplyAPI(self.MultiCanApplyAPIType, "qux")) 1105 1106 # Same multiple apply API schema with allowed instance name "baz". 1107 # The API schema type specifies an "apiSchemaCanOnlyApplyTo" list so 1108 # this instance can only be applied to those types. prim3 is a type in 1109 # the list and prim5 derives from a type in the list so only these 1110 # return true. 1111 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1112 "TestMultiCanApplyAPI", "baz"), 1113 ["TestTypedSchemaForAutoApply", 1114 "TestTypedSchemaForAutoApplyAbstractBase"]) 1115 self.assertEqual( 1116 Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1117 "TestMultiCanApplyAPI", "baz"), 1118 Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1119 "TestMultiCanApplyAPI")) 1120 self.assertTrue(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1121 "TestMultiCanApplyAPI", "baz")) 1122 self.assertFalse(prim.CanApplyAPI(self.MultiCanApplyAPIType, "baz")) 1123 self.assertFalse(prim2.CanApplyAPI(self.MultiCanApplyAPIType, "baz")) 1124 self.assertTrue(prim3.CanApplyAPI(self.MultiCanApplyAPIType, "baz")) 1125 self.assertFalse(prim4.CanApplyAPI(self.MultiCanApplyAPIType, "baz")) 1126 self.assertTrue(prim5.CanApplyAPI(self.MultiCanApplyAPIType, "baz")) 1127 1128 # Same multiple apply API schema with allowed instance name "foo". 1129 # The API schema type specifies an "apiSchemaCanOnlyApplyTo" list 1130 # specifically for "foo" so this instance can only be applied to those 1131 # types. prim3 is a type in the list and prim4 derives from a type in 1132 # the list so only these return true. 1133 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1134 "TestMultiCanApplyAPI", "foo"), 1135 ["TestTypedSchemaForAutoApply", 1136 "TestTypedSchemaForAutoApplyConcreteBase"]) 1137 self.assertNotEqual( 1138 Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1139 "TestMultiCanApplyAPI", "foo"), 1140 Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1141 "TestMultiCanApplyAPI")) 1142 self.assertTrue(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1143 "TestMultiCanApplyAPI", "foo")) 1144 self.assertFalse(prim.CanApplyAPI(self.MultiCanApplyAPIType, "foo")) 1145 self.assertFalse(prim2.CanApplyAPI(self.MultiCanApplyAPIType, "foo")) 1146 self.assertTrue(prim3.CanApplyAPI(self.MultiCanApplyAPIType, "foo")) 1147 self.assertTrue(prim4.CanApplyAPI(self.MultiCanApplyAPIType, "foo")) 1148 self.assertFalse(prim5.CanApplyAPI(self.MultiCanApplyAPIType, "foo")) 1149 1150 # Same multiple apply API schema with allowed instance name "bar". 1151 # The API schema type specifies yet another "apiSchemaCanOnlyApplyTo" 1152 # list specifically for "bar" so this instance can only be applied to 1153 # those types. prim4 and prim5 each derive from a different type in 1154 # the list so only these return true. 1155 self.assertEqual(Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1156 "TestMultiCanApplyAPI", "bar"), 1157 ["TestTypedSchemaForAutoApplyAbstractBase", 1158 "TestTypedSchemaForAutoApplyConcreteBase"]) 1159 self.assertNotEqual( 1160 Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1161 "TestMultiCanApplyAPI", "bar"), 1162 Usd.SchemaRegistry.GetAPISchemaCanOnlyApplyToTypeNames( 1163 "TestMultiCanApplyAPI")) 1164 self.assertTrue(Usd.SchemaRegistry.IsAllowedAPISchemaInstanceName( 1165 "TestMultiCanApplyAPI", "bar")) 1166 self.assertFalse(prim.CanApplyAPI(self.MultiCanApplyAPIType, "bar")) 1167 self.assertFalse(prim2.CanApplyAPI(self.MultiCanApplyAPIType, "bar")) 1168 self.assertFalse(prim3.CanApplyAPI(self.MultiCanApplyAPIType, "bar")) 1169 self.assertTrue(prim4.CanApplyAPI(self.MultiCanApplyAPIType, "bar")) 1170 self.assertTrue(prim5.CanApplyAPI(self.MultiCanApplyAPIType, "bar")) 1171 1172 # Error conditions 1173 # Coding error if called on single apply schema with an instance name. 1174 with self.assertRaises(Tf.ErrorException): 1175 self.assertFalse(prim.CanApplyAPI(self.SingleApplyAPIType, "foo")) 1176 # Coding error if called on multiple apply schema without an instance 1177 # name. 1178 with self.assertRaises(Tf.ErrorException): 1179 self.assertFalse(prim.CanApplyAPI(self.MultiApplyAPIType)) 1180 # Coding error if called on multiple apply schema with an empty instance 1181 # name. 1182 with self.assertRaises(Tf.ErrorException): 1183 self.assertFalse(prim.CanApplyAPI(self.MultiApplyAPIType, "")) 1184 1185 # Verify whyNot annotations when CanApplyAPI is false. 1186 result = prim4.CanApplyAPI(self.MultiCanApplyAPIType, "bar") 1187 self.assertTrue(result) 1188 self.assertEqual(result.whyNot, "") 1189 1190 result = prim.CanApplyAPI(self.MultiCanApplyAPIType, "qux") 1191 self.assertFalse(result) 1192 self.assertEqual(result.whyNot, 1193 "'qux' is not an allowed instance name for multiple " 1194 "apply API schema 'TestMultiCanApplyAPI'.") 1195 1196 result = prim.CanApplyAPI(self.MultiCanApplyAPIType, "bar") 1197 self.assertFalse(result) 1198 self.assertEqual(result.whyNot, 1199 "API schema 'TestMultiCanApplyAPI:bar' can only be " 1200 "applied to prims of the following types: " 1201 "TestTypedSchemaForAutoApplyAbstractBase, " 1202 "TestTypedSchemaForAutoApplyConcreteBase.") 1203 1204 result = prim.CanApplyAPI(self.MultiApplyAPIType, "bool_attr") 1205 self.assertFalse(result) 1206 self.assertEqual(result.whyNot, 1207 "'bool_attr' is not an allowed instance name for " 1208 "multiple apply API schema 'TestMultiApplyAPI'.") 1209 1210 def test_NestedAPISchemas(self): 1211 """ 1212 Tests the application of API schemas that have nested built-in API 1213 schemas 1214 """ 1215 stage = Usd.Stage.CreateInMemory() 1216 1217 # Simple helper for testing that a prim has expected attributes that 1218 # resolve to expected values. 1219 def _VerifyAttrValues(prim, expectedAttrValues): 1220 values = {name : prim.GetAttribute(name).Get() 1221 for name in expectedAttrValues.keys()} 1222 self.assertEqual(values, expectedAttrValues) 1223 1224 # Add a prim with no type and apply the TestNestedInnerSingleApplyAPI. 1225 innerSinglePrim = stage.DefinePrim("/InnerSingle") 1226 innerSinglePrim.ApplyAPI(self.NestedInnerSingleApplyAPIType) 1227 1228 # The authored applied API schemas for the prim is only the applied 1229 # TestNestedInnerSingleApplyAPI. 1230 self.assertEqual(innerSinglePrim.GetPrimTypeInfo().GetTypeName(), '') 1231 self.assertEqual(innerSinglePrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 1232 ["TestNestedInnerSingleApplyAPI"]) 1233 1234 # The composed applied API schemas however also contain the 1235 # TestSingleApplyAPI and the "bar" instance of TestMultiApplyAPI as 1236 # these are built-in APIs of TestNestedInnerSingleApplyAPI 1237 expectedAPISchemas = [ 1238 "TestNestedInnerSingleApplyAPI", 1239 "TestSingleApplyAPI", 1240 "TestMultiApplyAPI:bar"] 1241 self.assertEqual(innerSinglePrim.GetAppliedSchemas(), 1242 expectedAPISchemas) 1243 # The prim "has" all these built-in APIs as well. 1244 self.assertTrue(innerSinglePrim.HasAPI(self.NestedInnerSingleApplyAPIType)) 1245 self.assertTrue(innerSinglePrim.HasAPI(self.SingleApplyAPIType)) 1246 self.assertTrue(innerSinglePrim.HasAPI(self.MultiApplyAPIType)) 1247 self.assertTrue(innerSinglePrim.HasAPI(self.MultiApplyAPIType, "bar")) 1248 1249 # Properties come from all composed built-in APIs 1250 expectedPropNames = [ 1251 # Properties from TestNestedInnerSingleApplyAPI 1252 "innerSingle:int_attr", 1253 "innerSingle:relationship", 1254 "innerSingle:token_attr", 1255 # Properties from TestMultiApplyAPI:bar 1256 "multi:bar:bool_attr", 1257 "multi:bar:relationship", 1258 "multi:bar:token_attr", 1259 # Properties from TestSingleApplyAPI 1260 "single:bool_attr", 1261 "single:relationship", 1262 "single:token_attr"] 1263 self.assertEqual(innerSinglePrim.GetPropertyNames(), expectedPropNames) 1264 1265 # Verify that the attribute fallback values come from the API schemas 1266 # that define them. The attribute "multi:bar:token_attr" is defined in 1267 # TestNestedInnerSingleApplyAPI and overrides the attr fallback value 1268 # defined in TestMultiApplyAPI:bar 1269 expectedAttrValues = { 1270 "multi:bar:token_attr" : "inner_override", 1271 "multi:bar:bool_attr" : True, 1272 "innerSingle:token_attr" : "inner", 1273 "innerSingle:int_attr" : 3, 1274 "single:token_attr" : "bar", 1275 "single:bool_attr" : True} 1276 _VerifyAttrValues(innerSinglePrim, expectedAttrValues) 1277 1278 # Get the prim definition for the API schema and verify its applied 1279 # API schemas and properties match what was imparted on the prim. 1280 innerSingleApplyAPIDef = \ 1281 Usd.SchemaRegistry().FindAppliedAPIPrimDefinition( 1282 "TestNestedInnerSingleApplyAPI") 1283 self.assertTrue(innerSingleApplyAPIDef) 1284 self.assertEqual(innerSingleApplyAPIDef.GetAppliedAPISchemas(), 1285 expectedAPISchemas) 1286 self.assertEqual(sorted(innerSingleApplyAPIDef.GetPropertyNames()), 1287 expectedPropNames) 1288 self.assertEqual(innerSingleApplyAPIDef.GetDocumentation(), 1289 "Test nested single apply API schema: inner schema") 1290 1291 # Add a prim with no type and apply the TestNestedOuterSingleApplyAPI. 1292 outerSinglePrim = stage.DefinePrim("/OuterSingle") 1293 outerSinglePrim.ApplyAPI(self.NestedOuterSingleApplyAPIType) 1294 1295 # The authored applied API schemas for the prim is only the applied 1296 # TestNestedOuterSingleApplyAPI. 1297 self.assertEqual(outerSinglePrim.GetPrimTypeInfo().GetTypeName(), '') 1298 self.assertEqual(outerSinglePrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 1299 ["TestNestedOuterSingleApplyAPI"]) 1300 1301 # The composed applied API schemas however also contain the 1302 # the "foo" instance of TestMultiApplyAPI and 1303 # TestNestedInnerSingleApplyAPI and as these are built-in APIs of 1304 # TestNestedOuterSingleApplyAPI. However, because 1305 # TestNestedInnerSingleApplyAPI has its own built-in API schemas, those 1306 # are also pulled into the composed applied API schemas for this prim 1307 self.assertEqual(outerSinglePrim.GetTypeName(), '') 1308 expectedAPISchemas = [ 1309 "TestNestedOuterSingleApplyAPI", 1310 "TestMultiApplyAPI:foo", 1311 "TestNestedInnerSingleApplyAPI", 1312 "TestSingleApplyAPI", 1313 "TestMultiApplyAPI:bar"] 1314 self.assertEqual(outerSinglePrim.GetAppliedSchemas(), 1315 expectedAPISchemas) 1316 1317 # Properties come from all composed built-in APIs 1318 expectedPropNames = [ 1319 "innerSingle:int_attr", 1320 "innerSingle:relationship", 1321 "innerSingle:token_attr", 1322 # Properties from TestMultiApplyAPI:bar (included from 1323 # TestNestedInnerSingleApplyAPI) 1324 "multi:bar:bool_attr", 1325 "multi:bar:relationship", 1326 "multi:bar:token_attr", 1327 # Properties from TestMultiApplyAPI:foo 1328 "multi:foo:bool_attr", 1329 "multi:foo:relationship", 1330 "multi:foo:token_attr", 1331 # Properties from TestNestedOuterSingleApplyAPI 1332 "outerSingle:int_attr", 1333 "outerSingle:relationship", 1334 "outerSingle:token_attr", 1335 # Properties from TestSingleApplyAPI (included from 1336 # TestNestedInnerSingleApplyAPI) 1337 "single:bool_attr", 1338 "single:relationship", 1339 "single:token_attr"] 1340 self.assertEqual(outerSinglePrim.GetPropertyNames(), expectedPropNames) 1341 1342 # Verify that the attribute fallback values come from the API schemas 1343 # that define them. The attribute override for "multi:bar:token_attr" 1344 # from TestNestedInnerSingleApplyAPI still comes through. 1345 # Also The attribute "single:token_attr" is defined in 1346 # TestNestedOuterSingleApplyAPI and overrides the attr fallback value 1347 # defined in TestSingleApplyAPI 1348 expectedAttrValues = { 1349 "innerSingle:token_attr" : "inner", 1350 "innerSingle:int_attr" : 3, 1351 "multi:bar:token_attr" : "inner_override", 1352 "multi:bar:bool_attr" : True, 1353 "multi:foo:token_attr" : "foo", 1354 "multi:foo:bool_attr" : True, 1355 "outerSingle:token_attr" : "outer", 1356 "outerSingle:int_attr" : 4, 1357 "single:token_attr" : "outer_override", 1358 "single:bool_attr" : True} 1359 _VerifyAttrValues(outerSinglePrim, expectedAttrValues) 1360 1361 # Get the prim definition for the API schema and verify its applied 1362 # API schemas and properties match what was imparted on the prim. 1363 outerSingleApplyAPIDef = \ 1364 Usd.SchemaRegistry().FindAppliedAPIPrimDefinition( 1365 "TestNestedOuterSingleApplyAPI") 1366 self.assertTrue(outerSingleApplyAPIDef) 1367 self.assertEqual(outerSingleApplyAPIDef.GetAppliedAPISchemas(), 1368 expectedAPISchemas) 1369 self.assertEqual(sorted(outerSingleApplyAPIDef.GetPropertyNames()), 1370 expectedPropNames) 1371 self.assertEqual(outerSingleApplyAPIDef.GetDocumentation(), 1372 "Test nested single apply API schema: outer schema") 1373 1374 # Apply the TestNestedInnerSingleApplyAPI to the same prim. This API 1375 # is already included through the TestNestedOuterSingleApplyAPI. 1376 outerSinglePrim.ApplyAPI(self.NestedInnerSingleApplyAPIType) 1377 1378 # The authored applied API schemas for the prim now contain both the 1379 # applied APIs. 1380 self.assertEqual(outerSinglePrim.GetPrimTypeInfo().GetTypeName(), '') 1381 self.assertEqual(outerSinglePrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 1382 ["TestNestedOuterSingleApplyAPI", 1383 "TestNestedInnerSingleApplyAPI"]) 1384 1385 # The composed applied API schemas are fully expanded from both authored 1386 # APIs and will contain duplicates. We don't check for duplicates that 1387 # occur because different authored APIs include the same applied schema 1388 # even though we do remove duplicates when determining what API schemas 1389 # a single API includes. 1390 self.assertEqual(outerSinglePrim.GetTypeName(), '') 1391 expectedAPISchemas = [ 1392 # API schemas from expanded TestNestedOuterSingleApplyAPI 1393 "TestNestedOuterSingleApplyAPI", 1394 "TestMultiApplyAPI:foo", 1395 "TestNestedInnerSingleApplyAPI", 1396 "TestSingleApplyAPI", 1397 "TestMultiApplyAPI:bar", 1398 # API schemas from expanded TestNestedInnerSingleApplyAPI (even 1399 # though they're already in the list) 1400 "TestNestedInnerSingleApplyAPI", 1401 "TestSingleApplyAPI", 1402 "TestMultiApplyAPI:bar"] 1403 self.assertEqual(outerSinglePrim.GetAppliedSchemas(), 1404 expectedAPISchemas) 1405 1406 # The properties list and attribute values haven't changed though 1407 # because no actual new API schemas were added and the strength order 1408 # of the APIs haven't changed. 1409 self.assertEqual(outerSinglePrim.GetPropertyNames(), expectedPropNames) 1410 _VerifyAttrValues(outerSinglePrim, expectedAttrValues) 1411 1412 # Now let's swap the order of these two APIs so that the inner comes 1413 # before the outer. 1414 outerSinglePrim.RemoveAPI(self.NestedOuterSingleApplyAPIType) 1415 outerSinglePrim.ApplyAPI(self.NestedOuterSingleApplyAPIType) 1416 self.assertEqual(outerSinglePrim.GetPrimTypeInfo().GetAppliedAPISchemas(), 1417 ["TestNestedInnerSingleApplyAPI", 1418 "TestNestedOuterSingleApplyAPI"]) 1419 1420 # The order of the expanded API schemas has now changed too. 1421 expectedAPISchemas = [ 1422 # API schemas from expanded TestNestedInnerSingleApplyAPI 1423 "TestNestedInnerSingleApplyAPI", 1424 "TestSingleApplyAPI", 1425 "TestMultiApplyAPI:bar", 1426 # API schemas from expanded TestNestedOuterSingleApplyAPI 1427 "TestNestedOuterSingleApplyAPI", 1428 "TestMultiApplyAPI:foo", 1429 "TestNestedInnerSingleApplyAPI", 1430 "TestSingleApplyAPI", 1431 "TestMultiApplyAPI:bar"] 1432 self.assertEqual(outerSinglePrim.GetAppliedSchemas(), 1433 expectedAPISchemas) 1434 1435 # Once again The properties list doesn't change. 1436 self.assertEqual(outerSinglePrim.GetPropertyNames(), expectedPropNames) 1437 # However, the attribute value for single:token_attr has changed 1438 # because the override from TestNestedOuterSingleApplyAPI is no longer 1439 # stronger than the value from TestSingleApplyAPI as the first instance 1440 # of TestSingleApplyAPI now comes before it. 1441 expectedAttrValues["single:token_attr"] = "bar" 1442 _VerifyAttrValues(outerSinglePrim, expectedAttrValues) 1443 1444 1445 def test_NestedCycleAPISchema(self): 1446 """ 1447 Tests the application of API schemas that have nested built-in API 1448 schemas that would cause an inclusion cycle 1449 """ 1450 stage = Usd.Stage.CreateInMemory() 1451 1452 # Simple helper for testing that a prim has expected attributes that 1453 # resolve to expected values. 1454 def _VerifyAttrValues(prim, expectedAttrValues): 1455 values = {name : prim.GetAttribute(name).Get() 1456 for name in expectedAttrValues.keys()} 1457 self.assertEqual(values, expectedAttrValues) 1458 1459 # Test behavior when nested API schema form a cycle. In this example 1460 # TestNestedCycle1API includes TestNestedCycle2API which includes 1461 # TestNestedCycle3API which includes TestNestedCycle1API again. Create 1462 # three prims, each applying one of the API schemas. 1463 nestedCyclePrim1 = stage.DefinePrim("/Cycle1") 1464 nestedCyclePrim2 = stage.DefinePrim("/Cycle2") 1465 nestedCyclePrim3 = stage.DefinePrim("/Cycle3") 1466 nestedCyclePrim1.ApplyAPI(self.NestedCycle1APIType) 1467 nestedCyclePrim2.ApplyAPI(self.NestedCycle2APIType) 1468 nestedCyclePrim3.ApplyAPI(self.NestedCycle3APIType) 1469 1470 # For each prim the authored applied API schemas for the prim are still 1471 # only the single API that was applied. 1472 self.assertEqual(nestedCyclePrim1.GetPrimTypeInfo().GetTypeName(), '') 1473 self.assertEqual(nestedCyclePrim1.GetPrimTypeInfo().GetAppliedAPISchemas(), 1474 ["TestNestedCycle1API"]) 1475 self.assertEqual(nestedCyclePrim2.GetPrimTypeInfo().GetTypeName(), '') 1476 self.assertEqual(nestedCyclePrim2.GetPrimTypeInfo().GetAppliedAPISchemas(), 1477 ["TestNestedCycle2API"]) 1478 self.assertEqual(nestedCyclePrim3.GetPrimTypeInfo().GetTypeName(), '') 1479 self.assertEqual(nestedCyclePrim3.GetPrimTypeInfo().GetAppliedAPISchemas(), 1480 ["TestNestedCycle3API"]) 1481 1482 # The composed applied API schemas all contain all three API schemas, 1483 # however the order is different based on which schema was actually 1484 # the authored one. Note that during API schema expansion we don't try 1485 # to include the same API schema more than once which allows us to 1486 # handle cycles in this way. 1487 self.assertEqual(nestedCyclePrim1.GetTypeName(), '') 1488 self.assertEqual(nestedCyclePrim1.GetAppliedSchemas(), [ 1489 "TestNestedCycle1API", 1490 "TestNestedCycle2API", 1491 "TestNestedCycle3API"]) 1492 self.assertEqual(nestedCyclePrim2.GetTypeName(), '') 1493 self.assertEqual(nestedCyclePrim2.GetAppliedSchemas(), [ 1494 "TestNestedCycle2API", 1495 "TestNestedCycle3API", 1496 "TestNestedCycle1API"]) 1497 self.assertEqual(nestedCyclePrim3.GetTypeName(), '') 1498 self.assertEqual(nestedCyclePrim3.GetAppliedSchemas(), [ 1499 "TestNestedCycle3API", 1500 "TestNestedCycle1API", 1501 "TestNestedCycle2API"]) 1502 # All three prims "has" all three built-in APIs as well. 1503 self.assertTrue(nestedCyclePrim1.HasAPI(self.NestedCycle1APIType)) 1504 self.assertTrue(nestedCyclePrim1.HasAPI(self.NestedCycle2APIType)) 1505 self.assertTrue(nestedCyclePrim1.HasAPI(self.NestedCycle3APIType)) 1506 1507 self.assertTrue(nestedCyclePrim2.HasAPI(self.NestedCycle1APIType)) 1508 self.assertTrue(nestedCyclePrim2.HasAPI(self.NestedCycle2APIType)) 1509 self.assertTrue(nestedCyclePrim2.HasAPI(self.NestedCycle3APIType)) 1510 1511 self.assertTrue(nestedCyclePrim3.HasAPI(self.NestedCycle1APIType)) 1512 self.assertTrue(nestedCyclePrim3.HasAPI(self.NestedCycle2APIType)) 1513 self.assertTrue(nestedCyclePrim3.HasAPI(self.NestedCycle3APIType)) 1514 1515 # All three prims have all the same properties since they all have all 1516 # three API schemas applied. 1517 expectedPropNames = [ 1518 "cycle1:token_attr", 1519 "cycle2:token_attr", 1520 "cycle3:token_attr", 1521 "cycle:int_attr"] 1522 self.assertEqual(nestedCyclePrim1.GetPropertyNames(), expectedPropNames) 1523 self.assertEqual(nestedCyclePrim2.GetPropertyNames(), expectedPropNames) 1524 self.assertEqual(nestedCyclePrim3.GetPropertyNames(), expectedPropNames) 1525 1526 # For the three token attributes, each is only defined in its respective 1527 # API schema so they have the same fallback in each prim. 1528 # 'cycle:int_attr' is defined in all three of the cycle API schemas but 1529 # with different default values. Here the order of the applied schemas 1530 # matters and the strongest applied API's value wins. 1531 expectedAttrValues = { 1532 "cycle1:token_attr" : "cycle1", 1533 "cycle2:token_attr" : "cycle2", 1534 "cycle3:token_attr" : "cycle3"} 1535 expectedAttrValues["cycle:int_attr"] = 1 1536 _VerifyAttrValues(nestedCyclePrim1, expectedAttrValues) 1537 expectedAttrValues["cycle:int_attr"] = 2 1538 _VerifyAttrValues(nestedCyclePrim2, expectedAttrValues) 1539 expectedAttrValues["cycle:int_attr"] = 3 1540 _VerifyAttrValues(nestedCyclePrim3, expectedAttrValues) 1541 1542 # Get the prim definitions for each of these API schemas and verify its 1543 # applied API schemas and properties match what was imparted on the 1544 # prims. 1545 cycle1APIDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition( 1546 "TestNestedCycle1API") 1547 self.assertTrue(cycle1APIDef) 1548 self.assertEqual(cycle1APIDef.GetAppliedAPISchemas(), 1549 ["TestNestedCycle1API", 1550 "TestNestedCycle2API", 1551 "TestNestedCycle3API"]) 1552 self.assertEqual(sorted(cycle1APIDef.GetPropertyNames()), 1553 expectedPropNames) 1554 self.assertEqual(cycle1APIDef.GetDocumentation(), 1555 "Test nested single apply API schema with a cycle #1") 1556 1557 cycle2APIDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition( 1558 "TestNestedCycle2API") 1559 self.assertTrue(cycle2APIDef) 1560 self.assertEqual(cycle2APIDef.GetAppliedAPISchemas(), 1561 ["TestNestedCycle2API", 1562 "TestNestedCycle3API", 1563 "TestNestedCycle1API"]) 1564 self.assertEqual(sorted(cycle2APIDef.GetPropertyNames()), 1565 expectedPropNames) 1566 self.assertEqual(cycle2APIDef.GetDocumentation(), 1567 "Test nested single apply API schema with a cycle #2") 1568 1569 cycle3APIDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition( 1570 "TestNestedCycle3API") 1571 self.assertTrue(cycle3APIDef) 1572 self.assertEqual(cycle3APIDef.GetAppliedAPISchemas(), 1573 ["TestNestedCycle3API", 1574 "TestNestedCycle1API", 1575 "TestNestedCycle2API"]) 1576 self.assertEqual(sorted(cycle3APIDef.GetPropertyNames()), 1577 expectedPropNames) 1578 self.assertEqual(cycle3APIDef.GetDocumentation(), 1579 "Test nested single apply API schema with a cycle #3") 1580 1581 def test_ConcreteTypeWithBuiltinNestedAPISchemas(self): 1582 """ 1583 Tests a concrete schema type with built-in API schemas that include 1584 other API schemas. 1585 """ 1586 stage = Usd.Stage.CreateInMemory() 1587 1588 # Simple helper for testing that a prim has expected attributes that 1589 # resolve to expected values. 1590 def _VerifyAttrValues(prim, expectedAttrValues): 1591 values = {name : prim.GetAttribute(name).Get() 1592 for name in expectedAttrValues.keys()} 1593 self.assertEqual(values, expectedAttrValues) 1594 1595 # Test a typed prim whose concrete typed schema has built-in API schemas 1596 # that nest other API schemas. 1597 typedPrim = stage.DefinePrim( 1598 "/TypedPrim", "TestWithBuiltinNestedAppliedSchema") 1599 1600 # The prim has a type but no authored API schemas. 1601 self.assertEqual(typedPrim.GetPrimTypeInfo().GetTypeName(), 1602 "TestWithBuiltinNestedAppliedSchema") 1603 self.assertEqual(typedPrim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 1604 1605 # The composed API schemas are fully expanded from the two built-in API 1606 # schemas of the TestWithBuiltinNestedAppliedSchema type. 1607 expectedAPISchemas = [ 1608 # Expanded API schemas from built-in TestNestedOuterSingleApplyAPI 1609 "TestNestedOuterSingleApplyAPI", 1610 "TestMultiApplyAPI:foo", 1611 "TestNestedInnerSingleApplyAPI", 1612 "TestSingleApplyAPI", 1613 "TestMultiApplyAPI:bar", 1614 # Expanded API schemas from built-in TestNestedCycle1API 1615 "TestNestedCycle1API", 1616 "TestNestedCycle2API", 1617 "TestNestedCycle3API"] 1618 self.assertEqual(typedPrim.GetAppliedSchemas(), 1619 expectedAPISchemas) 1620 1621 # Properties come from the type and all composed built-in APIs 1622 expectedPropNames = [ 1623 # Properties from expanded built-in TestNestedCycle1API 1624 "cycle1:token_attr", 1625 "cycle2:token_attr", 1626 "cycle3:token_attr", 1627 "cycle:int_attr", 1628 # Properties from expanded built-in TestNestedOuterSingleApplyAPI 1629 "innerSingle:int_attr", 1630 "innerSingle:relationship", 1631 "innerSingle:token_attr", 1632 "multi:bar:bool_attr", 1633 "multi:bar:relationship", 1634 "multi:bar:token_attr", 1635 "multi:foo:bool_attr", 1636 "multi:foo:relationship", 1637 "multi:foo:token_attr", 1638 "outerSingle:int_attr", 1639 "outerSingle:relationship", 1640 "outerSingle:token_attr", 1641 "single:bool_attr", 1642 "single:relationship", 1643 "single:token_attr", 1644 # Properties from the prim type TestWithBuiltinNestedAppliedSchema 1645 "testAttr", 1646 "testRel"] 1647 self.assertEqual(typedPrim.GetPropertyNames(), expectedPropNames) 1648 1649 # Get the prim definition for the concrete typed schema and verify its 1650 # applied API schemas and properties match what was imparted on the 1651 # prim. 1652 typedPrimDef = \ 1653 Usd.SchemaRegistry().FindConcretePrimDefinition( 1654 "TestWithBuiltinNestedAppliedSchema") 1655 self.assertTrue(typedPrimDef) 1656 self.assertEqual(typedPrimDef.GetAppliedAPISchemas(), 1657 expectedAPISchemas) 1658 self.assertEqual(sorted(typedPrimDef.GetPropertyNames()), 1659 expectedPropNames) 1660 self.assertEqual(typedPrimDef.GetDocumentation(), 1661 "Test with built-in nested API schemas") 1662 1663 @unittest.skipIf(Tf.GetEnvSetting('USD_DISABLE_AUTO_APPLY_API_SCHEMAS'), 1664 "Auto apply API schemas are disabled") 1665 def test_APISchemasAutoAppliedToAPISchemas(self): 1666 """ 1667 Tests the behaviors of API schemas that are auto applied to other API 1668 schemas. 1669 """ 1670 stage = Usd.Stage.CreateInMemory() 1671 1672 # Define a prim with an empty type name and apply TestAutoAppliedToAPI. 1673 # TestAutoAppliedToAPI includes other API schemas through a combination 1674 # of built-in APIs and auto applied APIs. 1675 prim = stage.DefinePrim("/Prim") 1676 prim.ApplyAPI(self.AutoAppliedToAPIType) 1677 self.assertEqual(prim.GetTypeName(), '') 1678 self.assertEqual(prim.GetAppliedSchemas(), [ 1679 # Authored applied API 1680 "TestAutoAppliedToAPI", 1681 # Built-in API of 'TestAutoAppliedToAPI' 1682 "TestMultiApplyAPI:builtin", 1683 # Defined in plugin metadata that 'TestMultiApplyAPI:autoFoo' auto 1684 # applies to 'TestAutoAppliedToAPI' 1685 "TestMultiApplyAPI:autoFoo", 1686 # 'TestSingleApplyAPI' defines in its schema def that it auto 1687 # applies to 'TestAutoAppliedToAPI' 1688 "TestSingleApplyAPI"]) 1689 self.assertTrue(prim.HasAPI(self.AutoAppliedToAPIType)) 1690 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "builtin")) 1691 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "autoFoo")) 1692 self.assertTrue(prim.HasAPI(self.SingleApplyAPIType)) 1693 1694 # Prim's authored type is empty and its authored API schemas is just the 1695 # single authored schema. 1696 self.assertEqual(prim.GetPrimTypeInfo().GetTypeName(), '') 1697 self.assertEqual(prim.GetPrimTypeInfo().GetAppliedAPISchemas(), 1698 ["TestAutoAppliedToAPI"]) 1699 1700 # Prim's built-in properties come from all of the applied API schemas. 1701 self.assertEqual(prim.GetPropertyNames(), [ 1702 "multi:autoFoo:bool_attr", 1703 "multi:autoFoo:relationship", 1704 "multi:autoFoo:token_attr", 1705 "multi:builtin:bool_attr", 1706 "multi:builtin:relationship", 1707 "multi:builtin:token_attr", 1708 "single:bool_attr", 1709 "single:relationship", 1710 "single:token_attr", 1711 "testAttr", 1712 "testRel"]) 1713 1714 # Define a prim with an empty type name and apply 1715 # TestNestedAutoAppliedToAPI. 1716 # TestAutoAppliedToAPI auto applies to TestNestedAutoAppliedToAPI and 1717 # brings with it all of the API schemas that are built-in to it and auto 1718 # applied to it. 1719 prim = stage.DefinePrim("/Prim2") 1720 prim.ApplyAPI(self.NestedAutoAppliedToAPIType) 1721 self.assertEqual(prim.GetTypeName(), '') 1722 self.assertEqual(prim.GetAppliedSchemas(), [ 1723 # Authored applied API 1724 "TestNestedAutoAppliedToAPI", 1725 # Built-in API of 'TestNestedAutoAppliedToAPI' 1726 "TestMultiApplyAPI:foo", 1727 # 'TestAutoAppliedToAPI' defines in its schema def that it auto 1728 # applies to 'TestNestedAutoAppliedToAPI' 1729 "TestAutoAppliedToAPI", 1730 # Built-in API of 'TestAutoAppliedToAPI' 1731 "TestMultiApplyAPI:builtin", 1732 # Defined in plugin metadata that 'TestMultiApplyAPI:autoFoo' auto 1733 # applies to 'TestAutoAppliedToAPI' 1734 "TestMultiApplyAPI:autoFoo", 1735 # 'TestSingleApplyAPI' defines in its schema def that it auto 1736 # applies to 'TestAutoAppliedToAPI' 1737 "TestSingleApplyAPI"]) 1738 self.assertTrue(prim.HasAPI(self.NestedAutoAppliedToAPIType)) 1739 self.assertTrue(prim.HasAPI(self.AutoAppliedToAPIType)) 1740 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "foo")) 1741 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "builtin")) 1742 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "autoFoo")) 1743 self.assertTrue(prim.HasAPI(self.SingleApplyAPIType)) 1744 1745 # Prim's authored type is empty and its authored API schemas is just the 1746 # single authored schema. 1747 self.assertEqual(prim.GetPrimTypeInfo().GetTypeName(), '') 1748 self.assertEqual(prim.GetPrimTypeInfo().GetAppliedAPISchemas(), 1749 ["TestNestedAutoAppliedToAPI"]) 1750 1751 # Prim's built-in properties come from all of the applied API schemas. 1752 self.assertEqual(prim.GetPropertyNames(), [ 1753 "multi:autoFoo:bool_attr", 1754 "multi:autoFoo:relationship", 1755 "multi:autoFoo:token_attr", 1756 "multi:builtin:bool_attr", 1757 "multi:builtin:relationship", 1758 "multi:builtin:token_attr", 1759 "multi:foo:bool_attr", 1760 "multi:foo:relationship", 1761 "multi:foo:token_attr", 1762 "single:bool_attr", 1763 "single:relationship", 1764 "single:token_attr", 1765 "testAttr", 1766 "testRel"]) 1767 1768 # Define a prim with type name TestNestedAutoAppliedToAPIAppliedToPrim. 1769 # TestNestedAutoAppliedToAPI is defined to auto apply to this prim type 1770 # and brings with it all of the API schemas that are built-in to it and 1771 # auto applied to it. 1772 prim = stage.DefinePrim("/Prim3", 1773 "TestNestedAutoAppliedToAPIAppliedToPrim") 1774 self.assertEqual(prim.GetTypeName(), 1775 'TestNestedAutoAppliedToAPIAppliedToPrim') 1776 self.assertEqual(prim.GetAppliedSchemas(), [ 1777 # 'TestNestedAutoAppliedToAPI' defines in its schema def that it 1778 # auto applies to 'TestNestedAutoAppliedToAPIAppliedToPrim' 1779 "TestNestedAutoAppliedToAPI", 1780 # Built-in API of 'TestNestedAutoAppliedToAPI' 1781 "TestMultiApplyAPI:foo", 1782 # 'TestAutoAppliedToAPI' defines in its schema def that it auto 1783 # applies to 'TestNestedAutoAppliedToAPI' 1784 "TestAutoAppliedToAPI", 1785 # Built-in API of 'TestAutoAppliedToAPI' 1786 "TestMultiApplyAPI:builtin", 1787 # Defined in plugin metadata that 'TestMultiApplyAPI:autoFoo' auto 1788 # applies to 'TestAutoAppliedToAPI' 1789 "TestMultiApplyAPI:autoFoo", 1790 # 'TestSingleApplyAPI' defines in its schema def that it auto 1791 # applies to 'TestAutoAppliedToAPI' 1792 "TestSingleApplyAPI"]) 1793 1794 # Prim's authored applied API schemas is empty as the API schemas are 1795 # part of the type (through auto apply). 1796 self.assertEqual(prim.GetPrimTypeInfo().GetTypeName(), 1797 'TestNestedAutoAppliedToAPIAppliedToPrim') 1798 self.assertEqual(prim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 1799 1800 # Prim's built-in properties come from all of the applied API schemas. 1801 self.assertTrue(prim.HasAPI(self.NestedAutoAppliedToAPIType)) 1802 self.assertTrue(prim.HasAPI(self.AutoAppliedToAPIType)) 1803 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "foo")) 1804 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "builtin")) 1805 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "autoFoo")) 1806 self.assertTrue(prim.HasAPI(self.SingleApplyAPIType)) 1807 self.assertEqual(prim.GetPropertyNames(), [ 1808 "multi:autoFoo:bool_attr", 1809 "multi:autoFoo:relationship", 1810 "multi:autoFoo:token_attr", 1811 "multi:builtin:bool_attr", 1812 "multi:builtin:relationship", 1813 "multi:builtin:token_attr", 1814 "multi:foo:bool_attr", 1815 "multi:foo:relationship", 1816 "multi:foo:token_attr", 1817 "single:bool_attr", 1818 "single:relationship", 1819 "single:token_attr", 1820 "testAttr", 1821 "testRel"]) 1822 1823 @unittest.skipIf(not Tf.GetEnvSetting('USD_DISABLE_AUTO_APPLY_API_SCHEMAS'), 1824 "Auto apply API schemas are NOT disabled") 1825 def test_APISchemasAutoAppliedToAPISchemas_AutoApplyDisabled(self): 1826 """ 1827 Tests the behaviors of API schemas that are auto applied to other API 1828 schemas. 1829 """ 1830 stage = Usd.Stage.CreateInMemory() 1831 1832 # Define a prim with an empty type name and apply TestAutoAppliedToAPI. 1833 # TestAutoAppliedAPI includes other API schemas through a combination of 1834 # built-in APIs and auto applied APIs. The auto applied schemas are 1835 # disabled in the this test case. 1836 prim = stage.DefinePrim("/Prim") 1837 prim.ApplyAPI(self.AutoAppliedToAPIType) 1838 self.assertEqual(prim.GetTypeName(), '') 1839 self.assertEqual(prim.GetAppliedSchemas(), [ 1840 # Authored applied API 1841 "TestAutoAppliedToAPI", 1842 # Built-in API of 'TestAutoAppliedToAPI' 1843 "TestMultiApplyAPI:builtin" 1844 # 'TestMultiApplyAPI:autoFoo' and 'TestSingleApplyAPI' would be 1845 # auto applied so they do not show up when auto apply is disabled 1846 ]) 1847 self.assertTrue(prim.HasAPI(self.AutoAppliedToAPIType)) 1848 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "builtin")) 1849 self.assertFalse(prim.HasAPI(self.MultiApplyAPIType, "autoFoo")) 1850 self.assertFalse(prim.HasAPI(self.SingleApplyAPIType)) 1851 1852 # Prim's authored type is empty and its authored API schemas is just the 1853 # single authored schema. 1854 self.assertEqual(prim.GetPrimTypeInfo().GetTypeName(), '') 1855 self.assertEqual(prim.GetPrimTypeInfo().GetAppliedAPISchemas(), 1856 ["TestAutoAppliedToAPI"]) 1857 1858 # Prim's built-in properties come from all of the applied API schemas. 1859 self.assertEqual(prim.GetPropertyNames(), [ 1860 "multi:builtin:bool_attr", 1861 "multi:builtin:relationship", 1862 "multi:builtin:token_attr", 1863 "testAttr", 1864 "testRel"]) 1865 1866 # Define a prim with an empty type name and apply 1867 # TestNestedAutoAppliedToAPI. 1868 # TestAutoAppliedAPI auto applies to TestNestedAutoAppliedToAPI but 1869 # auto apply is disabled in this test case. 1870 prim = stage.DefinePrim("/Prim2") 1871 prim.ApplyAPI(self.NestedAutoAppliedToAPIType) 1872 self.assertEqual(prim.GetTypeName(), '') 1873 self.assertEqual(prim.GetAppliedSchemas(), [ 1874 # Authored applied API 1875 "TestNestedAutoAppliedToAPI", 1876 # Built-in API of 'TestNestedAutoAppliedToAPI' 1877 "TestMultiApplyAPI:foo", 1878 # 'TestAutoAppliedToAPI' would be auto applied it doesn't show up 1879 # when auto apply is disabled, nor do any of the API schemas that 1880 # would be included by it. 1881 ]) 1882 self.assertTrue(prim.HasAPI(self.NestedAutoAppliedToAPIType)) 1883 self.assertFalse(prim.HasAPI(self.AutoAppliedToAPIType)) 1884 self.assertTrue(prim.HasAPI(self.MultiApplyAPIType, "foo")) 1885 self.assertFalse(prim.HasAPI(self.MultiApplyAPIType, "builtin")) 1886 self.assertFalse(prim.HasAPI(self.MultiApplyAPIType, "autoFoo")) 1887 self.assertFalse(prim.HasAPI(self.SingleApplyAPIType)) 1888 1889 # Prim's authored type is empty and its authored API schemas is just the 1890 # single authored schema. 1891 self.assertEqual(prim.GetPrimTypeInfo().GetTypeName(), '') 1892 self.assertEqual(prim.GetPrimTypeInfo().GetAppliedAPISchemas(), 1893 ["TestNestedAutoAppliedToAPI"]) 1894 1895 # Prim's built-in properties come from all of the applied API schemas. 1896 self.assertEqual(prim.GetPropertyNames(), [ 1897 "multi:foo:bool_attr", 1898 "multi:foo:relationship", 1899 "multi:foo:token_attr"]) 1900 1901 # Define a prim with type name TestNestedAutoAppliedToAPIAppliedToPrim. 1902 # TestNestedAutoAppliedToAPI is defined to auto apply to this prim type 1903 # auto apply is disabled in this test case. 1904 prim = stage.DefinePrim("/Prim3", 1905 "TestNestedAutoAppliedToAPIAppliedToPrim") 1906 self.assertEqual(prim.GetTypeName(), 1907 'TestNestedAutoAppliedToAPIAppliedToPrim') 1908 # 'TestNestedAutoAppliedToAPI' would be auto applied so it doesn't show 1909 # up when auto apply is disabled, nor do any of the API schemas that 1910 # would be included by it. 1911 self.assertEqual(prim.GetAppliedSchemas(), []) 1912 1913 self.assertEqual(prim.GetPrimTypeInfo().GetTypeName(), 1914 'TestNestedAutoAppliedToAPIAppliedToPrim') 1915 self.assertEqual(prim.GetPrimTypeInfo().GetAppliedAPISchemas(), []) 1916 self.assertEqual(prim.GetPropertyNames(), []) 1917 1918 1919if __name__ == "__main__": 1920 unittest.main() 1921