Repository: mlflow/mlflow

Issue:
Fix `use-set-literal` lint errors
Fix `use-set-literal` lint errors by following the instructions below (example PR: #6534):

https://github.com/mlflow/mlflow/blob/1b89add428da0a4453e7523a20d13f04f6291f37/pylint_plugins/set_checker.py#L12-L41

## What needs to be fixed?

`set` applied on `list` or `tuple` literal need to be converted to `set` literal:

```python
# Bad
set([1, 2, 3])
set((1, 2, 3))

# Good
{1, 2, 3}
```

## Files

| File                                                               | Assignee     | PR    |
| :----------------------------------------------------------------- | :----------- | :---- |
| mlflow/azure/client.py                                             | @Monkero     | #6544 |
| mlflow/entities/lifecycle_stage.py                                 | @Monkero     | #6544 |
| mlflow/entities/run_status.py                                      | @Monkero     | #6544 |
| mlflow/server/handlers.py                                          | @dsgibbons   | #6542 |
| mlflow/tracking/fluent.py                                          | @dsgibbons   | #6542 |
| mlflow/utils/autologging_utils/safety.py                           | @dsgibbons   | #6542 |
| tests/autologging/test_autologging_behaviors_unit.py               | @dsgibbons   | #6543 |
| tests/entities/test_run_info.py                                    | @dsgibbons   | #6543 |
| tests/entities/test_run_status.py                                  | @dsgibbons   | #6543 |
| tests/lightgbm/test_lightgbm_autolog.py                            | @iamthen0ise | #6560 |
| tests/models/test_model_input_examples.py                          | @iamthen0ise | #6560 |
| tests/projects/test_project_spec.py                                | @iamthen0ise | #6560 |
| tests/pyfunc/test_model_export_with_loader_module_and_data_path.py | @dsgibbons   | #6584 |
| tests/store/artifact/test_databricks_artifact_repo.py              | @dsgibbons   | #6584 |
| tests/store/artifact/test_ftp_artifact_repo.py                     | @dsgibbons   | #6584 |
| ~tests/tensorflow/test_tensorflow2_autolog.py~                     | -            | -     |
| tests/utils/test_requirements_utils.py                             | @dsgibbons   | #6584 |
| tests/xgboost/test_xgboost_autolog.py                              | @dsgibbons   | #6584 |
| mlflow/utils/search_utils.py                                       | @harupy      | #6534 |
| tests/entities/model_registry/test_model_version.py                | @harupy      | #6534 |
| tests/entities/model_registry/test_registered_model.py             | @harupy      | #6534 |
| tests/store/tracking/test_sqlalchemy_store.py                      | @harupy      | #6534 |
| tests/tracking/test_model_registry.py                              | @harupy      | #6534 |


If you're interested in working on this issue, ping me with the file you would like to work on. Please fix only 1 ~ 3 items per pull request.


Discussion:
I'm happy to look at all the mlflow/ files. Do you definitely want a separate PR for each file?
@dsgibbons Thanks for the help! I've updated the description. You can fix 1 ~ 3 items per pull request.
Can I also participate?
@Monkero Absolutely!
I'll start putting together PRs for this issue in about 12 hours @Monkero so if you want to make a start then go ahead. I'll then start fixing the ones that don't already have PRs against them, starting from the top of the list.
@harupy Would you mind saving the number of items you will fix for first-time contributors?
@Monkero Assigned the first three items to you :)
Ok, I`ve done them, but do I have to write tests for it? If the answer is 'yes', then the question is 'how?'
@Monkero No. `mlflow/pylint_plugins/set_checker.py` should work as a test.
`mlflow/utils/search_utils.py` is contained within `pylint_plugins/set_checker.py` but is not included in the table above. `mlflow/utils/search_utils.py` still uses `set()` instead of `{}`.
> `mlflow/utils/search_utils.py` is contained within `pylint_plugins/set_checker.py` but is not included in the table above. `mlflow/utils/search_utils.py` still uses `set()` instead of `{}`.

I forgot to include the items I fixed in #6534. Updated the table.
@harupy Hi! I'd like to take some files from this task.
@iamthen0ise Awesome! Let me assign some files to you.
@iamthen0ise Done!
@dsgibbons Can you fix the remaining files?
Yes @harupy 
@dsgibbons Thanks! When you file a PR, can you remove the `IGNORED_FILES` variable?


```diff
diff --git a/pylint_plugins/set_checker.py b/pylint_plugins/set_checker.py
index 0a7f1d483..b646ef37e 100644
--- a/pylint_plugins/set_checker.py
+++ b/pylint_plugins/set_checker.py
@@ -5,30 +5,6 @@ from pylint.interfaces import IAstroidChecker
 from pylint.checkers import BaseChecker
 
 
-IGNORED_FILES = set(
-    map(
-        os.path.abspath,
-        [
-            ##### Instructions #####
-            # 1. Select the file you would like to work on.
-            # 2. Remove the file from the list.
-            # 3. Run `pylint <the file>`.
-            # 4. Fix lint errors.
-            # 5. File a PR.
-            "tests/lightgbm/test_lightgbm_autolog.py",
-            "tests/models/test_model_input_examples.py",
-            "tests/projects/test_project_spec.py",
-            "tests/pyfunc/test_model_export_with_loader_module_and_data_path.py",
-            "tests/store/artifact/test_databricks_artifact_repo.py",
-            "tests/store/artifact/test_ftp_artifact_repo.py",
-            "tests/tensorflow/test_tensorflow2_autolog.py",
-            "tests/utils/test_requirements_utils.py",
-            "tests/xgboost/test_xgboost_autolog.py",
-        ],
-    )
-)
-
-
 class SetChecker(BaseChecker):
     __implements__ = IAstroidChecker
 
@@ -45,8 +21,6 @@ class SetChecker(BaseChecker):
     priority = -1
 
     def visit_call(self, node: astroid.Call):
-        if node.root().file in IGNORED_FILES:
-            return
         if (
             node.func.as_string() == "set"
             and node.args
```

Resolving patch:
diff --git a/pylint_plugins/set_checker.py b/pylint_plugins/set_checker.py
--- a/pylint_plugins/set_checker.py
+++ b/pylint_plugins/set_checker.py
@@ -1,34 +1,8 @@
-import os
-
 import astroid
 from pylint.interfaces import IAstroidChecker
 from pylint.checkers import BaseChecker
 
 
-IGNORED_FILES = set(
-    map(
-        os.path.abspath,
-        [
-            ##### Instructions #####
-            # 1. Select the file you would like to work on.
-            # 2. Remove the file from the list.
-            # 3. Run `pylint <the file>`.
-            # 4. Fix lint errors.
-            # 5. File a PR.
-            "tests/lightgbm/test_lightgbm_autolog.py",
-            "tests/models/test_model_input_examples.py",
-            "tests/projects/test_project_spec.py",
-            "tests/pyfunc/test_model_export_with_loader_module_and_data_path.py",
-            "tests/store/artifact/test_databricks_artifact_repo.py",
-            "tests/store/artifact/test_ftp_artifact_repo.py",
-            "tests/tensorflow/test_tensorflow2_autolog.py",
-            "tests/utils/test_requirements_utils.py",
-            "tests/xgboost/test_xgboost_autolog.py",
-        ],
-    )
-)
-
-
 class SetChecker(BaseChecker):
     __implements__ = IAstroidChecker
 
@@ -45,8 +19,6 @@ class SetChecker(BaseChecker):
     priority = -1
 
     def visit_call(self, node: astroid.Call):
-        if node.root().file in IGNORED_FILES:
-            return
         if (
             node.func.as_string() == "set"
             and node.args


Test patch:
diff --git a/tests/pyfunc/test_model_export_with_loader_module_and_data_path.py b/tests/pyfunc/test_model_export_with_loader_module_and_data_path.py
--- a/tests/pyfunc/test_model_export_with_loader_module_and_data_path.py
+++ b/tests/pyfunc/test_model_export_with_loader_module_and_data_path.py
@@ -551,7 +551,7 @@ def test_column_schema_enforcement_no_col_names():
 
     # Can only provide data type that can be converted to dataframe...
     with pytest.raises(MlflowException, match="Expected input to be DataFrame or list. Found: set"):
-        pyfunc_model.predict(set([1, 2, 3]))
+        pyfunc_model.predict({1, 2, 3})
 
     # 9. dictionaries of str -> list/nparray work
     d = {"a": [1.0], "b": [2.0], "c": [3.0]}
diff --git a/tests/store/artifact/test_databricks_artifact_repo.py b/tests/store/artifact/test_databricks_artifact_repo.py
--- a/tests/store/artifact/test_databricks_artifact_repo.py
+++ b/tests/store/artifact/test_databricks_artifact_repo.py
@@ -548,9 +548,7 @@ def test_list_artifacts_handles_pagination(self, databricks_artifact_repo):
             call_endpoint_mock.side_effect = list_artifact_paginated_response_protos
             message_mock.return_value = None
             artifacts = databricks_artifact_repo.list_artifacts()
-            assert set(["a.txt", "b", "c.txt", "d", "e.txt", "f"]) == {
-                file.path for file in artifacts
-            }
+            assert {"a.txt", "b", "c.txt", "d", "e.txt", "f"} == {file.path for file in artifacts}
             calls = [
                 mock.call(ListArtifacts(run_id=MOCK_RUN_ID, path="")),
                 mock.call(ListArtifacts(run_id=MOCK_RUN_ID, path="", page_token="2")),
diff --git a/tests/store/artifact/test_ftp_artifact_repo.py b/tests/store/artifact/test_ftp_artifact_repo.py
--- a/tests/store/artifact/test_ftp_artifact_repo.py
+++ b/tests/store/artifact/test_ftp_artifact_repo.py
@@ -229,7 +229,7 @@ def test_log_artifacts(artifact_path, ftp_mock, tmpdir):
     call_mock = MagicMock(return_value=ftp_mock)
     repo.get_ftp_client.return_value = MagicMock(__enter__=call_mock)
 
-    dirs_created = set([dest_path_root])
+    dirs_created = {dest_path_root}
     files_created = set()
     cwd_history = ["/"]
 
@@ -272,24 +272,21 @@ def storbinary_mock(cmd, _):
     dest_path = (
         dest_path_root if artifact_path is None else posixpath.join(dest_path_root, artifact_path)
     )
-    dirs_expected = set(
-        [
-            dest_path,
-            posixpath.join(dest_path, "empty1"),
-            posixpath.join(dest_path, "subsubdir"),
-            posixpath.join(dest_path, "subsubdir", "empty2"),
-        ]
-    )
-    files_expected = set(
-        [
-            posixpath.join(dest_path, "a.txt"),
-            posixpath.join(dest_path, "b.txt"),
-            posixpath.join(dest_path, "c.txt"),
-            posixpath.join(dest_path, "subsubdir/aa.txt"),
-            posixpath.join(dest_path, "subsubdir/bb.txt"),
-            posixpath.join(dest_path, "subsubdir/cc.txt"),
-        ]
-    )
+    dirs_expected = {
+        dest_path,
+        posixpath.join(dest_path, "empty1"),
+        posixpath.join(dest_path, "subsubdir"),
+        posixpath.join(dest_path, "subsubdir", "empty2"),
+    }
+
+    files_expected = {
+        posixpath.join(dest_path, "a.txt"),
+        posixpath.join(dest_path, "b.txt"),
+        posixpath.join(dest_path, "c.txt"),
+        posixpath.join(dest_path, "subsubdir/aa.txt"),
+        posixpath.join(dest_path, "subsubdir/bb.txt"),
+        posixpath.join(dest_path, "subsubdir/cc.txt"),
+    }
 
     for dirs_expected_i in dirs_expected.copy():
         if dirs_expected_i != dest_path_root:
diff --git a/tests/utils/test_requirements_utils.py b/tests/utils/test_requirements_utils.py
--- a/tests/utils/test_requirements_utils.py
+++ b/tests/utils/test_requirements_utils.py
@@ -309,7 +309,7 @@ def test_infer_requirements_does_not_print_warning_for_recognized_packages():
         return_value=["sklearn"],
     ), mock.patch(
         "mlflow.utils.requirements_utils._PYPI_PACKAGE_INDEX",
-        _PyPIPackageIndex(date="2022-01-01", package_names=set(["scikit-learn"])),
+        _PyPIPackageIndex(date="2022-01-01", package_names={"scikit-learn"}),
     ), mock.patch(
         "mlflow.utils.requirements_utils._logger.warning"
     ) as mock_warning:
diff --git a/tests/xgboost/test_xgboost_autolog.py b/tests/xgboost/test_xgboost_autolog.py
--- a/tests/xgboost/test_xgboost_autolog.py
+++ b/tests/xgboost/test_xgboost_autolog.py
@@ -188,8 +188,8 @@ def test_xgb_autolog_sklearn():
     client = MlflowClient()
     run = client.get_run(run.info.run_id)
     assert run.data.metrics.items() <= params.items()
-    artifacts = set(x.path for x in client.list_artifacts(run.info.run_id))
-    assert artifacts >= set(["feature_importance_weight.png", "feature_importance_weight.json"])
+    artifacts = {x.path for x in client.list_artifacts(run.info.run_id)}
+    assert artifacts >= {"feature_importance_weight.png", "feature_importance_weight.json"}
     loaded_model = mlflow.xgboost.load_model(model_uri)
     np.testing.assert_allclose(loaded_model.predict(X), model.predict(X))