From 4f335ed1eba63d8628f1fe406abffe046ff71653 Mon Sep 17 00:00:00 2001 From: Marcelo Saguas Iacovone Date: Sat, 17 Feb 2024 10:37:53 -0800 Subject: [PATCH 1/8] Implements a different approach for __repr__ --- cmdx.py | 85 +++++++++++++++++++++++++++++++------------------------- tests.py | 3 +- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/cmdx.py b/cmdx.py index d592474..64f00d6 100644 --- a/cmdx.py +++ b/cmdx.py @@ -511,7 +511,7 @@ class Node(object): >>> transform = createNode("transform") >>> transform["tx"] = 5 >>> transform["worldMatrix"][0] >> decompose["inputMatrix"] - >>> decompose["outputTranslate"] + >>> decompose["outputTranslate"].read() (5.0, 0.0, 0.0) """ @@ -548,7 +548,8 @@ def __str__(self): return self.name(namespace=True) def __repr__(self): - return self.name(namespace=True) + cls_name = '{}.{}'.format(__name__, self.__class__.__name__) + return "<{} : '{}'>".format(cls_name, self.name(namespace=True)) def __add__(self, other): """Support legacy + '.attr' behavior @@ -578,7 +579,7 @@ def __getitem__(self, key): Example: >>> node = createNode("transform") >>> node["translate"] = (1, 1, 1) - >>> node["translate", Meters] + >>> node["translate", Meters].read() (0.01, 0.01, 0.01) """ @@ -624,7 +625,7 @@ def __setitem__(self, key, value): True >>> node["rotateX", Degrees] = 1.0 >>> node["rotateX"] = Degrees(1) - >>> node["rotateX", Degrees] + >>> node["rotateX", Degrees].read() 1.0 >>> node["myDist"] = Distance() >>> node["myDist"] = node["translateX"] @@ -980,7 +981,7 @@ def update(self, attrs): Examples: >>> node = createNode("transform") >>> node.update({"tx": 5.0, ("ry", Degrees): 30.0}) - >>> node["tx"] + >>> node["tx"].read() 5.0 """ @@ -998,14 +999,14 @@ def clear(self): Example: >>> node = createNode("transform") >>> node["translateX"] = 5 - >>> node["translateX"] + >>> node["translateX"].read() 5.0 >>> # Plug was reused - >>> node["translateX"] + >>> node["translateX"].read() 5.0 >>> # Value was reused >>> node.clear() - >>> node["translateX"] + >>> node["translateX"].read() 5.0 >>> # Plug and value was recomputed @@ -1513,7 +1514,8 @@ def __str__(self): return self.path() def __repr__(self): - return self.path() + cls_name = '{}.{}'.format(__name__, self.__class__.__name__) + return "<{} : '{}'>".format(cls_name, self.path()) def __or__(self, other): """Syntax sugar for finding a child @@ -1522,13 +1524,13 @@ def __or__(self, other): >>> _new() >>> parent = createNode("transform", "parent") >>> child = createNode("transform", "child", parent) - >>> parent | "child" - |parent|child + >>> (parent | "child").path() + '|parent|child' # Stackable too >>> grand = createNode("transform", "grand", child) - >>> parent | "child" | "grand" - |parent|child|grand + >>> (parent | "child" | "grand").path() + '|parent|child|grand' """ @@ -2301,8 +2303,8 @@ def flatten(self, type=None): >>> cc = cmds.sets([gc, b], name="child") >>> parent = cmds.sets([cc, c], name="parent") >>> mainset = encode(parent) - >>> sorted(mainset.flatten(), key=lambda n: n.name()) - [|a, |b, |c] + >>> sorted([n.path() for n in mainset.flatten()]) + ['|a', '|b', '|c'] """ @@ -2560,9 +2562,9 @@ def __add__(self, other): Example: >>> node = createNode("transform") >>> node["tx"] = 5 - >>> node["translate"] + "X" + >>> (node["translate"] + "X").read() 5.0 - >>> node["t"] + "x" + >>> (node["t"] + "x").read() 5.0 >>> try: ... node["t"] + node["r"] @@ -2597,11 +2599,11 @@ def __iadd__(self, other): >>> node["myArray"].extend([2.0, 3.0]) >>> node["myArray"] += 5.1 >>> node["myArray"] += [1.1, 2.3, 999.0] - >>> node["myArray"][0] + >>> node["myArray"][0].read() 1.0 - >>> node["myArray"][6] + >>> node["myArray"][6].read() 999.0 - >>> node["myArray"][-1] + >>> node["myArray"][-1].read() 999.0 """ @@ -2627,7 +2629,13 @@ def __str__(self): return str(self.read()) def __repr__(self): - return str(self.read()) + cls_name = '{}.{}'.format(__name__, self.__class__.__name__) + read_val = self.read() + if isinstance(read_val, string_types): + # Add surrounding single quotes, indicating the value is a string + read_val = "'{}'".format(read_val) + + return "<{} : {}>".format(cls_name, read_val) def __rshift__(self, other): """Support connecting attributes via A >> B""" @@ -2798,7 +2806,7 @@ def __setitem__(self, index, value): Example: >>> node = createNode("transform") >>> node["translate"][0] = 5 - >>> node["tx"] + >>> node["tx"].read() 5.0 """ @@ -3173,9 +3181,9 @@ def extend(self, values): >>> node = createNode("transform") >>> node["myArray"] = Double(array=True) >>> node["myArray"].extend([1.0, 2.0, 3.0]) - >>> node["myArray"][0] + >>> node["myArray"][0].read() 1.0 - >>> node["myArray"][-1] + >>> node["myArray"][-1].read() 3.0 """ @@ -4101,7 +4109,7 @@ def connections(self, True >>> b["ihi"].connection() == a True - >>> a["ihi"] + >>> a["ihi"].read() 2 >>> b["arrayAttr"] = Long(array=True) >>> b["arrayAttr"][0] >> a["ihi"] @@ -6350,16 +6358,16 @@ def connect(self, src, dst, force=True): >>> with DagModifier() as mod: ... mod.connect(tm["sx"], tm["tx"]) ... - >>> tm["tx"].connection() - |myTransform + >>> tm["tx"].connection().path() + '|myTransform' >>> cmds.undo() >>> tm["tx"].connection() is None True # Connect without undo >>> tm["tx"] << tx["output"] - >>> tm["tx"].connection() - myAnimCurve + >>> tm["tx"].connection().name() + 'myAnimCurve' # Disconnect without undo >>> tm["tx"] // tx["output"] @@ -6444,12 +6452,12 @@ def connectAttr(self, srcPlug, dstNode, dstAttr): ... otherAttr = mod.addAttr(otherNode, Message("otherAttr")) ... mod.connectAttr(newNode["newAttr"], otherNode, otherAttr) ... - >>> newNode["newAttr"].connection() - |otherNode + >>> newNode["newAttr"].connection().path() + '|otherNode' >>> cmds.undo() - >>> newNode["newAttr"].connection() - |newNode + >>> newNode["newAttr"].connection().path() + '|newNode' """ @@ -6768,9 +6776,9 @@ class DagModifier(_BaseModifier): ... >>> getAttr(node1 + ".translateX") 1.0 - >>> node2["translate"][0] + >>> node2["translate"][0].read() 1.0 - >>> node2["translate"][1] + >>> node2["translate"][1].read() 2.0 >>> with DagModifier() as mod: ... node1 = mod.createNode("transform") @@ -6778,9 +6786,9 @@ class DagModifier(_BaseModifier): ... node1["translate"] = (5, 6, 7) ... node1["translate"] >> node2["translate"] ... - >>> node2["translate"][0] + >>> node2["translate"][0].read() 5.0 - >>> node2["translate"][1] + >>> node2["translate"][1].read() 6.0 Example, without context manager: @@ -7721,7 +7729,8 @@ def __hash__(self): def __repr__(self): """Avoid repr depicting the full contents of this dict""" - return self["name"] + cls_name = '{}.{}'.format(__name__, self.__class__.__name__) + return "<{} : '{}'>".format(cls_name, self["name"]) def __new__(cls, *args, **kwargs): """Support for using name of assignment diff --git a/tests.py b/tests.py index 73ccac6..7f7834f 100644 --- a/tests.py +++ b/tests.py @@ -383,8 +383,9 @@ def test_nodeoperators(): node = cmdx.createNode(cmdx.tTransform, name="myNode") assert_equals(node, "|myNode") + assert_equals(repr(node), "") assert_not_equals(node, "|NotEquals") - assert_equals(str(node), repr(node)) + assert_not_equals(str(node), repr(node)) @with_setup(new_scene) From 5d8a033f7610be6f1c20460e9cfda070ba5684b6 Mon Sep 17 00:00:00 2001 From: Marcelo Saguas Iacovone Date: Sat, 17 Feb 2024 13:02:18 -0800 Subject: [PATCH 2/8] Fixes Python2.7 compatibility for doctests --- cmdx.py | 57 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/cmdx.py b/cmdx.py index 64f00d6..49923bb 100644 --- a/cmdx.py +++ b/cmdx.py @@ -1524,13 +1524,21 @@ def __or__(self, other): >>> _new() >>> parent = createNode("transform", "parent") >>> child = createNode("transform", "child", parent) - >>> (parent | "child").path() - '|parent|child' + >>> result = (parent | "child").path() + >>> result in ( + ... '|parent|child', + ... u'|parent|child' + ... ) + True # Stackable too >>> grand = createNode("transform", "grand", child) - >>> (parent | "child" | "grand").path() - '|parent|child|grand' + >>> result = (parent | "child" | "grand").path() + >>> result in ( + ... '|parent|child|grand', + ... u'|parent|child|grand' + ... ) + True """ @@ -2303,8 +2311,12 @@ def flatten(self, type=None): >>> cc = cmds.sets([gc, b], name="child") >>> parent = cmds.sets([cc, c], name="parent") >>> mainset = encode(parent) - >>> sorted([n.path() for n in mainset.flatten()]) - ['|a', '|b', '|c'] + >>> result = sorted([n.path() for n in mainset.flatten()]) + >>> result in ( + ... ['|a', '|b', '|c'], + ... [u'|a', u'|b', u'|c'] + ... ) + True """ @@ -6358,16 +6370,25 @@ def connect(self, src, dst, force=True): >>> with DagModifier() as mod: ... mod.connect(tm["sx"], tm["tx"]) ... - >>> tm["tx"].connection().path() - '|myTransform' + >>> result = tm["tx"].connection().path() + >>> result in ( + ... '|myTransform', + ... u'|myTransform' + ... ) + True + >>> cmds.undo() >>> tm["tx"].connection() is None True # Connect without undo >>> tm["tx"] << tx["output"] - >>> tm["tx"].connection().name() - 'myAnimCurve' + >>> result = tm["tx"].connection().name() + >>> result in ( + ... 'myAnimCurve', + ... u'myAnimCurve' + ... ) + True # Disconnect without undo >>> tm["tx"] // tx["output"] @@ -6452,12 +6473,20 @@ def connectAttr(self, srcPlug, dstNode, dstAttr): ... otherAttr = mod.addAttr(otherNode, Message("otherAttr")) ... mod.connectAttr(newNode["newAttr"], otherNode, otherAttr) ... - >>> newNode["newAttr"].connection().path() - '|otherNode' + >>> result = newNode["newAttr"].connection().path() + >>> result in ( + ... '|otherNode', + ... u'|otherNode' + ... ) + True >>> cmds.undo() - >>> newNode["newAttr"].connection().path() - '|newNode' + >>> result = newNode["newAttr"].connection().path() + >>> result in ( + ... '|newNode', + ... u'|newNode' + ... ) + True """ From eb98987634267acd3b35ac6c6226cab215d3a85b Mon Sep 17 00:00:00 2001 From: Marcelo Saguas Iacovone Date: Sun, 18 Feb 2024 10:48:49 -0800 Subject: [PATCH 3/8] Reimplements old doctests without .name(), .path() and .read() --- cmdx.py | 104 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 28 deletions(-) diff --git a/cmdx.py b/cmdx.py index 49923bb..b2e633f 100644 --- a/cmdx.py +++ b/cmdx.py @@ -511,6 +511,8 @@ class Node(object): >>> transform = createNode("transform") >>> transform["tx"] = 5 >>> transform["worldMatrix"][0] >> decompose["inputMatrix"] + >>> decompose["outputTranslate"] + >>> decompose["outputTranslate"].read() (5.0, 0.0, 0.0) @@ -579,6 +581,8 @@ def __getitem__(self, key): Example: >>> node = createNode("transform") >>> node["translate"] = (1, 1, 1) + >>> node["translate", Meters] + >>> node["translate", Meters].read() (0.01, 0.01, 0.01) @@ -625,6 +629,8 @@ def __setitem__(self, key, value): True >>> node["rotateX", Degrees] = 1.0 >>> node["rotateX"] = Degrees(1) + >>> node["rotateX", Degrees] + >>> node["rotateX", Degrees].read() 1.0 >>> node["myDist"] = Distance() @@ -981,6 +987,8 @@ def update(self, attrs): Examples: >>> node = createNode("transform") >>> node.update({"tx": 5.0, ("ry", Degrees): 30.0}) + >>> node["tx"] + >>> node["tx"].read() 5.0 @@ -999,13 +1007,19 @@ def clear(self): Example: >>> node = createNode("transform") >>> node["translateX"] = 5 + >>> node["translateX"] + >>> node["translateX"].read() 5.0 >>> # Plug was reused + >>> node["translateX"] + >>> node["translateX"].read() 5.0 >>> # Value was reused >>> node.clear() + >>> node["translateX"] + >>> node["translateX"].read() 5.0 >>> # Plug and value was recomputed @@ -1524,8 +1538,9 @@ def __or__(self, other): >>> _new() >>> parent = createNode("transform", "parent") >>> child = createNode("transform", "child", parent) - >>> result = (parent | "child").path() - >>> result in ( + >>> parent | "child" + + >>> (parent | "child").path() in ( ... '|parent|child', ... u'|parent|child' ... ) @@ -1533,8 +1548,9 @@ def __or__(self, other): # Stackable too >>> grand = createNode("transform", "grand", child) - >>> result = (parent | "child" | "grand").path() - >>> result in ( + >>> parent | "child" | "grand" + + >>> (parent | "child" | "grand").path() in ( ... '|parent|child|grand', ... u'|parent|child|grand' ... ) @@ -2301,22 +2317,24 @@ def flatten(self, type=None): """Return members, converting nested object sets into its members Example: - >>> from maya import cmds - >>> _ = cmds.file(new=True, force=True) - >>> a = cmds.createNode("transform", name="a") - >>> b = cmds.createNode("transform", name="b") - >>> c = cmds.createNode("transform", name="c") - >>> cmds.select(a) - >>> gc = cmds.sets([a], name="grandchild") - >>> cc = cmds.sets([gc, b], name="child") - >>> parent = cmds.sets([cc, c], name="parent") - >>> mainset = encode(parent) - >>> result = sorted([n.path() for n in mainset.flatten()]) - >>> result in ( - ... ['|a', '|b', '|c'], - ... [u'|a', u'|b', u'|c'] - ... ) - True + >>> from maya import cmds + >>> _ = cmds.file(new=True, force=True) + >>> a = cmds.createNode("transform", name="a") + >>> b = cmds.createNode("transform", name="b") + >>> c = cmds.createNode("transform", name="c") + >>> cmds.select(a) + >>> gc = cmds.sets([a], name="grandchild") + >>> cc = cmds.sets([gc, b], name="child") + >>> parent = cmds.sets([cc, c], name="parent") + >>> mainset = encode(parent) + >>> sorted(mainset.flatten(), key=lambda n: n.name()) + [, , ] + >>> result = sorted([n.name() for n in mainset.flatten()]) + >>> result in ( + ... ['a', 'b', 'c'], + ... [u'a', u'b', u'c'] + ... ) + True """ @@ -2574,8 +2592,12 @@ def __add__(self, other): Example: >>> node = createNode("transform") >>> node["tx"] = 5 + >>> node["translate"] + "X" + >>> (node["translate"] + "X").read() 5.0 + >>> node["t"] + "x" + >>> (node["t"] + "x").read() 5.0 >>> try: @@ -2611,10 +2633,16 @@ def __iadd__(self, other): >>> node["myArray"].extend([2.0, 3.0]) >>> node["myArray"] += 5.1 >>> node["myArray"] += [1.1, 2.3, 999.0] + >>> node["myArray"][0] + >>> node["myArray"][0].read() 1.0 + >>> node["myArray"][6] + >>> node["myArray"][6].read() 999.0 + >>> node["myArray"][-1] + >>> node["myArray"][-1].read() 999.0 @@ -2818,6 +2846,8 @@ def __setitem__(self, index, value): Example: >>> node = createNode("transform") >>> node["translate"][0] = 5 + >>> node["tx"] + >>> node["tx"].read() 5.0 @@ -3193,8 +3223,12 @@ def extend(self, values): >>> node = createNode("transform") >>> node["myArray"] = Double(array=True) >>> node["myArray"].extend([1.0, 2.0, 3.0]) + >>> node["myArray"][0] + >>> node["myArray"][0].read() 1.0 + >>> node["myArray"][-1] + >>> node["myArray"][-1].read() 3.0 @@ -4121,6 +4155,8 @@ def connections(self, True >>> b["ihi"].connection() == a True + >>> a["ihi"] + >>> a["ihi"].read() 2 >>> b["arrayAttr"] = Long(array=True) @@ -6370,8 +6406,9 @@ def connect(self, src, dst, force=True): >>> with DagModifier() as mod: ... mod.connect(tm["sx"], tm["tx"]) ... - >>> result = tm["tx"].connection().path() - >>> result in ( + >>> tm["tx"].connection() + + >>> tm["tx"].connection().path() in ( ... '|myTransform', ... u'|myTransform' ... ) @@ -6383,8 +6420,9 @@ def connect(self, src, dst, force=True): # Connect without undo >>> tm["tx"] << tx["output"] - >>> result = tm["tx"].connection().name() - >>> result in ( + >>> tm["tx"].connection() + + >>> tm["tx"].connection().name() in ( ... 'myAnimCurve', ... u'myAnimCurve' ... ) @@ -6473,16 +6511,18 @@ def connectAttr(self, srcPlug, dstNode, dstAttr): ... otherAttr = mod.addAttr(otherNode, Message("otherAttr")) ... mod.connectAttr(newNode["newAttr"], otherNode, otherAttr) ... - >>> result = newNode["newAttr"].connection().path() - >>> result in ( + >>> newNode["newAttr"].connection() + + >>> newNode["newAttr"].connection().path() in ( ... '|otherNode', ... u'|otherNode' ... ) True >>> cmds.undo() - >>> result = newNode["newAttr"].connection().path() - >>> result in ( + >>> newNode["newAttr"].connection() + + >>> newNode["newAttr"].connection().path() in ( ... '|newNode', ... u'|newNode' ... ) @@ -6805,8 +6845,12 @@ class DagModifier(_BaseModifier): ... >>> getAttr(node1 + ".translateX") 1.0 + >>> node2["translate"][0] + >>> node2["translate"][0].read() 1.0 + >>> node2["translate"][1] + >>> node2["translate"][1].read() 2.0 >>> with DagModifier() as mod: @@ -6815,8 +6859,12 @@ class DagModifier(_BaseModifier): ... node1["translate"] = (5, 6, 7) ... node1["translate"] >> node2["translate"] ... + >>> node2["translate"][0] + >>> node2["translate"][0].read() 5.0 + >>> node2["translate"][1] + >>> node2["translate"][1].read() 6.0 From b482befd9077c42160d894b17672e267d9d46874 Mon Sep 17 00:00:00 2001 From: Marcelo Saguas Iacovone Date: Tue, 20 Feb 2024 23:39:47 -0800 Subject: [PATCH 4/8] Changes the repr diplay to be more code-like --- cmdx.py | 113 ++++++++++++++++++++++++++++++------------------------- tests.py | 2 +- 2 files changed, 63 insertions(+), 52 deletions(-) diff --git a/cmdx.py b/cmdx.py index b2e633f..58a9441 100644 --- a/cmdx.py +++ b/cmdx.py @@ -512,7 +512,7 @@ class Node(object): >>> transform["tx"] = 5 >>> transform["worldMatrix"][0] >> decompose["inputMatrix"] >>> decompose["outputTranslate"] - + cmdx.Plug("decompose", "outputTranslate") == (5.0, 0.0, 0.0) >>> decompose["outputTranslate"].read() (5.0, 0.0, 0.0) @@ -551,7 +551,7 @@ def __str__(self): def __repr__(self): cls_name = '{}.{}'.format(__name__, self.__class__.__name__) - return "<{} : '{}'>".format(cls_name, self.name(namespace=True)) + return '{}("{}")'.format(cls_name, self.name(namespace=True)) def __add__(self, other): """Support legacy + '.attr' behavior @@ -579,10 +579,11 @@ def __getitem__(self, key): optionally pass tuple to include unit. Example: + >>> _new() >>> node = createNode("transform") >>> node["translate"] = (1, 1, 1) >>> node["translate", Meters] - + cmdx.Plug("transform1", "translate") == (0.01, 0.01, 0.01) >>> node["translate", Meters].read() (0.01, 0.01, 0.01) @@ -630,7 +631,7 @@ def __setitem__(self, key, value): >>> node["rotateX", Degrees] = 1.0 >>> node["rotateX"] = Degrees(1) >>> node["rotateX", Degrees] - + cmdx.Plug("myNode", "rotateX") == 1.0 >>> node["rotateX", Degrees].read() 1.0 >>> node["myDist"] = Distance() @@ -985,10 +986,11 @@ def update(self, attrs): attrs (dict): Key/value pairs of name and attribute Examples: + >>> _new() >>> node = createNode("transform") >>> node.update({"tx": 5.0, ("ry", Degrees): 30.0}) >>> node["tx"] - + cmdx.Plug("transform1", "translateX") == 5.0 >>> node["tx"].read() 5.0 @@ -1005,21 +1007,22 @@ def clear(self): values, freeing up memory at the expense of performance. Example: + >>> _new() >>> node = createNode("transform") >>> node["translateX"] = 5 >>> node["translateX"] - + cmdx.Plug("transform1", "translateX") == 5.0 >>> node["translateX"].read() 5.0 >>> # Plug was reused >>> node["translateX"] - + cmdx.Plug("transform1", "translateX") == 5.0 >>> node["translateX"].read() 5.0 >>> # Value was reused >>> node.clear() >>> node["translateX"] - + cmdx.Plug("transform1", "translateX") == 5.0 >>> node["translateX"].read() 5.0 >>> # Plug and value was recomputed @@ -1529,7 +1532,7 @@ def __str__(self): def __repr__(self): cls_name = '{}.{}'.format(__name__, self.__class__.__name__) - return "<{} : '{}'>".format(cls_name, self.path()) + return '{}("{}")'.format(cls_name, self.name()) def __or__(self, other): """Syntax sugar for finding a child @@ -1537,9 +1540,9 @@ def __or__(self, other): Examples: >>> _new() >>> parent = createNode("transform", "parent") - >>> child = createNode("transform", "child", parent) + >>> child = createNode("transform", "child", parent) >>> parent | "child" - + cmdx.DagNode("child") >>> (parent | "child").path() in ( ... '|parent|child', ... u'|parent|child' @@ -1547,9 +1550,9 @@ def __or__(self, other): True # Stackable too - >>> grand = createNode("transform", "grand", child) + >>> grand = createNode("transform", "grand", child) >>> parent | "child" | "grand" - + cmdx.DagNode("grand") >>> (parent | "child" | "grand").path() in ( ... '|parent|child|grand', ... u'|parent|child|grand' @@ -2317,24 +2320,24 @@ def flatten(self, type=None): """Return members, converting nested object sets into its members Example: - >>> from maya import cmds - >>> _ = cmds.file(new=True, force=True) - >>> a = cmds.createNode("transform", name="a") - >>> b = cmds.createNode("transform", name="b") - >>> c = cmds.createNode("transform", name="c") - >>> cmds.select(a) - >>> gc = cmds.sets([a], name="grandchild") - >>> cc = cmds.sets([gc, b], name="child") - >>> parent = cmds.sets([cc, c], name="parent") - >>> mainset = encode(parent) - >>> sorted(mainset.flatten(), key=lambda n: n.name()) - [, , ] - >>> result = sorted([n.name() for n in mainset.flatten()]) - >>> result in ( - ... ['a', 'b', 'c'], - ... [u'a', u'b', u'c'] - ... ) - True + >>> from maya import cmds + >>> _ = cmds.file(new=True, force=True) + >>> a = cmds.createNode("transform", name="a") + >>> b = cmds.createNode("transform", name="b") + >>> c = cmds.createNode("transform", name="c") + >>> cmds.select(a) + >>> gc = cmds.sets([a], name="grandchild") + >>> cc = cmds.sets([gc, b], name="child") + >>> parent = cmds.sets([cc, c], name="parent") + >>> mainset = encode(parent) + >>> sorted(mainset.flatten(), key=lambda n: n.name()) + [cmdx.DagNode("a"), cmdx.DagNode("b"), cmdx.DagNode("c")] + >>> result = sorted([n.name() for n in mainset.flatten()]) + >>> result in ( + ... ['a', 'b', 'c'], + ... [u'a', u'b', u'c'] + ... ) + True """ @@ -2590,14 +2593,15 @@ def __add__(self, other): than adding to longName, e.g. node["translate"] + "X" Example: + >>> _new() >>> node = createNode("transform") >>> node["tx"] = 5 >>> node["translate"] + "X" - + cmdx.Plug("transform1", "translateX") == 5.0 >>> (node["translate"] + "X").read() 5.0 >>> node["t"] + "x" - + cmdx.Plug("transform1", "translateX") == 5.0 >>> (node["t"] + "x").read() 5.0 >>> try: @@ -2627,6 +2631,7 @@ def __iadd__(self, other): """Support += operator, for .append() Example: + >>> _new() >>> node = createNode("transform") >>> node["myArray"] = Double(array=True) >>> node["myArray"].append(1.0) @@ -2634,15 +2639,15 @@ def __iadd__(self, other): >>> node["myArray"] += 5.1 >>> node["myArray"] += [1.1, 2.3, 999.0] >>> node["myArray"][0] - + cmdx.Plug("transform1", "myArray[0]") == 1.0 >>> node["myArray"][0].read() 1.0 >>> node["myArray"][6] - + cmdx.Plug("transform1", "myArray[6]") == 999.0 >>> node["myArray"][6].read() 999.0 >>> node["myArray"][-1] - + cmdx.Plug("transform1", "myArray[6]") == 999.0 >>> node["myArray"][-1].read() 999.0 @@ -2669,13 +2674,16 @@ def __str__(self): return str(self.read()) def __repr__(self): - cls_name = '{}.{}'.format(__name__, self.__class__.__name__) read_val = self.read() if isinstance(read_val, string_types): # Add surrounding single quotes, indicating the value is a string - read_val = "'{}'".format(read_val) + read_val = '"{}"'.format(read_val) - return "<{} : {}>".format(cls_name, read_val) + cls_name = '{}.{}'.format(__name__, self.__class__.__name__) + return '{}("{}", "{}") == {}'.format(cls_name, + self.node().name(), + self.name(), + read_val) def __rshift__(self, other): """Support connecting attributes via A >> B""" @@ -2844,10 +2852,11 @@ def __setitem__(self, index, value): """Write to child of array or compound plug Example: + >>> _new() >>> node = createNode("transform") >>> node["translate"][0] = 5 >>> node["tx"] - + cmdx.Plug("transform1", "translateX") == 5.0 >>> node["tx"].read() 5.0 @@ -3220,15 +3229,16 @@ def extend(self, values): If cmdx.Plug's, create a new entry and connect it. Example: + >>> _new() >>> node = createNode("transform") >>> node["myArray"] = Double(array=True) >>> node["myArray"].extend([1.0, 2.0, 3.0]) >>> node["myArray"][0] - + cmdx.Plug("transform1", "myArray[0]") == 1.0 >>> node["myArray"][0].read() 1.0 >>> node["myArray"][-1] - + cmdx.Plug("transform1", "myArray[2]") == 3.0 >>> node["myArray"][-1].read() 3.0 @@ -4156,7 +4166,7 @@ def connections(self, >>> b["ihi"].connection() == a True >>> a["ihi"] - + cmdx.Plug("A", "isHistoricallyInteresting") == 2 >>> a["ihi"].read() 2 >>> b["arrayAttr"] = Long(array=True) @@ -6407,7 +6417,7 @@ def connect(self, src, dst, force=True): ... mod.connect(tm["sx"], tm["tx"]) ... >>> tm["tx"].connection() - + cmdx.DagNode("myTransform") >>> tm["tx"].connection().path() in ( ... '|myTransform', ... u'|myTransform' @@ -6421,7 +6431,7 @@ def connect(self, src, dst, force=True): # Connect without undo >>> tm["tx"] << tx["output"] >>> tm["tx"].connection() - + cmdx.AnimCurve("myAnimCurve") >>> tm["tx"].connection().name() in ( ... 'myAnimCurve', ... u'myAnimCurve' @@ -6512,7 +6522,7 @@ def connectAttr(self, srcPlug, dstNode, dstAttr): ... mod.connectAttr(newNode["newAttr"], otherNode, otherAttr) ... >>> newNode["newAttr"].connection() - + cmdx.DagNode("otherNode") >>> newNode["newAttr"].connection().path() in ( ... '|otherNode', ... u'|otherNode' @@ -6521,7 +6531,7 @@ def connectAttr(self, srcPlug, dstNode, dstAttr): >>> cmds.undo() >>> newNode["newAttr"].connection() - + cmdx.DagNode("newNode") >>> newNode["newAttr"].connection().path() in ( ... '|newNode', ... u'|newNode' @@ -6837,6 +6847,7 @@ class DagModifier(_BaseModifier): """Modifier for DAG nodes Example: + >>> _new() >>> with DagModifier() as mod: ... node1 = mod.createNode("transform") ... node2 = mod.createNode("transform", parent=node1) @@ -6846,11 +6857,11 @@ class DagModifier(_BaseModifier): >>> getAttr(node1 + ".translateX") 1.0 >>> node2["translate"][0] - + cmdx.Plug("transform2", "translateX") == 1.0 >>> node2["translate"][0].read() 1.0 >>> node2["translate"][1] - + cmdx.Plug("transform2", "translateY") == 2.0 >>> node2["translate"][1].read() 2.0 >>> with DagModifier() as mod: @@ -6860,11 +6871,11 @@ class DagModifier(_BaseModifier): ... node1["translate"] >> node2["translate"] ... >>> node2["translate"][0] - + cmdx.Plug("transform4", "translateX") == 5.0 >>> node2["translate"][0].read() 5.0 >>> node2["translate"][1] - + cmdx.Plug("transform4", "translateY") == 6.0 >>> node2["translate"][1].read() 6.0 diff --git a/tests.py b/tests.py index 7f7834f..3a327b6 100644 --- a/tests.py +++ b/tests.py @@ -383,7 +383,7 @@ def test_nodeoperators(): node = cmdx.createNode(cmdx.tTransform, name="myNode") assert_equals(node, "|myNode") - assert_equals(repr(node), "") + assert_equals(repr(node), 'cmdx.DagNode("myNode")') assert_not_equals(node, "|NotEquals") assert_not_equals(str(node), repr(node)) From 019abe4d3e5a5513c40dc663b03b3026c9e78512 Mon Sep 17 00:00:00 2001 From: Marcelo Saguas Iacovone Date: Wed, 21 Feb 2024 23:10:30 -0800 Subject: [PATCH 5/8] Skips read() call within Plug __repr__ if the plug's apiType is of type Mfn.kCompoundAttribute --- cmdx.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmdx.py b/cmdx.py index 58a9441..66907f2 100644 --- a/cmdx.py +++ b/cmdx.py @@ -2674,12 +2674,16 @@ def __str__(self): return str(self.read()) def __repr__(self): + cls_name = '{}.{}'.format(__name__, self.__class__.__name__) + if self._mplug.attribute().apiType() == om.MFn.kCompoundAttribute: + return '{}("{}", "{}")'.format(cls_name, + self.node().name(), + self.name()) read_val = self.read() if isinstance(read_val, string_types): # Add surrounding single quotes, indicating the value is a string read_val = '"{}"'.format(read_val) - cls_name = '{}.{}'.format(__name__, self.__class__.__name__) return '{}("{}", "{}") == {}'.format(cls_name, self.node().name(), self.name(), @@ -7818,7 +7822,7 @@ def __hash__(self): def __repr__(self): """Avoid repr depicting the full contents of this dict""" cls_name = '{}.{}'.format(__name__, self.__class__.__name__) - return "<{} : '{}'>".format(cls_name, self["name"]) + return 'cmdx.{}("{}")'.format(cls_name, self["name"]) def __new__(cls, *args, **kwargs): """Support for using name of assignment From 73f1aefaf1b4514ed07f4c96350f7b669a9d39e2 Mon Sep 17 00:00:00 2001 From: Marcelo Saguas Iacovone Date: Thu, 22 Feb 2024 21:03:49 -0800 Subject: [PATCH 6/8] Delegates Plug __repr__ value reading to __str__ --- cmdx.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/cmdx.py b/cmdx.py index 66907f2..8f79282 100644 --- a/cmdx.py +++ b/cmdx.py @@ -2674,20 +2674,27 @@ def __str__(self): return str(self.read()) def __repr__(self): + try: + # Delegate the value reading to __str__ + read_result = str(self) + valid = True + except: + valid = False + cls_name = '{}.{}'.format(__name__, self.__class__.__name__) - if self._mplug.attribute().apiType() == om.MFn.kCompoundAttribute: - return '{}("{}", "{}")'.format(cls_name, - self.node().name(), - self.name()) - read_val = self.read() - if isinstance(read_val, string_types): - # Add surrounding single quotes, indicating the value is a string - read_val = '"{}"'.format(read_val) - - return '{}("{}", "{}") == {}'.format(cls_name, - self.node().name(), - self.name(), - read_val) + msg = '{}("{}", "{}")'.format(cls_name, + self.node().name(), + self.name()) + if valid: + try: + if self.typeClass() == String: + # Add surrounding quotes, indicating it is a string + read_result = '"{}"'.format(read_result) + except TypeError: + pass + msg += ' == {}'.format(read_result) + + return msg def __rshift__(self, other): """Support connecting attributes via A >> B""" From 8da17d3235828ec2fff902bb04eb40fed6bdd22c Mon Sep 17 00:00:00 2001 From: Marcelo Saguas Iacovone Date: Mon, 26 Feb 2024 23:52:55 -0800 Subject: [PATCH 7/8] Removes try/excepts and implements test case for string plugs --- cmdx.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/cmdx.py b/cmdx.py index 8f79282..f16ce74 100644 --- a/cmdx.py +++ b/cmdx.py @@ -653,6 +653,13 @@ def __setitem__(self, key, value): ... else: ... assert False >>> + >>> node["myString"] = String() + >>> node["myString"] + cmdx.Plug("myNode", "myString") == "" + >>> node["myString"] = "Hello, world!" + >>> node["myString"] + cmdx.Plug("myNode", "myString") == "Hello, world!" + >>> >>> delete(node) """ @@ -2674,24 +2681,21 @@ def __str__(self): return str(self.read()) def __repr__(self): - try: - # Delegate the value reading to __str__ - read_result = str(self) - valid = True - except: - valid = False - cls_name = '{}.{}'.format(__name__, self.__class__.__name__) msg = '{}("{}", "{}")'.format(cls_name, self.node().name(), self.name()) - if valid: - try: - if self.typeClass() == String: + + if not self.isCompound and not self.isArray: + # Delegate and include the value result from __str__ + read_result = str(self) + attr = self._mplug.attribute() + typ = attr.apiType() + if typ == om.MFn.kTypedAttribute: + typ = om.MFnTypedAttribute(attr).attrType() + if typ == om.MFnData.kString: # Add surrounding quotes, indicating it is a string read_result = '"{}"'.format(read_result) - except TypeError: - pass msg += ' == {}'.format(read_result) return msg From 70857defa2beeb9886eeec675f50e3a90a220d6e Mon Sep 17 00:00:00 2001 From: Marcelo Saguas Iacovone Date: Mon, 26 Feb 2024 23:59:23 -0800 Subject: [PATCH 8/8] Fixes if statement for not isCompound/isArray --- cmdx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmdx.py b/cmdx.py index f16ce74..024829b 100644 --- a/cmdx.py +++ b/cmdx.py @@ -2686,7 +2686,7 @@ def __repr__(self): self.node().name(), self.name()) - if not self.isCompound and not self.isArray: + if not all((self.isCompound, self.isArray)): # Delegate and include the value result from __str__ read_result = str(self) attr = self._mplug.attribute()