Skip to content

Commit

Permalink
Update options to be a mapping instead of a simple namespace
Browse files Browse the repository at this point in the history
This commit changes the options class to be a mapping instead of a
simple namespace. While we wanted to preserve attribute based access
primarily the simple namespace is too limited in practice and involves a
lot of hacking around the internals such as frequent calls to
Options.__dict__ to get an iterator of fields in the options. To improve
the usability of the class without breaking existing users this changes
the base class to be a MutableMapping and adds the necessary methods to
make it usable like a dict or a simple namespace.
  • Loading branch information
mtreinish committed May 7, 2021
1 parent 48305a8 commit 763141f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
2 changes: 1 addition & 1 deletion qiskit/providers/basicaer/qasm_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def __init__(self, configuration=None, provider=None, **fields):
self._shots = 0
self._memory = False
self._initial_statevector = self.options.get("initial_statevector")
self._chop_threshold = self.options.get("chop_threashold")
self._chop_threshold = self.options.get("chop_threshold")
self._qobj_config = None
# TEMP
self._sample_measure = False
Expand Down
61 changes: 57 additions & 4 deletions qiskit/providers/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

"""Container class for backend options."""

import types
from collections.abc import MutableMapping


class Options(types.SimpleNamespace):
class Options(MutableMapping):
"""Base options object
This class is the abstract class that all backend options are based
Expand All @@ -26,10 +26,63 @@ class Options(types.SimpleNamespace):
options.
"""

_dict = {}

def __init__(self, **kwargs):
self._dict = {}
super().__init__()
self._dict = kwargs

def __getattr__(self, field):
if field == "_dict":
super().__getattribute__(field)
elif field not in self._dict:
raise AttributeError("%s not a valid option" % field)
self._dict[field]

def __getitem__(self, field):
if field not in self._dict:
raise KeyError("%s not a valid option" % field)
self._dict.get(field, default)

def __setitem__(self, field, value):
if field in self._dict:
self._dict[field] = value
else:
raise KeyError("%s not a valid option" % field)

def __delitem__(self, field):
del self._dict[field]

def __len__(self):
return len(self._dict)

def __iter__(self):
return iter(self._dict)

def __setattr__(self, field, value):
if field == "_dict":
super().__setattr__(field, value)
elif field in self._dict:
self._dict[field] = value
else:
raise AttributeError("%s not a valid option" % field)

def __repr__(self):
return "Options(%s)" % ", ".join("k=v" for k, v in self._dict.items())

def update_options(self, **fields):
"""Update options with kwargs"""
self.__dict__.update(fields)
self._dict.update(fields)

def get(self, field, default=None):
"""Get an option value for a given key."""
return getattr(self, field, default)
return self._dict.get(field, default)

def __dict__(self):
return self._dict

def __eq__(self, other):
if isinstance(other, Options):
return self._dict == other._dict
return NotImplementedError

0 comments on commit 763141f

Please sign in to comment.