| """ |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| """ |
| |
| from typing import Optional, Any, Type, Union, Generic, TypeVar |
| from dataclasses import dataclass |
| |
| |
| @dataclass(frozen=True) |
| class Description: |
| """Configuration option description.""" |
| |
| text: str |
| |
| @staticmethod |
| def builder() -> 'DescriptionBuilder': |
| """Create a description builder.""" |
| return DescriptionBuilder() |
| |
| |
| class DescriptionBuilder: |
| """Builder for Description objects.""" |
| |
| def __init__(self): |
| self._text = "" |
| |
| def text(self, text: str) -> 'DescriptionBuilder': |
| """Set the description text.""" |
| self._text = text |
| return self |
| |
| def build(self) -> Description: |
| """Build the Description object.""" |
| return Description(text=self._text) |
| |
| |
| T = TypeVar('T') |
| |
| |
| class ConfigOption(Generic[T]): |
| """ |
| A ConfigOption describes a configuration parameter. It encapsulates the configuration |
| key, deprecated older versions of the key, and an optional default value for the configuration |
| parameter. |
| |
| ConfigOptions are built via the ConfigOptions class. Once created, a config |
| option is immutable. |
| """ |
| |
| EMPTY_DESCRIPTION = Description(text="") |
| |
| def __init__(self, |
| key: str, |
| clazz: Type, |
| description: Optional[Description] = None, |
| default_value: Any = None): |
| """ |
| Creates a new config option with fallback keys. |
| |
| Args: |
| key: The current key for that config option |
| clazz: Type of the ConfigOption value |
| description: Description for that option |
| default_value: The default value for this option |
| """ |
| if not key: |
| raise ValueError("Key must not be null.") |
| |
| self._key = key |
| self._clazz = clazz |
| self._description = description or self.EMPTY_DESCRIPTION |
| self._default_value = default_value |
| |
| def key(self) -> str: |
| """Gets the configuration key.""" |
| return self._key |
| |
| def get_clazz(self) -> Type: |
| """Gets the type class of this config option.""" |
| return self._clazz |
| |
| def description(self) -> Description: |
| """Returns the description of this option.""" |
| return self._description |
| |
| def has_default_value(self) -> bool: |
| """Checks if this option has a default value.""" |
| return self._default_value is not None |
| |
| def default_value(self) -> Any: |
| """Returns the default value, or None if there is no default value.""" |
| return self._default_value |
| |
| def with_description(self, description: Union[str, Description]) -> 'ConfigOption': |
| """ |
| Creates a new config option, using this option's key and default value, and adding the given |
| description. The given description is used when generation the configuration documentation. |
| Args: |
| description: The description for this option. |
| Returns: |
| A new config option, with given description. |
| """ |
| if isinstance(description, str): |
| desc = Description.builder().text(description).build() |
| else: |
| desc = description |
| |
| return ConfigOption( |
| key=self._key, |
| clazz=self._clazz, |
| description=desc, |
| default_value=self._default_value, |
| ) |
| |
| def __eq__(self, other) -> bool: |
| """Check equality with another ConfigOption.""" |
| if not isinstance(other, ConfigOption): |
| return False |
| |
| return (self._key == other._key and |
| self._default_value == other._default_value) |
| |
| def __hash__(self) -> int: |
| """Calculate hash code.""" |
| return hash((self._key, self._default_value)) |
| |
| def __str__(self) -> str: |
| """String representation of the config option.""" |
| return f"key: '{self._key}'; default_value: {self._default_value}" |