Repository: locustio/locust
File: locust/web.py (Python)

Code before:
            self.update_template_args()
            return render_template("index.html", **self.template_args)

        @app.route("/swarm", methods=["POST"])
        @self.auth_required_if_enabled
        def swarm() -> Response:
            assert request.method == "POST"

            # Loading UserClasses & ShapeClasses if Locust is running with UserClass Picker
            if self.userclass_picker_is_active:
                if not self.environment.available_user_classes:
                    err_msg = "UserClass picker is active but there are no available UserClasses"
                    return jsonify({"success": False, "message": err_msg, "host": environment.host})

                # Getting Specified User Classes
                form_data_user_class_names = request.form.getlist("user_classes")

                # Updating UserClasses
                if form_data_user_class_names:
                    user_classes = {}
                    for user_class_name, user_class_object in self.environment.available_user_classes.items():
                        if user_class_name in form_data_user_class_names:
                            user_classes[user_class_name] = user_class_object

                else:
                    user_classes = {key: value for (key, value) in self.environment.available_user_classes.items if
                                    value in self.environment.user_classes}
                self._update_user_classes(user_classes)

                # Updating ShapeClass if specified in WebUI Form
                form_data_shape_class_name = request.form.get("shape_class", "Default")
                if form_data_shape_class_name == "Default":
                    self._update_shape_class(None)
                else:
                    self._update_shape_class(form_data_shape_class_name)

                # Stopping Runners and setting user dispatchers to None so that they
                # are recreated with the appropriate UserClasses
                self._stop_runners()

            parsed_options_dict = vars(environment.parsed_options) if environment.parsed_options else {}
            for key, value in request.form.items():
                if key == "user_count":  # if we just renamed this field to "users" we wouldn't need this
                    user_count = int(value)
                elif key == "spawn_rate":
                    spawn_rate = float(value)
                elif key == "host":
                    # Replace < > to guard against XSS
                    environment.host = str(request.form["host"]).replace("<", "").replace(">", "")
                elif key in parsed_options_dict:
                    # update the value in environment.parsed_options, but dont change the type.

Review comment (suggestion):
I tried out this change and got
```
File "/Users/michaelnester/git/locust/locust/web.py", line 167, in swarm
  user_classes = {
TypeError: 'builtin_function_or_method' object is not iterable
```

I think it needs to be `self.environment.available_user_classes.items()`, which worked for me (using python 3.9)

Code after:
        @self.auth_required_if_enabled
        def swarm() -> Response:
            assert request.method == "POST"

            # Loading UserClasses & ShapeClasses if Locust is running with UserClass Picker
            if self.userclass_picker_is_active:
                if not self.environment.available_user_classes:
                    err_msg = "UserClass picker is active but there are no available UserClasses"
                    return jsonify({"success": False, "message": err_msg, "host": environment.host})

                # Getting Specified User Classes
                form_data_user_class_names = request.form.getlist("user_classes")

                # Updating UserClasses
                if form_data_user_class_names:
                    user_classes = {}
                    for user_class_name, user_class_object in self.environment.available_user_classes.items():
                        if user_class_name in form_data_user_class_names:
                            user_classes[user_class_name] = user_class_object

                else:
                    if self.environment.runner and self.environment.runner.state == STATE_RUNNING:
                        # Test is already running
                        # Using the user classes that have already been selected
                        user_classes = {
                            key: value
                            for (key, value) in self.environment.available_user_classes.items()
                            if value in self.environment.user_classes
                        }
                    else:
                        # Starting test with no user class selection
                        # Defaulting to using all available user classes
                        user_classes = self.environment.available_user_classes

                self._update_user_classes(user_classes)

                # Updating ShapeClass if specified in WebUI Form
                form_data_shape_class_name = request.form.get("shape_class", "Default")
                if form_data_shape_class_name == "Default":
                    self._update_shape_class(None)
                else:
                    self._update_shape_class(form_data_shape_class_name)

                # Stopping Runners and setting user dispatchers to None so that they
                # are recreated with the appropriate UserClasses
                self._stop_runners()

            parsed_options_dict = vars(environment.parsed_options) if environment.parsed_options else {}
            for key, value in request.form.items():
                if key == "user_count":  # if we just renamed this field to "users" we wouldn't need this
                    user_count = int(value)