Skip to content

Nestable, tab-able options for use in Python programs

License

Notifications You must be signed in to change notification settings

topper-123/optioneer

Repository files navigation

optioneer

https://travis-ci.com/topper-123/optioneer.svg?branch=master

optioneer makes in-program options, that:

  • can be nested and grouped,
  • can be discovered in the REPL when tab-completing,
  • can give each option a doc string, for easily explaining the option
  • may deprecate options according to a transparent deprecation cycle
  • may validate options when they're changed
  • can do custom callbacks

optioneer does not do CLI options, but is used strictly to create in-program options.

As such, its best use case is probably to create options for library code that is used by other programs. In fact, optioneer is a reworked and self-contained version of the core/config.py module in pandas and options created by optioneer work very similarly to pandas.options.

Installation

Installing is easy using pip:

pip install optioneer

Usage guide

In a config.py file in your package, set up your options:

from optioneer import Optioneer

options_maker = Optioneer()
options_maker.register_option('api_key', 'abcdefg', doc='The API key to our service')
options_maker.register_option('display.width', 200, doc='Width of our display')
options_maker.register_option('display.height', 200, doc='Height of our display')
options_maker.register_option('color', 'red', validator=options_maker.is_str)

options = options_maker.options

Then, in the relevant location of your library, just do from .config import options and you've got your options set up.

Users of your library can now access the options from the chosen location in your package. For example, if you've made it available in the top-level __init__.py of a package called mylib:

>>> import mylib
>>> mylib.options
Options(
  api_key: 'abcdefg' [default: 'abcdefg']
      The API key to our service
  color: 'red' [default: 'red']
      No description available.
  display.height: 200 [default: 200]
      Height of our display
  display.width: 200 [default: 200]
      Width of our display
  )

Notice how the repr output shows the relevant options and their descriptions.

The relevant options are discoverable using tabs in the REPL:

>>> mylib.options.<TAB>
option.api_key options.color options.display
>>> mylib.options.display.<TAB>
options.display.height options.display.width

You can also easily see the options and their values and docs for subgroups in the repr string:

>>> mylib.options.display
Options(
  display.height: 200 [default: 200]
      Height of our display
  display.width: 200 [default: 200]
      Width of our display
  )

Callbacks

By providing a callback when registering options, changed options may trigger a desired actions. For example, if you in your config.py do:

def callback_func(key, value):
    print("key: {!r} value: {!r}".format(key, value))
options_maker.register_option('a.args', True, callback=callback_func)

Then changing that option will trigger the callback:

>>> mylib.options.args = False
key: 'a.args' value: False

Of course, the callback can be more realistic than in the example above, e.g. logging or setting some internal option or something else.

Deprecating options

If you need to deprecate an option, optioneer allows you to do that:

options_maker.deprecate_option('api_key', msg='An api key is no longer needed')

Now your users get a deprecation warning, if they access this option:

>>> mylib.options.api_key
An api key is no longer needed
C:\Users\TP\Documents\Python\optioneer\optioneer\lib.py:677: FutureWarning: An api key is no longer needed
  warnings.warn(deprecated_option.msg, FutureWarning)
Out[20]: 'abcdefg'

If an options should be renamed and/or a marker should be set for when the option will be removed, that is also possible:

options_maker.register_option('display.length', 300, doc='Length of our display')
options_maker.deprecate_option('display.height', redirect_key='display.length',
                               removal_version='v1.3')

Then accessing the display.height option will show

>>> mylib.options.display.height
C:\Users\TP\Documents\Python\optioneer\optioneer\lib.py:689: FutureWarning: 'display.height' is deprecated and will be removed in v1.3, please use 'display.length' instead.
  warnings.warn(msg, FutureWarning)
Out[24]: 300

Deprecated options will not show up in the repr output or when tab-completing.

Dependencies

optioneer has no external dependencies.

optioneer uses pytest for testing.

License

optioneer is BSD 3-licensed.

About

Nestable, tab-able options for use in Python programs

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages