Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions meshroom/core/desc/node.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import enum
from inspect import getfile
from inspect import getfile, getattr_static
from pathlib import Path
import logging
import shlex
Expand Down Expand Up @@ -427,7 +427,12 @@ def buildCommandLine(self, chunk) -> str:
if chunk.node.isParallelized and chunk.node.size > 1:
cmdSuffix = " " + self.commandLineRange.format(**chunk.range.toDict()) + " " + cmdSuffix

return cmdPrefix + chunk.node.nodeDesc.commandLine.format(**chunk.node._expVars, **chunk.node._staticExpVars, **cmdLineVars) + cmdSuffix
commandLineValue = getattr_static(self, 'commandLine')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
commandLineValue = getattr_static(self, 'commandLine')
# In the case of a lambda, we want a single "node" argument and not the node descriptor "self".
# Therefore, we use getattr_static to retrieve the raw lambda instead of a bound method, which
# would impose "self" as the first argument if we accessed "self.commandLine".
commandLineValue = getattr_static(self, 'commandLine')

if callable(commandLineValue):
cmd = commandLineValue(chunk.node)
else:
cmd = commandLineValue.format(**chunk.node._expVars, **chunk.node._staticExpVars, **cmdLineVars)
return cmdPrefix + cmd + cmdSuffix

def processChunk(self, chunk):
cmd = self.buildCommandLine(chunk)
Expand Down
94 changes: 94 additions & 0 deletions tests/test_nodeCommandLineFormatting.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,64 @@
#!/usr/bin/env python
# coding:utf-8

from unittest.mock import patch, PropertyMock

from meshroom.core.graph import Graph
from meshroom.core import desc

from .utils import registerNodeDesc, unregisterNodeDesc


class NodeWithCommandLineLambda(desc.CommandLineNode):
"""
A node using a lambda for the commandLine member variable.
"""
commandLine = lambda node: f"myapp --input {node.input.value} --output {node.output.value}"

inputs = [
desc.File(
name="input",
label="Input File",
description="An input file.",
value="/some/input",
),
]

outputs = [
desc.File(
name="output",
label="Output",
description="Output file.",
value="{nodeCacheFolder}/output.txt",
),
]


class NodeWithCommandLineString(desc.CommandLineNode):
"""
A node using a string template for the commandLine member variable.
"""
commandLine = "myapp --input {inputValue} --output {outputValue}"

inputs = [
desc.File(
name="input",
label="Input File",
description="An input file.",
value="/some/input",
),
]

outputs = [
desc.File(
name="output",
label="Output",
description="Output file.",
value="{nodeCacheFolder}/output.txt",
),
]


class NodeWithAttributesNeedingFormatting(desc.Node):
"""
A node containing list, file, choice and group attributes in order to test the
Expand Down Expand Up @@ -187,3 +239,45 @@ def test_formatting_groups(self):

assert node.secondGroup.getValueStr() == '"False,second_value,3.0"'
assert node._expVars["secondGroupValue"] == 'False,second_value,3.0'


class TestCommandLineLambda:

@classmethod
def setup_class(cls):
registerNodeDesc(NodeWithCommandLineLambda)
registerNodeDesc(NodeWithCommandLineString)

@classmethod
def teardown_class(cls):
unregisterNodeDesc(NodeWithCommandLineLambda)
unregisterNodeDesc(NodeWithCommandLineString)

def test_commandLine_lambda(self):
graph = Graph("")
node = graph.addNewNode("NodeWithCommandLineLambda")
chunk = node.chunks[0]
with patch("meshroom.core.plugins.NodePlugin.commandPrefix", new_callable=PropertyMock, return_value=""), \
patch("meshroom.core.plugins.NodePlugin.commandSuffix", new_callable=PropertyMock, return_value=""):
cmd = node.nodeDesc.buildCommandLine(chunk)
assert "--input /some/input" in cmd
assert "--output" in cmd

def test_commandLine_string(self):
graph = Graph("")
node = graph.addNewNode("NodeWithCommandLineString")
chunk = node.chunks[0]
with patch("meshroom.core.plugins.NodePlugin.commandPrefix", new_callable=PropertyMock, return_value=""), \
patch("meshroom.core.plugins.NodePlugin.commandSuffix", new_callable=PropertyMock, return_value=""):
cmd = node.nodeDesc.buildCommandLine(chunk)
assert cmd == "myapp --input /some/input --output {}".format(node.output.value)

def test_commandLine_lambda_uses_node_attribute(self):
graph = Graph("")
node = graph.addNewNode("NodeWithCommandLineLambda")
node.input.value = "/custom/path/file.txt"
chunk = node.chunks[0]
with patch("meshroom.core.plugins.NodePlugin.commandPrefix", new_callable=PropertyMock, return_value=""), \
patch("meshroom.core.plugins.NodePlugin.commandSuffix", new_callable=PropertyMock, return_value=""):
cmd = node.nodeDesc.buildCommandLine(chunk)
assert "--input /custom/path/file.txt" in cmd