Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 50 additions & 5 deletions brian2/core/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
from brian2.units.fundamentalunits import Quantity, have_same_dimensions
from brian2.utils.stringtools import deindent, indent

__all__ = ["PreferenceError", "BrianPreference", "prefs", "brian_prefs"]
__all__ = [
"PreferenceError",
"BrianPreference",
"prefs",
"brian_prefs",
"brian_configuration",
]


def parse_preference_name(name):
Expand Down Expand Up @@ -304,7 +310,7 @@ def _restore(self):
"""
self.prefs.update(**self.backup_prefs)

def _get_one_documentation(self, basename, link_targets):
def _get_one_documentation(self, basename, valuefunc, link_targets):
"""
Document a single category of preferences.
"""
Expand All @@ -323,7 +329,7 @@ def _get_one_documentation(self, basename, link_targets):
if link_targets:
# Make a link target
s += f".. _brian-pref-{linkname}:\n\n"
s += f"``{name}`` = ``{pref.representor(pref.default)}``\n"
s += f"``{name}`` = ``{pref.representor(valuefunc(pref, name))}``\n"
s += indent(deindent(pref.docs, docstring=True))
s += "\n\n"
return s
Expand All @@ -345,13 +351,45 @@ def get_documentation(self, basename=None, link_targets=True):
s += basename + "\n" + '"' * len(basename) + "\n\n"
else:
s += "**" + basename + "**\n\n"
s += self._get_one_documentation(basename, link_targets)
s += self._get_one_documentation(
basename, lambda pref, fullname: pref.default, link_targets
)
# for basename in self.pref_register:
# s += '**' + basename + '**\n\n'
# s += basename+'\n'+'"'*len(basename)+'\n\n'
# s += self._get_one_documentation(basename, link_targets)
else:
s += self._get_one_documentation(basename, link_targets)
s += self._get_one_documentation(
basename, lambda pref, fullname: pref.default, link_targets
)

return s

def get_configuration(self, basename=None):
"""
Generates a string documenting the current values of all preferences
with the given `basename`. If no `basename` is given, all preferences
are documented.
"""
s = ""
if basename is None:
basenames = sorted(
[tuple(basename.split(".")) for basename in self.pref_register]
)
for basename in basenames:
lev = len(basename)
basename = ".".join(basename)
if lev == 1:
s += basename + "\n" + '"' * len(basename) + "\n\n"
else:
s += "**" + basename + "**\n\n"
s += self._get_one_documentation(
basename, lambda pref, fullname: self[fullname], False
)
else:
s += self._get_one_documentation(
basename, lambda pref, fullname: self[fullname], False
)

return s

Expand Down Expand Up @@ -741,3 +779,10 @@ def __getitem__(self, item):


brian_prefs = ErrorRaiser()


def brian_configuration():
"""
Return a string summarizing the current Brian preferences.
"""
return prefs.get_configuration()
1 change: 1 addition & 0 deletions brian2/only.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def restore_initial_state():
"BrianPreference",
"prefs",
"brian_prefs",
"brian_configuration",
"Clock",
"EventClock",
"defaultclock",
Expand Down
41 changes: 40 additions & 1 deletion brian2/tests/test_preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from numpy import float32, float64
from numpy.testing import assert_equal

from brian2 import amp, restore_initial_state, volt
from brian2 import amp, brian_configuration, prefs, restore_initial_state, volt
from brian2.core.preferences import (
BrianGlobalPreferences,
BrianGlobalPreferencesView,
Expand Down Expand Up @@ -198,6 +198,45 @@ def test_brianglobalpreferences():
assert gp["a.b"] == 5


@pytest.mark.codegen_independent
def test_brian_configuration():
configuration = brian_configuration()
assert len(configuration)
assert "core" in configuration
assert "``core.default_float_dtype``" in configuration

gp = BrianGlobalPreferences()
gp.register_preferences(
"example",
"Example preferences",
value=BrianPreference(1, "Example value"),
)
example_configuration = gp.get_configuration()
assert "example" in example_configuration
assert "``example.value`` = ``1``" in example_configuration


@pytest.mark.codegen_independent
def test_brian_configuration_current_values():
original_configuration = brian_configuration()
try:
prefs["core.default_float_dtype"] = float32
changed_configuration = brian_configuration()
assert changed_configuration != original_configuration
assert "``core.default_float_dtype`` = ``float32``" in changed_configuration

prefs.reset_to_defaults()
reset_configuration = brian_configuration()
assert reset_configuration == original_configuration
finally:
restore_initial_state()


@pytest.mark.codegen_independent
def test_brian_configuration_importable():
assert callable(brian_configuration)


@pytest.mark.codegen_independent
def test_preference_name_access():
"""
Expand Down
6 changes: 6 additions & 0 deletions docs_sphinx/advanced/preferences.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ work, e.g. in ipython, as it offers autocompletion and documentation.
In ipython, ``prefs.codegen.cpp?`` would display a docstring with all
the preferences available in the ``codegen.cpp`` category.

To get a plain-text summary of the current preference values, use
`brian_configuration`::

>>> from brian2 import brian_configuration
>>> print(brian_configuration()) # doctest: +SKIP

Preference files
----------------

Expand Down
Loading