1
$\begingroup$

I'm running into a weird problem where running blender from the command line will run with the --background flag, but it's not recognizing the --python flag. Any thoughts?

enter image description here

This is the output of my current directory: enter image description here.

The script I'm running is the script found here

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

Thanks!

$\endgroup$
5
  • $\begingroup$ This is strange. It should have worked and those are not Blender's command line options printed after usage. Could you please check if using ./blender --factory-startup --background --python ./unit_test_example.py works correctly? Could it be that you have third-party add-ons or Python packages installed? $\endgroup$ Commented Jun 28, 2022 at 22:39
  • $\begingroup$ It seems that the printed options are for unittest as seen here: bugs.python.org/issue41253 $\endgroup$ Commented Jun 28, 2022 at 22:43
  • $\begingroup$ @RobertGützkow Oh, these are very interesting findings! With the --factory-startup, I still get the same error. $\endgroup$ Commented Jun 28, 2022 at 22:52
  • 1
    $\begingroup$ Your script is probably doing something like parser.parse_args() ie. trying to interpret all Blender's arguments as it's own arguments. See eg this. Post your script. $\endgroup$
    – scurest
    Commented Jun 29, 2022 at 2:19
  • $\begingroup$ My script is this: import unittest class TestStringMethods(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper(), 'FOO') def test_isupper(self): self.assertTrue('FOO'.isupper()) self.assertFalse('Foo'.isupper()) def test_split(self): s = 'hello world' self.assertEqual(s.split(), ['hello', 'world']) # check that s.split fails when the separator is not a string with self.assertRaises(TypeError): s.split(2) if __name__ == '__main__': unittest.main() $\endgroup$ Commented Jun 29, 2022 at 16:29

1 Answer 1

3
$\begingroup$

When you run a Python script, sys.argv will be all arguments passed to Blender. That means if you call a Python functions that expects to "own" all of sys.argv it will see all Blender's arguments and get confused because it probably isn't expecting them.

In your case, you call unittest.main. From the docs

The argv argument can be a list of options passed to the program, with the first element being the program name. If not specified or None, the values of sys.argv are used.

So this explains it. Your script is trying to interpret the arguments in sys.argv that belong to Blender as though they belonged to it.

If you don't intend to pass any arguments to your script, you can just pass a fake program name as argv, eg. unittest.main(argv=['something']).

If you do intend to pass arguments, Blender let's you pass your own arguments after --. So you would do something like

    import sys
    argv = [__file__]  # program name
    if "--" in sys.argv:
        argv += sys.argv[sys.argv.index("--") + 1:]

    unittest.main(argv=argv)
$\endgroup$
1
  • $\begingroup$ Awesome, thanks for the answer! Yes, adding unittest.main(argv=['something']) at the bottom of the python file did the trick! $\endgroup$ Commented Jun 29, 2022 at 21:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .