Repository: dwavesystems/dwave-cloud-client

Issue:
Client.get_solver mutates instance defaults
```
defaults = dict(solver=dict(order_by='id'))

with Client.from_config(defaults=defaults) as client:
    assert 'order_by' in client.defaults['solver']
    solver = client.get_solver()
    assert 'order_by' not in client.defaults['solver']
```

Discussion:

Patch:
diff --git a/dwave/cloud/client.py b/dwave/cloud/client.py
index dd68167..abace57 100644
--- a/dwave/cloud/client.py
+++ b/dwave/cloud/client.py
@@ -1068,11 +1068,13 @@ class Client(object):
 
         # in absence of other filters, config/env solver filters/name are used
         if not filters and self.default_solver:
-            filters = self.default_solver
+            filters = copy.deepcopy(self.default_solver)
 
         # allow `order_by` from default config/init override
         if order_by is None:
             order_by = filters.pop('order_by', 'avg_load')
+        else:
+            filters.pop('order_by', None)
 
         # get the first solver that satisfies all filters
         try:


Test patch:
diff --git a/tests/test_mock_solver_loading.py b/tests/test_mock_solver_loading.py
index e6fa54e..a4db844 100644
--- a/tests/test_mock_solver_loading.py
+++ b/tests/test_mock_solver_loading.py
@@ -208,6 +208,22 @@ class MockSolverLoading(unittest.TestCase):
                 with self.assertRaises(ValueError):
                     client.get_solver(solver_name)
 
+    def test_get_solver_reproducible(self):
+        """get_solver should return same solver (assuming cache hasn't changed)"""
+
+        with requests_mock.mock() as m:
+            setup_server(m)
+
+            # prefer solvers with longer name: that's our second solver
+            defaults = dict(solver=dict(order_by=lambda s: -len(s.id)))
+
+            with Client(url, token, defaults=defaults) as client:
+                solver = client.get_solver()
+                self.assertEqual(solver.id, second_solver_name)
+
+                solver = client.get_solver()
+                self.assertEqual(solver.id, second_solver_name)
+
     def test_solver_filtering_in_client(self):
         # base client
         self.assertTrue(Client.is_solver_handled(solver_object('test', 'qpu')))