codecov-commenter: # [Codecov](https://codecov.io/gh/dwavesystems/dwave-system/pull/317?src=pr&el=h1) Report
> Merging [#317](https://codecov.io/gh/dwavesystems/dwave-system/pull/317?src=pr&el=desc) into [master](https://codecov.io/gh/dwavesystems/dwave-system/commit/0cf36f5db89d8c16c4d36be56a7487235de15ea7?el=desc) will **decrease** coverage by `1.26%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/dwavesystems/dwave-system/pull/317/graphs/tree.svg?width=650&height=150&src=pr&token=t7cis9A6tt)](https://codecov.io/gh/dwavesystems/dwave-system/pull/317?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #317      +/-   ##
==========================================
- Coverage   92.85%   91.58%   -1.27%     
==========================================
  Files          22       22              
  Lines        1176     1177       +1     
==========================================
- Hits         1092     1078      -14     
- Misses         84       99      +15     
```


| [Impacted Files](https://codecov.io/gh/dwavesystems/dwave-system/pull/317?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [dwave/system/samplers/dwave\_sampler.py](https://codecov.io/gh/dwavesystems/dwave-system/pull/317/diff?src=pr&el=tree#diff-ZHdhdmUvc3lzdGVtL3NhbXBsZXJzL2R3YXZlX3NhbXBsZXIucHk=) | `78.75% <100.00%> (-8.05%)` | :arrow_down: |
| [dwave/system/samplers/leap\_hybrid\_sampler.py](https://codecov.io/gh/dwavesystems/dwave-system/pull/317/diff?src=pr&el=tree#diff-ZHdhdmUvc3lzdGVtL3NhbXBsZXJzL2xlYXBfaHlicmlkX3NhbXBsZXIucHk=) | `73.52% <100.00%> (ø)` | |
| [dwave/system/composites/embedding.py](https://codecov.io/gh/dwavesystems/dwave-system/pull/317/diff?src=pr&el=tree#diff-ZHdhdmUvc3lzdGVtL2NvbXBvc2l0ZXMvZW1iZWRkaW5nLnB5) | `95.73% <0.00%> (-1.22%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/dwavesystems/dwave-system/pull/317?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/dwavesystems/dwave-system/pull/317?src=pr&el=footer). Last update [0cf36f5...17c125e](https://codecov.io/gh/dwavesystems/dwave-system/pull/317?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/docs/reference/minimize_energy/dwave.embedding.chain_breaks.MinimizeEnergy.rst b/docs/reference/minimize_energy/dwave.embedding.chain_breaks.MinimizeEnergy.rst
index 0dcfd20..71e3b63 100644
--- a/docs/reference/minimize_energy/dwave.embedding.chain_breaks.MinimizeEnergy.rst
+++ b/docs/reference/minimize_energy/dwave.embedding.chain_breaks.MinimizeEnergy.rst
@@ -1,7 +1,16 @@
-dwave.embedding.chain_breaks.MinimizeEnergy
-===========================================
+﻿dwave.embedding.chain\_breaks.MinimizeEnergy
+============================================
 
 .. currentmodule:: dwave.embedding.chain_breaks
 
 .. autoclass:: MinimizeEnergy
-    :members: __call__
+
+
+   .. automethod:: __init__
+
+
+   .. rubric:: Methods
+
+   .. autosummary::
+
+      ~MinimizeEnergy.__init__
diff --git a/dwave/system/samplers/clique.py b/dwave/system/samplers/clique.py
index 608cbcd..d8e1f30 100644
--- a/dwave/system/samplers/clique.py
+++ b/dwave/system/samplers/clique.py
@@ -56,10 +56,7 @@ class DWaveCliqueSampler(dimod.Sampler):
     """
     def __init__(self, **config):
 
-        # get the QPU with the most qubits available, subject to other
-        # constraints specified in **config
-        self.child = child = DWaveSampler(order_by='-num_active_qubits',
-                                          **config)
+        self.child = child = DWaveSampler(**config)
 
         # do some topology checking
         try:
diff --git a/dwave/system/samplers/dwave_sampler.py b/dwave/system/samplers/dwave_sampler.py
index e7ba5c6..6c6183a 100644
--- a/dwave/system/samplers/dwave_sampler.py
+++ b/dwave/system/samplers/dwave_sampler.py
@@ -21,8 +21,9 @@ for explanations of technical terms in descriptions of Ocean tools.
 """
 from __future__ import division
 
-import functools
 import time
+import functools
+import collections.abc as abc
 
 from warnings import warn
 
@@ -113,6 +114,10 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
             See :meth:`~dwave.cloud.client.Client.get_solvers` for a more detailed
             description of the parameter.
 
+            Note:
+                Isolated use of ``order_by`` has been deprecated in 0.10.0.
+                Please specify it as part of the ``solver`` argument dict.
+
         config_file (str, optional):
             Path to a configuration file that identifies a D-Wave system and provides
             connection information.
@@ -120,6 +125,18 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
         profile (str, optional):
             Profile to select from the configuration file.
 
+        client (str, optional, default='qpu'):
+            Client type used for accessing the API. Client type effectively
+            constraints the solver's ``category``. Supported values are
+            ``qpu``, ``sw`` and ``hybrid`` for QPU, software and hybrid solvers
+            respectively. In addition, ``base`` client type doesn't filter
+            solvers at all.
+
+            Note:
+                Prior to version 0.10.0, :class:`.DWaveSampler` used the
+                ``base`` client, allowing non-QPU solvers to be selected.
+                To reproduce the old behavior, set ``client='base'``.
+
         endpoint (str, optional):
             D-Wave API endpoint URL.
 
@@ -127,14 +144,13 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
             Authentication token for the D-Wave API to authenticate the client session.
 
         solver (dict/str, optional):
-            Solver (a D-Wave system on which to run submitted problems) to select given
-            as a set of required features. Supported features and values are described in
+            Solver (a D-Wave system on which to run submitted problems) to
+            select given as a set of required features. Solver priority (if
+            multiple solvers match) can be given via ``order_by`` key. Supported
+            features and values are described in
             :meth:`~dwave.cloud.client.Client.get_solvers`. For backward
             compatibility, a solver name, formatted as a string, is accepted.
 
-        proxy (str, optional):
-            Proxy URL to be used for accessing the D-Wave API.
-
         **config:
             Keyword arguments passed directly to :meth:`~dwave.cloud.client.Client.from_config`.
 
@@ -153,7 +169,7 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
 
         >>> from dwave.system import DWaveSampler
         ...
-        >>> sampler = DWaveSampler(solver={'qpu': True})
+        >>> sampler = DWaveSampler()
         ...
         >>> qubit_a = sampler.nodelist[0]
         >>> qubit_b = next(iter(sampler.adjacency[qubit_a]))
@@ -169,18 +185,25 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
     """
     def __init__(self, failover=False, retry_interval=-1, order_by=None, **config):
 
-        if config.get('solver_features') is not None:
-            warn("'solver_features' argument has been renamed to 'solver'.", DeprecationWarning)
+        # fold isolated order_by under solver
+        if order_by is not None:
+            warn("'order_by' has been moved under 'solver' dict.",
+                 DeprecationWarning)
 
-            if config.get('solver') is not None:
-                raise ValueError("can not combine 'solver' and 'solver_features'")
+        # strongly prefer QPU solvers; requires kwarg-level override
+        config.setdefault('client', 'qpu')
 
-            config['solver'] = config.pop('solver_features')
+        # weakly prefer QPU solver with the highest qubit count,
+        # easily overridden on any config level above defaults (file/env/kwarg)
+        defaults = config.setdefault('defaults', {})
+        if not isinstance(defaults, abc.Mapping):
+            raise TypeError("mapping expected for 'defaults'")
+        defaults.update(solver=dict(order_by='-num_active_qubits'))
 
         self.client = Client.from_config(**config)
 
+        # NOTE: split behavior until we remove `order_by` kwarg
         if order_by is None:
-            # use the default from the cloud-client
             self.solver = self.client.get_solver()
         else:
             self.solver = self.client.get_solver(order_by=order_by)
@@ -189,7 +212,7 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
         self.retry_interval = retry_interval
 
     warnings_default = WarningAction.IGNORE
-    """Defines the default behabior for :meth:`.sample_ising`'s  and
+    """Defines the default behavior for :meth:`.sample_ising`'s  and
     :meth:`sample_qubo`'s `warnings` kwarg.
     """
 
@@ -207,7 +230,7 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
             >>> from dwave.system import DWaveSampler
             >>> sampler = DWaveSampler()
             >>> sampler.properties    # doctest: +SKIP
-            {u'anneal_offset_ranges': [[-0.2197463755538704, 0.03821687759418928],
+            {'anneal_offset_ranges': [[-0.2197463755538704, 0.03821687759418928],
               [-0.2242514597680286, 0.01718456460967399],
               [-0.20860153999435985, 0.05511969218508182],
             # Snipped above response for brevity
@@ -238,12 +261,12 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
             >>> from dwave.system import DWaveSampler
             >>> sampler = DWaveSampler()
             >>> sampler.parameters    # doctest: +SKIP
-            {u'anneal_offsets': ['parameters'],
-            u'anneal_schedule': ['parameters'],
-            u'annealing_time': ['parameters'],
-            u'answer_mode': ['parameters'],
-            u'auto_scale': ['parameters'],
-            # Snipped above response for brevity
+            {'anneal_offsets': ['parameters'],
+             'anneal_schedule': ['parameters'],
+             'annealing_time': ['parameters'],
+             'answer_mode': ['parameters'],
+             'auto_scale': ['parameters'],
+             # Snipped above response for brevity
 
         See `Ocean Glossary <https://docs.ocean.dwavesys.com/en/stable/concepts/index.html>`_
         for explanations of technical terms in descriptions of Ocean tools.
@@ -342,7 +365,7 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
 
             >>> from dwave.system import DWaveSampler
             ...
-            >>> sampler = DWaveSampler(solver={'qpu': True})
+            >>> sampler = DWaveSampler()
             ...
             >>> qubit_a = sampler.nodelist[0]
             >>> qubit_b = next(iter(sampler.adjacency[qubit_a]))
@@ -496,24 +519,22 @@ class DWaveSampler(dimod.Sampler, dimod.Structured):
 
 
     def to_networkx_graph(self):
-
         """Converts DWaveSampler's structure to a Chimera or Pegasus NetworkX graph.
 
         Returns:
-            G : :class:`networkx.Graph` graph.
+            :class:`networkx.Graph`:
                 Either an (m, n, t) Chimera lattice or a Pegasus lattice of size m.
+
         Examples:
             This example converts a selected D-Wave system solver to a graph
             and verifies it has over 2000 nodes.
 
             >>> from dwave.system import DWaveSampler
             ...
-            >>> sampler = DWaveSampler(solver={'qpu': True})
+            >>> sampler = DWaveSampler()
             >>> g = sampler.to_networkx_graph()      # doctest: +SKIP
             >>> len(g.nodes) > 2000                  # doctest: +SKIP
             True
-
-
         """
 
         topology_type = self.properties['topology']['type']
diff --git a/dwave/system/samplers/leap_hybrid_sampler.py b/dwave/system/samplers/leap_hybrid_sampler.py
index 55b896f..89d23c4 100644
--- a/dwave/system/samplers/leap_hybrid_sampler.py
+++ b/dwave/system/samplers/leap_hybrid_sampler.py
@@ -29,6 +29,7 @@ from dwave.cloud import Client
 
 __all__ = ['LeapHybridSampler']
 
+
 class LeapHybridSampler(dimod.Sampler):
     """A class for using Leap's cloud-based hybrid solvers.
 
@@ -40,15 +41,6 @@ class LeapHybridSampler(dimod.Sampler):
     Inherits from :class:`dimod.Sampler`.
 
     Args:
-        solver (dict/str, optional):
-            Solver (a hybrid solver on which to run submitted problems) to select
-            named as a string or given as a set of required features. Supported
-            features and values are described in
-            :meth:`~dwave.cloud.client.Client.get_solvers`.
-
-        connection_close (bool, optional):
-            Force HTTP(S) connection close after each request.
-
         config_file (str, optional):
             Path to a configuration file that identifies a hybrid solver and provides
             connection information.
@@ -62,11 +54,14 @@ class LeapHybridSampler(dimod.Sampler):
         token (str, optional):
             Authentication token for the D-Wave API to authenticate the client session.
 
-        proxy (str, optional):
-            Proxy URL to be used for accessing the D-Wave API.
+        solver (dict/str, optional):
+            Solver (a hybrid solver on which to run submitted problems) to select
+            named as a string or given as a set of required features. Supported
+            features and values are described in
+            :meth:`~dwave.cloud.client.Client.get_solvers`.
 
         **config:
-            Keyword arguments passed directly to :meth:`~dwave.cloud.client.Client.from_config`.
+            Keyword arguments passed to :meth:`~dwave.cloud.client.Client.from_config`.
 
     Examples:
         This example builds a random sparse graph and uses a hybrid solver to find a
@@ -94,22 +89,26 @@ class LeapHybridSampler(dimod.Sampler):
 
     def __init__(self, solver=None, connection_close=True, **config):
 
-        # always use the base class (QPU client filters-out the hybrid solvers)
-        config['client'] = 'base'
+        # we want a Hybrid solver by default, but allow override
+        config.setdefault('client', 'hybrid')
 
         if solver is None:
             solver = {}
 
         if isinstance(solver, abc.Mapping):
+            # TODO: instead of solver selection, try with user's default first
             if solver.setdefault('category', 'hybrid') != 'hybrid':
                 raise ValueError("the only 'category' this sampler supports is 'hybrid'")
             if solver.setdefault('supported_problem_types__contains', 'bqm') != 'bqm':
                 raise ValueError("the only problem type this sampler supports is 'bqm'")
 
+            # prefer the latest version, but allow kwarg override
+            solver.setdefault('order_by', '-version')
+
         self.client = Client.from_config(
             solver=solver, connection_close=connection_close, **config)
 
-        self.solver = self.client.get_solver(order_by='-version')
+        self.solver = self.client.get_solver()
 
         # For explicitly named solvers:
         if self.properties.get('category') != 'hybrid':
diff --git a/dwave/system/utilities.py b/dwave/system/utilities.py
index ddf83f6..2dea158 100644
--- a/dwave/system/utilities.py
+++ b/dwave/system/utilities.py
@@ -47,7 +47,7 @@ def common_working_graph(graph0, graph1):
         >>> import dwave_networkx as dnx
         >>> from dwave.system import DWaveSampler, common_working_graph
         ...
-        >>> sampler = DWaveSampler(solver={'qpu': True})
+        >>> sampler = DWaveSampler()
         >>> C4 = dnx.chimera_graph(4)  # a 4x4 lattice of Chimera tiles
         >>> c4_working_graph = common_working_graph(C4, sampler.adjacency)   
 
diff --git a/requirements.txt b/requirements.txt
index eb54766..93ea17a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
 --extra-index-url https://pypi.dwavesys.com/simple
 
 dimod==0.9.6
-dwave-cloud-client==0.7.5
+dwave-cloud-client==0.8.0
 dwave-networkx==0.8.4
 dwave-drivers==0.4.4
 dwave-tabu==0.2.2
diff --git a/setup.py b/setup.py
index e3c1e8d..f89a34b 100644
--- a/setup.py
+++ b/setup.py
@@ -26,7 +26,7 @@ exec(open(os.path.join(".", "dwave", "system", "package_info.py")).read())
 
 
 install_requires = ['dimod>=0.9.6,<0.10.0',
-                    'dwave-cloud-client>=0.7.5,<0.8.0',
+                    'dwave-cloud-client>=0.8.0,<0.9.0',
                     'dwave-networkx>=0.8.4',
                     'networkx>=2.0,<3.0',
                     'homebase>=1.0.0,<2.0.0',

Specialized samplers for QPU & hybrid solvers + a new general one
Continuing the discussion from #278 here. In short, the proposal so far is:

- [x] (A) Specialize `DWaveSampler` for QPU solvers by using `client=qpu` and leave `solver` features undefined.

- [x] (B) Specialize `LeapHybridSampler` for hybrid solvers, with `client=hybrid`.

- [ ] ~(C) Introduce a new general sampler (name TBD), which will use the generic `client=base`, it will support structured and unstructured solvers, and it won't imply any solver features. Ideally, this sampler would be easy to subclass. Potentially implement `DWaveSampler` and `LeapHybridSampler` as such subclasses.~

- [ ] (D) Specialize `DWaveCliqueSampler` for QPU solvers by using `client=qpu` and leave `solver` features undefined.
diff --git a/tests/qpu/test_dwavecliquesampler.py b/tests/qpu/test_dwavecliquesampler.py
index ac8dcb0..5cdd238 100644
--- a/tests/qpu/test_dwavecliquesampler.py
+++ b/tests/qpu/test_dwavecliquesampler.py
@@ -24,8 +24,7 @@ from dwave.system import DWaveCliqueSampler
 class TestDWaveCliqueSampler(unittest.TestCase):
     def test_chimera(self):
         try:
-            sampler = DWaveCliqueSampler(
-                solver=dict(topology__type='chimera', qpu=True))
+            sampler = DWaveCliqueSampler(solver=dict(topology__type='chimera'))
         except (ValueError, ConfigFileError, SolverNotFoundError):
             raise unittest.SkipTest("no Chimera-structured QPU available")
 
@@ -40,8 +39,7 @@ class TestDWaveCliqueSampler(unittest.TestCase):
 
     def test_pegasus(self):
         try:
-            sampler = DWaveCliqueSampler(
-                solver=dict(topology__type='pegasus', qpu=True))
+            sampler = DWaveCliqueSampler(solver=dict(topology__type='pegasus'))
         except (ValueError, ConfigFileError, SolverNotFoundError):
             raise unittest.SkipTest("no Pegasus-structured QPU available")
 
diff --git a/tests/qpu/test_dwavesampler.py b/tests/qpu/test_dwavesampler.py
index ac7293f..d530e81 100644
--- a/tests/qpu/test_dwavesampler.py
+++ b/tests/qpu/test_dwavesampler.py
@@ -14,11 +14,13 @@
 #
 # =============================================================================
 import unittest
+from unittest import mock
 
 import numpy
 
 import dimod
 from dwave.cloud.exceptions import ConfigFileError
+from dwave.cloud.client import Client
 
 from dwave.system.samplers import DWaveSampler
 
@@ -28,7 +30,7 @@ class TestDWaveSampler(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         try:
-            cls.qpu = DWaveSampler(solver=dict(qpu=True))
+            cls.qpu = DWaveSampler()
         except (ValueError, ConfigFileError):
             raise unittest.SkipTest("no qpu available")
 
@@ -113,8 +115,7 @@ class TestMissingQubits(unittest.TestCase):
     def setUpClass(cls):
         try:
             # get a QPU with less than 100% yield
-            cls.qpu = DWaveSampler(solver=dict(qpu=True,
-                                               num_active_qubits__lt=2048))
+            cls.qpu = DWaveSampler(solver=dict(num_active_qubits__lt=2048))
         except (ValueError, ConfigFileError):
             raise unittest.SkipTest("no qpu available")
 
@@ -132,3 +133,26 @@ class TestMissingQubits(unittest.TestCase):
 
         self.assertEqual(set(sampleset.variables), set(sampler.nodelist))
         assert len(sampleset.variables) < 2048  # sanity check
+
+
+class TestClientSelection(unittest.TestCase):
+
+    def test_client_type(self):
+        with mock.patch('dwave.cloud.qpu.Client') as qpu:
+            self.assertEqual(DWaveSampler().client, qpu())
+            self.assertEqual(DWaveSampler(client='qpu').client, qpu())
+
+        with mock.patch('dwave.cloud.sw.Client') as sw:
+            self.assertEqual(DWaveSampler(client='sw').client, sw())
+
+        with mock.patch('dwave.cloud.hybrid.Client') as hybrid:
+            self.assertEqual(DWaveSampler(client='hybrid').client, hybrid())
+
+    def test_base_client(self):
+        # to test 'base' client instantiation offline,
+        # we would need a mock client and a mock solver
+        try:
+            self.assertEqual(type(DWaveSampler(client=None).client), Client)
+            self.assertEqual(type(DWaveSampler(client='base').client), Client)
+        except (ValueError, ConfigFileError):
+            raise unittest.SkipTest("no API token available")
diff --git a/tests/qpu/test_embeddingcomposite.py b/tests/qpu/test_embeddingcomposite.py
index 31f51ba..0b328f8 100644
--- a/tests/qpu/test_embeddingcomposite.py
+++ b/tests/qpu/test_embeddingcomposite.py
@@ -28,8 +28,8 @@ class TestEmbeddingCompositeExactSolver(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         try:
-            cls.qpu = DWaveSampler(solver=dict(
-                qpu=True, initial_state=True, anneal_schedule=True))
+            cls.qpu = DWaveSampler(
+                solver=dict(initial_state=True, anneal_schedule=True))
         except (ValueError, ConfigFileError):
             raise unittest.SkipTest("no qpu available")
 
diff --git a/tests/qpu/test_schedules.py b/tests/qpu/test_schedules.py
index 20dcae8..80be6f3 100644
--- a/tests/qpu/test_schedules.py
+++ b/tests/qpu/test_schedules.py
@@ -25,7 +25,7 @@ class TestRamp(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         try:
-            cls.qpu = DWaveSampler(solver=dict(qpu=True, h_gain_schedule=True))
+            cls.qpu = DWaveSampler(solver=dict(h_gain_schedule=True))
         except (ValueError, ConfigFileError):
             raise unittest.SkipTest("no qpu available")
 
diff --git a/tests/qpu/test_virtual_graph_composite.py b/tests/qpu/test_virtual_graph_composite.py
index 792a94d..f4206a2 100644
--- a/tests/qpu/test_virtual_graph_composite.py
+++ b/tests/qpu/test_virtual_graph_composite.py
@@ -30,7 +30,7 @@ class TestVirtualGraphComposite(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         try:
-            cls.qpu = DWaveSampler(solver=dict(qpu=True, flux_biases=True))
+            cls.qpu = DWaveSampler(solver=dict(flux_biases=True))
         except (ValueError, ConfigFileError):
             raise unittest.SkipTest("no qpu available")
 
diff --git a/tests/test_dwavecliquesampler.py b/tests/test_dwavecliquesampler.py
index e21fe0c..5a674bd 100644
--- a/tests/test_dwavecliquesampler.py
+++ b/tests/test_dwavecliquesampler.py
@@ -51,7 +51,7 @@ class MockDWaveSampler(dimod.RandomSampler, dimod.Structured):
 
 
 class MockChimeraDWaveSampler(MockDWaveSampler):
-    def __init__(self, order_by=None):
+    def __init__(self, **config):
         super().__init__()
 
         self.properties.update(topology=dict(shape=[4, 4, 4], type='chimera'))
@@ -75,7 +75,7 @@ class MockChimeraDWaveSampler(MockDWaveSampler):
 
 
 class MockPegasusDWaveSampler(MockDWaveSampler):
-    def __init__(self, order_by=None):
+    def __init__(self, **config):
         super().__init__()
 
         self.properties.update(topology=dict(shape=[6], type='pegasus'))
diff --git a/tests/test_dwavesampler.py b/tests/test_dwavesampler.py
index e2bc761..7268206 100644
--- a/tests/test_dwavesampler.py
+++ b/tests/test_dwavesampler.py
@@ -20,6 +20,7 @@ import warnings
 
 from collections import namedtuple
 from concurrent.futures import Future
+from unittest import mock
 from uuid import uuid4
 
 import numpy as np
@@ -32,13 +33,6 @@ from dwave.cloud.exceptions import SolverOfflineError, SolverNotFoundError
 from dwave.system.samplers import DWaveSampler
 from dwave.system.warnings import EnergyScaleWarning, TooFewSamplesWarning
 
-try:
-    # py3
-    import unittest.mock as mock
-except ImportError:
-    # py2
-    import mock
-
 
 C16 = dnx.chimera_graph(16)
 
@@ -106,25 +100,37 @@ class TestDwaveSampler(unittest.TestCase):
         self.sampler.solver = MockSolver()
 
     @mock.patch('dwave.system.samplers.dwave_sampler.Client')
-    def test_solver_init(self, MockClient):
-        """Deprecation warning is raised for `solver_features` use, but it still works."""
-
-        # assertWarns not available in py2
-        with warnings.catch_warnings(record=True) as w:
-            warnings.simplefilter("always")
-            DWaveSampler(solver_features={'qpu': True})
-            self.assertEqual(len(w), 1)
-            self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
-
-        with warnings.catch_warnings(record=True) as w:
-            warnings.simplefilter("always")
-            DWaveSampler(solver={'qpu': True})
-            self.assertEqual(len(w), 0)
-
-        MockClient.reset_mock()
+    def test_init_default(self, MockClient):
+        """QPU with the highest number of qubits chosen by default."""
+
+        sampler = DWaveSampler()
+
+        MockClient.from_config.assert_called_once_with(
+            client='qpu',
+            defaults={'solver': {'order_by': '-num_active_qubits'}})
+
+    @mock.patch('dwave.system.samplers.dwave_sampler.Client')
+    def test_init_generic_behavior(self, MockClient):
+        """Generic solver behavior (default prior to 0.10.0) can be forced."""
+
+        sampler = DWaveSampler(client='base')
+
+        MockClient.from_config.assert_called_once_with(
+            client='base',
+            defaults={'solver': {'order_by': '-num_active_qubits'}})
+
+    @mock.patch('dwave.system.samplers.dwave_sampler.Client')
+    def test_init_solver(self, MockClient):
+        """QPU can be explicitly selected (old default usage example)"""
+
         solver = {'qpu': True, 'num_qubits__gt': 1000}
+
         sampler = DWaveSampler(solver=solver)
-        MockClient.from_config.assert_called_once_with(solver=solver)
+
+        MockClient.from_config.assert_called_once_with(
+            client='qpu',
+            solver=solver,
+            defaults={'solver': {'order_by': '-num_active_qubits'}})
 
     def test_sample_ising_variables(self):
 
diff --git a/tests/test_leaphybridsolver.py b/tests/test_leaphybridsolver.py
index 9964ae1..a14add6 100644
--- a/tests/test_leaphybridsolver.py
+++ b/tests/test_leaphybridsolver.py
@@ -18,6 +18,7 @@ import numpy as np
 
 import dimod
 from dwave.cloud import Client
+from dwave.cloud.exceptions import SolverNotFoundError
 
 try:
     # py3
@@ -40,13 +41,13 @@ class MockClient:
 
         self.args = kwargs
 
-    def get_solver(self, order_by=None):
+    def get_solver(self, **filters):
 
         if isinstance(self.args['solver'], str) and self.args['solver'] == 'not_hybrid_solver':
             return MockBadLeapHybridSolver()
 
         if self.args.get('client', 'base') not in ['base', 'hybrid']:
-            return MockBadLeapHybridSolver()
+            raise SolverNotFoundError
 
         return MockLeapHybridSolver()
 
@@ -61,21 +62,25 @@ class TestLeapHybridSampler(unittest.TestCase):
         mock_client.reset_mock()
         LeapHybridSampler()
         mock_client.from_config.assert_called_once_with(
-            client='base', connection_close=True,
+            client='hybrid', connection_close=True,
             solver={'category': 'hybrid',
-                    'supported_problem_types__contains': 'bqm'})
+                    'supported_problem_types__contains': 'bqm',
+                    'order_by': '-version'})
 
-        # Non-hybrid client setting is ignored?
+        # Non-hybrid client setting
         mock_client.reset_mock()
-        LeapHybridSampler(client='qpu')
+        with self.assertRaises(SolverNotFoundError):
+            LeapHybridSampler(client='qpu')
 
         # Explicitly set category to hybrid
         mock_client.reset_mock()
-        LeapHybridSampler(solver={'category': 'hybrid', 'supported_problem_types__contains': 'bqm'})
+        LeapHybridSampler(solver={'category': 'hybrid',
+                                  'supported_problem_types__contains': 'bqm'})
         mock_client.from_config.assert_called_once_with(
-            client='base', connection_close=True,
+            client='hybrid', connection_close=True,
             solver={'category': 'hybrid',
-                    'supported_problem_types__contains': 'bqm'})
+                    'supported_problem_types__contains': 'bqm',
+                    'order_by': '-version'})
 
         # Explicitly set category to not hybrid
         with self.assertRaises(ValueError):
@@ -85,27 +90,29 @@ class TestLeapHybridSampler(unittest.TestCase):
         mock_client.reset_mock()
         LeapHybridSampler(solver={'qpu': True})
         mock_client.from_config.assert_called_once_with(
-            client='base', connection_close=True,
+            client='hybrid', connection_close=True,
             solver={'qpu': True, 'category': 'hybrid',
-                    'supported_problem_types__contains': 'bqm'})
+                    'supported_problem_types__contains': 'bqm',
+                    'order_by': '-version'})
 
         mock_client.reset_mock()
-        LeapHybridSampler(solver={'qpu': True, 'anneal_schedule' :False})
+        LeapHybridSampler(solver={'qpu': True, 'anneal_schedule': False})
         mock_client.from_config.assert_called_once_with(
-            client='base', connection_close=True,
+            client='hybrid', connection_close=True,
             solver={'anneal_schedule': False, 'qpu': True, 'category': 'hybrid',
-                    'supported_problem_types__contains': 'bqm'})
+                    'supported_problem_types__contains': 'bqm',
+                    'order_by': '-version'})
 
         # Named solver: hybrid
         mock_client.reset_mock()
         LeapHybridSampler(solver="hybrid_solver")
         mock_client.from_config.assert_called_once_with(
-            client='base', connection_close=True, solver="hybrid_solver")
+            client='hybrid', connection_close=True, solver="hybrid_solver")
 
         mock_client.reset_mock()
         LeapHybridSampler(connection_close=False, solver="hybrid_solver")
         mock_client.from_config.assert_called_once_with(
-            client='base', connection_close=False, solver="hybrid_solver")
+            client='hybrid', connection_close=False, solver="hybrid_solver")
 
         # Named solver: non-hybrid
         with self.assertRaises(ValueError):
@@ -115,18 +122,20 @@ class TestLeapHybridSampler(unittest.TestCase):
         mock_client.reset_mock()
         LeapHybridSampler(connection_close=False)
         mock_client.from_config.assert_called_once_with(
-            client='base', connection_close=False,
+            client='hybrid', connection_close=False,
             solver={'category': 'hybrid',
-                    'supported_problem_types__contains': 'bqm'})
+                    'supported_problem_types__contains': 'bqm',
+                    'order_by': '-version'})
 
         mock_client.reset_mock()
         LeapHybridSampler(connection_close=False,
                           solver={'category': 'hybrid',
                                   'supported_problem_types__contains': 'bqm'})
         mock_client.from_config.assert_called_once_with(
-            client='base', connection_close=False,
+            client='hybrid', connection_close=False,
             solver={'category': 'hybrid',
-                    'supported_problem_types__contains': 'bqm'})
+                    'supported_problem_types__contains': 'bqm',
+                    'order_by': '-version'})
 
     @mock.patch('dwave.system.samplers.leap_hybrid_sampler.Client')
     def test_sample_bqm(self, mock_client):

pip install -e .[drivers] --extra-index-url https://pypi.dwavesys.com/simple
parse_log_pytest
requirements.txt
coverage codecov pytest
apt-get update apt-get install -y gcc python3-dev
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi @ file:///croot/certifi_1671487769961/work/certifi
charset-normalizer==3.4.1
click==8.1.8
codecov==2.1.13
coverage==7.2.7
decorator==4.4.2
dimod==0.9.6
dwave-cloud-client==0.7.5
dwave-drivers==0.4.4
dwave-networkx==0.8.4
-e git+https://github.com/dwavesystems/dwave-system.git@fd1d5936ffa5ae3fa2539e619202c3f0e07fd64d#egg=dwave_system
dwave-tabu==0.2.2
exceptiongroup==1.2.2
fasteners==0.19
homebase==1.0.1
idna==3.10
importlib-metadata==6.7.0
iniconfig==2.0.0
minorminer==0.2.0
mock==2.0.0
networkx==2.6.3
numpy==1.18.0
packaging==24.0
pbr==6.1.1
plucky==0.4.3
pluggy==1.2.0
PySocks==1.7.1
pytest==7.4.4
python-dateutil==2.9.0.post0
requests==2.31.0
scipy==1.7.3
six==1.11.0
tomli==2.0.1
typing_extensions==4.7.1
urllib3==2.0.7
zipp==3.15.0

name: dwave-system
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - charset-normalizer==3.4.1
      - click==8.1.8
      - codecov==2.1.13
      - coverage==7.2.7
      - decorator==4.4.2
      - dimod==0.9.6
      - dwave-cloud-client==0.7.5
      - dwave-drivers==0.4.4
      - dwave-networkx==0.8.4
      - dwave-tabu==0.2.2
      - exceptiongroup==1.2.2
      - fasteners==0.19
      - homebase==1.0.1
      - idna==3.10
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - minorminer==0.2.0
      - mock==2.0.0
      - networkx==2.6.3
      - numpy==1.18.0
      - packaging==24.0
      - pbr==6.1.1
      - plucky==0.4.3
      - pluggy==1.2.0
      - pysocks==1.7.1
      - pytest==7.4.4
      - python-dateutil==2.9.0.post0
      - requests==2.31.0
      - scipy==1.7.3
      - six==1.11.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - zipp==3.15.0
prefix: /opt/conda/envs/dwave-system

tests/qpu/test_dwavesampler.py::TestClientSelection::test_client_type tests/test_dwavesampler.py::TestDwaveSampler::test_init_default tests/test_dwavesampler.py::TestDwaveSampler::test_init_generic_behavior tests/test_dwavesampler.py::TestDwaveSampler::test_init_solver tests/test_leaphybridsolver.py::TestLeapHybridSampler::test_solver_init
tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_api tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_clique tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_ferromagnet_chimera tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_largest_clique tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjArrayBQM_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjArrayBQM_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjArrayBQM_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjArrayBQM_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjDictBQM_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjDictBQM_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjDictBQM_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjDictBQM_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjMapBQM_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjMapBQM_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjMapBQM_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjMapBQM_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjVectorBQM_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjVectorBQM_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjVectorBQM_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_AdjVectorBQM_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_BinaryQuadraticModel_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_BinaryQuadraticModel_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_BinaryQuadraticModel_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_binary_BinaryQuadraticModel_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_ising_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_ising_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_ising_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_ising_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_qubo_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_qubo_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_qubo_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_qubo_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjArrayBQM_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjArrayBQM_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjArrayBQM_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjArrayBQM_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjDictBQM_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjDictBQM_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjDictBQM_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjDictBQM_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjMapBQM_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjMapBQM_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjMapBQM_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjMapBQM_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjVectorBQM_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjVectorBQM_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjVectorBQM_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_AdjVectorBQM_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_BinaryQuadraticModel_1path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_BinaryQuadraticModel_1var_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_BinaryQuadraticModel_2path_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_sample_spin_BinaryQuadraticModel_empty_<dwave.system.samplers.clique.DWaveCliqueSampler tests/test_dwavecliquesampler.py::TestDWaveCliqueSampler::test_too_large tests/test_dwavesampler.py::TestDwaveSampler::test_failover_false tests/test_dwavesampler.py::TestDwaveSampler::test_failover_notfound_noretry tests/test_dwavesampler.py::TestDwaveSampler::test_failover_offline tests/test_dwavesampler.py::TestDwaveSampler::test_sample_ising_variables tests/test_dwavesampler.py::TestDwaveSampler::test_sample_qubo_variables tests/test_dwavesampler.py::TestDwaveSampler::test_to_networkx_chimera tests/test_dwavesampler.py::TestDwaveSampler::test_to_networkx_pegasus tests/test_dwavesampler.py::TestDwaveSampler::test_warnings_energy_range tests/test_dwavesampler.py::TestDwaveSampler::test_warnings_sampling_error tests/test_dwavesampler.py::TestDWaveSamplerAnnealSchedule::test_typical tests/test_leaphybridsolver.py::TestLeapHybridSampler::test_sample_bqm tests/test_leaphybridsolver.py::TestLeapHybridSampler::test_sample_ising_variables tests/test_leaphybridsolver.py::TestLeapHybridSampler::test_sample_qubo_variables
dwave/system/samplers/clique.py setup.py docs/reference/minimize_energy/dwave.embedding.chain_breaks.MinimizeEnergy.rst dwave/system/samplers/leap_hybrid_sampler.py dwave/system/utilities.py dwave/system/samplers/dwave_sampler.py requirements.txt
dwave/system/samplers/clique.py setup.py docs/reference/minimize_energy/dwave.embedding.chain_breaks.MinimizeEnergy.rst dwave/system/samplers/leap_hybrid_sampler.py dwave/system/utilities.py dwave/system/samplers/dwave_sampler.py requirements.txt