-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
… being done in wrapObject. This overloaded __getattribute__ actually allows any of the UsdSchemaBase APIs to be called (as all of the methods at this level can still return useful information). But its purpose is to block calls to APIs defined on subclasses. Provided similar protection for UsdGeomPrimvar, which is an odd case that is like a schema class, but operates on a single attribute and so is not derived from SchemaBase. Added some test cases, including an explicit test of issue PixarAnimationStudios#872, a crash when calling UsdGeom.Xformable().ClearXformOpOrder(). TestUsdRiSplineAPI had to be updated because a test in there was not expecting the RuntimeException from an invalid object.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#!/pxrpythonsubst | ||
# | ||
# Copyright 2017 Pixar | ||
This comment has been minimized.
Sorry, something went wrong. |
||
# | ||
# Licensed under the Apache License, Version 2.0 (the "Apache License") | ||
# with the following modification; you may not use this file except in | ||
# compliance with the Apache License and the following modification to it: | ||
# Section 6. Trademarks. is deleted and replaced with: | ||
# | ||
# 6. Trademarks. This License does not grant permission to use the trade | ||
# names, trademarks, service marks, or product names of the Licensor | ||
# and its affiliates, except as required to comply with Section 4(c) of | ||
# the License and to reproduce the content of the NOTICE file. | ||
# | ||
# You may obtain a copy of the Apache License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the Apache License with the above modification is | ||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the Apache License for the specific | ||
# language governing permissions and limitations under the Apache License. | ||
|
||
from pxr import Gf, Tf, Sdf, Usd, Vt | ||
import unittest, math | ||
|
||
class TestUsdSchemaBase(unittest.TestCase): | ||
|
||
def test_InvalidSchemaBase(self): | ||
sb = Usd.SchemaBase() | ||
# It should still be safe to get the prim, but the prim will be invalid. | ||
p = sb.GetPrim() | ||
with self.assertRaises(RuntimeError): | ||
p.IsActive() | ||
# It should still be safe to get the path, but the path will be empty. | ||
self.assertEqual(sb.GetPath(), Sdf.Path()) | ||
|
||
This comment has been minimized.
Sorry, something went wrong.
spiffmon
|
||
if __name__ == "__main__": | ||
unittest.main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,14 +102,40 @@ _GetTimeSamplesInInterval(const UsdGeomPrimvar &self, | |
|
||
static size_t __hash__(const UsdGeomPrimvar &self) { return hash_value(self); } | ||
|
||
// We override __getattribute__ for UsdGeomPrimvar to check object validity | ||
// and raise an exception instead of crashing from Python. | ||
|
||
// Store the original __getattribute__ so we can dispatch to it after verifying | ||
// validity. | ||
static TfStaticData<TfPyObjWrapper> _object__getattribute__; | ||
|
||
// This function gets wrapped as __getattribute__ on UsdGeomPrimvar. | ||
static object | ||
__getattribute__(object selfObj, const char *name) { | ||
// Allow attribute lookups if the attribute name starts with '__', or | ||
// if the object's prim is valid. | ||
if ((name[0] == '_' && name[1] == '_') || | ||
extract<UsdGeomPrimvar &>(selfObj)().GetAttr().GetPrim().IsValid() || | ||
This comment has been minimized.
Sorry, something went wrong.
spiffmon
|
||
strcmp(name, "GetAttr") == 0) { | ||
// Dispatch to object's __getattribute__. | ||
return (*_object__getattribute__)(selfObj, name); | ||
} else { | ||
// Otherwise raise a runtime error. | ||
TfPyThrowRuntimeError( | ||
TfStringPrintf("Accessed invalid attribute as a primvar")); | ||
} | ||
// Unreachable. | ||
return object(); | ||
} | ||
|
||
} // anonymous namespace | ||
|
||
void wrapUsdGeomPrimvar() | ||
{ | ||
typedef UsdGeomPrimvar Primvar; | ||
|
||
class_<Primvar>("Primvar") | ||
class_<Primvar> clsObj("Primvar"); | ||
clsObj | ||
.def(init<UsdAttribute>(arg("attr"))) | ||
|
||
.def(self == self) | ||
|
@@ -180,5 +206,9 @@ void wrapUsdGeomPrimvar() | |
to_python_converter<std::vector<UsdGeomPrimvar>, | ||
TfPySequenceToPython<std::vector<UsdGeomPrimvar>>>(); | ||
implicitly_convertible<Primvar, UsdAttribute>(); | ||
|
||
// Save existing __getattribute__ and replace. | ||
*_object__getattribute__ = object(clsObj.attr("__getattribute__")); | ||
clsObj.def("__getattribute__", __getattribute__); | ||
} | ||
|
1 comment
on commit 6670c46
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @marktucker - this is great. Just a few comments inline.
Can you update the date to 2019, please?