Skip to content

suites not always assigned in loadTestsFromNames in loader.py #445

@jwlarocque

Description

@jwlarocque

If a plugin implements the loadTestsFromNames hook, doesn't set event.handled=True and sets events.names to something Falsey (e.g. []), suites is never assigned.
I think there could be a scenario in which a plugin would want to remove certain or all test names from events.names without setting handled=True, and that suites should default to an empty list in this case.

Example plugin (run with any test):

class Example(Plugin):
    alwaysOn = True

    def loadTestsFromNames(self, event):
        event.names = []

Trace:

  File ".../bin/nose2", line 10, in <module>
    sys.exit(discover())
  File ".../lib/python3.7/site-packages/nose2/main.py", line 301, in discover
    return main(*args, **kwargs)
  File ".../lib/python3.7/site-packages/nose2/main.py", line 87, in __init__
    super(PluggableTestProgram, self).__init__(**kw)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 100, in __init__
    self.parseArgs(argv)
  File ".../lib/python3.7/site-packages/nose2/main.py", line 120, in parseArgs
    self.createTests()
  File ".../lib/python3.7/site-packages/nose2/main.py", line 253, in createTests
    self.testNames, self.module)
  File ".../lib/python3.7/site-packages/nose2/loader.py", line 73, in loadTestsFromNames
    return self.suiteClass(suites)
UnboundLocalError: local variable 'suites' referenced before assignment

Relevant method in loader.py:

def loadTestsFromNames(self, testNames, module=None):
        """Load tests from test names.

        Fires :func:`loadTestsFromNames` hook.

        """
        event = events.LoadFromNamesEvent(
            self, testNames, module)
        result = self.session.hooks.loadTestsFromNames(event)
        log.debug('loadTestsFromNames event %s result %s', event, result)
        if event.handled:
            suites = result or []
        else:
            if event.names:
                suites = [self.loadTestsFromName(name, module)
                          for name in event.names]
            elif module:
                suites = self.loadTestsFromModule(module)
        if event.extraTests:
            suites.extend(event.extraTests)
        return self.suiteClass(suites)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions