question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

KeyError when defining task attribute in `__init__`.

See original GitHub issue

Description of issue

This appears to be the same behavior that was reported in #886. I’m unable to use weighted task dictionarys as I get KeyError failures when trying to run. This appears to occur because I’m trying to initialize tasks inside init instead of statically when the class initalizes.

For purposes of the example below, Foo and Bar are defined directly in the class so you WOULD be able to say

class FooBarTaskSet(TaskSet):
    tasks = { Foo: 1, Bar: 2 }

but in the actual code, the tasks are defined as methods on the base class. Each sub-class calls one or more of the methods in the base class to create different scenarios. So in order to be able to populate tasks, I have to use self.Foo and in order to use self I have to initialize the value in __init__.

Expected behavior

As long as the tasks attribute is initialized before the class is created, I should be able to modify it however I please, and setting it in init should work the same.

Actual behavior

If tasks is set in __init__ (regardless of whether before or after calling super().__init__(...)), you will see KeyErrors

[2019-08-19 16:58:21,786] benran6/ERROR/stderr: Traceback (most recent call last):
  File "c:\python36\lib\site-packages\locust\core.py", line 358, in run
    self.schedule_task(self.get_next_task())
  File "c:\python36\lib\site-packages\locust\core.py", line 419, in get_next_task
    return random.choice(self.tasks)
  File "c:\python36\lib\random.py", line 258, in choice
    return seq[i]
KeyError: 1

Environment settings

  • OS: Windows
  • Python version: 3.6.2
  • Locust version: 0.11.0

Steps to reproduce (for bug reports)

class FooBarTaskSet(TaskSet):

    def Foo(self):
        print('Foo')

    def Bar(self):
        print('Bar')

    def __init__(self, parent):
        super().__init__(parent)
        self.tasks = {Foo: 2, Bar: 1}

class MyLocust(HttpLocust):
    host = f'https://localhost:8123'
    task_set = FooBarTaskSet
    min_wait = 500
    max_wait = 1000

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
kyczawoncommented, Feb 27, 2020

Yeah I know, just wanted to share a use case that leads to this same issue and an implementation for the helper function you suggested

1reaction
heymancommented, Oct 21, 2019

The way TaskSet is currently implemented, the tasks attribute is constructed/processed within TaskSets’s meta class (TaskSetMeta) upon class creation, and the constructed/processed result is always a list of references to callable tasks. So having a class such as:

class FooBarTaskSet(TaskSet):
    tasks = {taskA:1, taskB:2}

would result in the final tasks attribute to be set to [taskA, taskB, taskB]. This list of tasks will then be used to randomly pick tasks from.

So in your case you could instead change the self.tasks to self.tasks = [Foo, Foo, Bar]. You could also create a helper method set_tasks (or something) that takes a {Task: weight} dict and replaces the tasks attribute with a constructed list .

Read more comments on GitHub >

github_iconTop Results From Across the Web

python - Celery KeyError when wrapping app.task function ...
I'm led to believe that the wrapper is somehow modifying the name=.. attribute passed to app.task with the function name from helpers.py which...
Read more >
How to fix Python KeyError Exceptions in simple steps?
Know about Python KeyError Exception. And learn how to handle exceptions in Python. A detailed guide to Errors and Exceptions in Python.
Read more >
Python KeyError Exceptions and How to Handle Them
The Python KeyError is a type of LookupError exception and denotes that there was an issue retrieving the key you were looking for....
Read more >
Writing a locustfile — Locust 2.14.0 documentation
Another way to define the tasks of a User is by setting the tasks attribute. The tasks attribute is either a list of...
Read more >
Concepts — Airflow Documentation
A Task defines a unit of work within a DAG; it is represented as a node in ... The get function will throw...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found