Skip to content

Commit

Permalink
refactor type annotations using Python 3.9+ syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
robhudson authored and willkg committed Oct 24, 2024
1 parent c36771b commit 787a7ec
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 103 deletions.
4 changes: 2 additions & 2 deletions src/everett/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
version as importlib_version,
PackageNotFoundError,
)
from typing import Callable, List, Union
from typing import Callable, Union


try:
Expand Down Expand Up @@ -60,7 +60,7 @@ class DetailedConfigurationError(ConfigurationError):
"""Base class for configuration errors that have a msg, namespace, key, and parser."""

def __init__(
self, msg: str, namespace: Union[List[str], None], key: str, parser: Callable
self, msg: str, namespace: Union[list[str], None], key: str, parser: Callable
):
self.msg = msg
self.namespace = namespace
Expand Down
10 changes: 5 additions & 5 deletions src/everett/ext/inifile.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import logging
import os
from typing import Dict, List, Optional, Union
from typing import Optional, Union

from configobj import ConfigObj

Expand Down Expand Up @@ -124,7 +124,7 @@ class ConfigIniEnv:
"""

def __init__(self, possible_paths: Union[str, List[str]]) -> None:
def __init__(self, possible_paths: Union[str, list[str]]) -> None:
"""
:param possible_paths: either a single string with a file path (e.g.
``"/etc/project.ini"`` or a list of strings with file paths
Expand All @@ -147,11 +147,11 @@ def __init__(self, possible_paths: Union[str, List[str]]) -> None:
if not self.path:
logger.debug("No INI file found: %s", possible_paths)

def parse_ini_file(self, path: str) -> Dict:
def parse_ini_file(self, path: str) -> dict:
"""Parse ini file at ``path`` and return dict."""
cfgobj = ConfigObj(path, list_values=False)

def extract_section(namespace: List[str], d: Dict) -> Dict:
def extract_section(namespace: list[str], d: dict) -> dict:
cfg = {}
for key, val in d.items():
if isinstance(d[key], dict):
Expand All @@ -164,7 +164,7 @@ def extract_section(namespace: List[str], d: Dict) -> Dict:
return extract_section([], cfgobj.dict())

def get(
self, key: str, namespace: Optional[List[str]] = None
self, key: str, namespace: Optional[list[str]] = None
) -> Union[str, NoValue]:
"""Retrieve value for key."""
if not self.path:
Expand Down
12 changes: 6 additions & 6 deletions src/everett/ext/yamlfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import logging
import os
from typing import Dict, List, Optional, Union
from typing import Optional, Union

import yaml

Expand Down Expand Up @@ -109,7 +109,7 @@ class ConfigYamlEnv:
"""

def __init__(self, possible_paths: Union[str, List[str]]) -> None:
def __init__(self, possible_paths: Union[str, list[str]]) -> None:
"""
:param possible_paths: either a single string with a file path (e.g.
``"/etc/project.yaml"`` or a list of strings with file paths
Expand All @@ -132,15 +132,15 @@ def __init__(self, possible_paths: Union[str, List[str]]) -> None:
if not self.path:
logger.debug("No YAML file found: %s", possible_paths)

def parse_yaml_file(self, path: str) -> Dict:
def parse_yaml_file(self, path: str) -> dict:
"""Parse yaml file at ``path`` and return a dict."""
with open(path, "r") as fp:
with open(path) as fp:
data = yaml.safe_load(fp)

if not data:
return {}

def traverse(namespace: List[str], d: Dict) -> Dict:
def traverse(namespace: list[str], d: dict) -> dict:
cfg = {}
for key, val in d.items():
if isinstance(val, dict):
Expand All @@ -161,7 +161,7 @@ def traverse(namespace: List[str], d: Dict) -> Dict:
return traverse([], data)

def get(
self, key: str, namespace: Optional[List[str]] = None
self, key: str, namespace: Optional[list[str]] = None
) -> Union[str, NoValue]:
"""Retrieve value for key."""
if not self.path:
Expand Down
59 changes: 27 additions & 32 deletions src/everett/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,10 @@
from typing import (
Any,
Callable,
Dict,
Iterable,
List,
Mapping,
Optional,
Tuple,
Type,
Union,
)
from collections.abc import Iterable, Mapping

from everett import (
ConfigurationError,
Expand Down Expand Up @@ -101,7 +96,7 @@ def qualname(thing: Any) -> str:


def build_msg(
namespace: Optional[List[str]],
namespace: Optional[list[str]],
key: Optional[str],
parser: Optional[Callable],
msg: str = "",
Expand Down Expand Up @@ -156,7 +151,7 @@ class Config:
def __init__(
self,
default: Union[str, NoValue] = NO_VALUE,
alternate_keys: Optional[List[str]] = None,
alternate_keys: Optional[list[str]] = None,
doc: str = "",
parser: Callable = str,
meta: Any = None,
Expand Down Expand Up @@ -201,7 +196,7 @@ def __eq__(self, obj: Any) -> bool:
)


def get_config_for_class(cls: Type) -> Dict[str, Tuple[Option, Type]]:
def get_config_for_class(cls: type) -> dict[str, tuple[Option, type]]:
"""Roll up configuration options for this class and parent classes.
This handles subclasses overriding configuration options in parent classes.
Expand Down Expand Up @@ -229,8 +224,8 @@ def get_config_for_class(cls: Type) -> Dict[str, Tuple[Option, Type]]:


def traverse_tree(
instance: Any, namespace: Optional[List[str]] = None
) -> Iterable[Tuple[List[str], str, Option, Any]]:
instance: Any, namespace: Optional[list[str]] = None
) -> Iterable[tuple[list[str], str, Option, Any]]:
"""Traverses a tree of objects and computes the configuration for it
Note: This expects the tree not to have any loops or repeated nodes.
Expand Down Expand Up @@ -270,7 +265,7 @@ def traverse_tree(
return options


def parse_env_file(envfile: Iterable[str]) -> Dict:
def parse_env_file(envfile: Iterable[str]) -> dict:
"""Parse the content of an iterable of lines as ``.env``.
Return a dict of config variables.
Expand Down Expand Up @@ -482,7 +477,7 @@ def get_parser(parser: Callable) -> Callable:
return parser


def listify(thing: Any) -> List[Any]:
def listify(thing: Any) -> list[Any]:
"""Convert thing to a list.
If thing is a string, then returns a list of thing. Otherwise
Expand All @@ -500,7 +495,7 @@ def listify(thing: Any) -> List[Any]:
return thing


def generate_uppercase_key(key: str, namespace: Optional[List[str]] = None) -> str:
def generate_uppercase_key(key: str, namespace: Optional[list[str]] = None) -> str:
"""Given a key and a namespace, generates a final uppercase key.
>>> generate_uppercase_key("foo")
Expand Down Expand Up @@ -568,7 +563,7 @@ def __init__(self, parser: Callable, delimiter: str = ","):
self.sub_parser = parser
self.delimiter = delimiter

def __call__(self, value: str) -> List[Any]:
def __call__(self, value: str) -> list[Any]:
parser = get_parser(self.sub_parser)
if value:
return [parser(token.strip()) for token in value.split(self.delimiter)]
Expand All @@ -583,7 +578,7 @@ class ConfigOverrideEnv:
"""Override configuration layer for testing."""

def get(
self, key: str, namespace: Optional[List[str]] = None
self, key: str, namespace: Optional[list[str]] = None
) -> Union[str, NoValue]:
"""Retrieve value for key."""
global _CONFIG_OVERRIDE
Expand Down Expand Up @@ -644,7 +639,7 @@ def __init__(self, obj: Any, force_lower: bool = True):
self.obj = obj

def get(
self, key: str, namespace: Optional[List[str]] = None
self, key: str, namespace: Optional[list[str]] = None
) -> Union[str, NoValue]:
"""Retrieve value for key."""
full_key = generate_uppercase_key(key, namespace)
Expand Down Expand Up @@ -727,11 +722,11 @@ class ConfigDictEnv:
"""

def __init__(self, cfg: Dict):
def __init__(self, cfg: dict):
self.cfg = {key.upper(): val for key, val in cfg.items()}

def get(
self, key: str, namespace: Optional[List[str]] = None
self, key: str, namespace: Optional[list[str]] = None
) -> Union[str, NoValue]:
"""Retrieve value for key."""
full_key = generate_uppercase_key(key, namespace)
Expand Down Expand Up @@ -795,7 +790,7 @@ class ConfigEnvFileEnv:
"""

def __init__(self, possible_paths: Union[str, List[str]]):
def __init__(self, possible_paths: Union[str, list[str]]):
self.data = {}
self.path = None

Expand All @@ -812,7 +807,7 @@ def __init__(self, possible_paths: Union[str, List[str]]):
break

def get(
self, key: str, namespace: Optional[List[str]] = None
self, key: str, namespace: Optional[list[str]] = None
) -> Union[str, NoValue]:
"""Retrieve value for key."""
full_key = generate_uppercase_key(key, namespace)
Expand Down Expand Up @@ -867,7 +862,7 @@ class ConfigOSEnv:
"""

def get(
self, key: str, namespace: Optional[List[str]] = None
self, key: str, namespace: Optional[list[str]] = None
) -> Union[str, NoValue]:
"""Retrieve value for key."""
full_key = generate_uppercase_key(key, namespace)
Expand All @@ -890,7 +885,7 @@ def get_runtime_config(
config: "ConfigManager",
component: Any,
traverse: Callable = traverse_tree,
) -> List[Tuple[List[str], str, Any, Option]]:
) -> list[tuple[list[str], str, Any, Option]]:
"""Returns configuration specification and values for a component tree
For example, if you had a tree of components instantiated, you could
Expand Down Expand Up @@ -989,7 +984,7 @@ class ConfigManager:

def __init__(
self,
environments: List[Any],
environments: list[Any],
doc: str = "",
msg_builder: Callable = build_msg,
with_override: bool = True,
Expand Down Expand Up @@ -1037,10 +1032,10 @@ def build_msg(namespace, key, parser, msg="", option_doc="", config_doc=""):
self.doc = doc
self.msg_builder = msg_builder

self.namespace: List[str] = []
self.namespace: list[str] = []

self.bound_component: Any = None
self.bound_component_prefix: List[str] = []
self.bound_component_prefix: list[str] = []
self.bound_component_options: Mapping[str, Any] = {}

self.original_manager = self
Expand Down Expand Up @@ -1084,7 +1079,7 @@ def basic_config(cls, env_file: str = ".env", doc: str = "") -> "ConfigManager":
return cls(environments=[ConfigOSEnv(), ConfigEnvFileEnv([env_file])], doc=doc)

@classmethod
def from_dict(cls, dict_config: Dict) -> "ConfigManager":
def from_dict(cls, dict_config: dict) -> "ConfigManager":
"""Create a ConfigManager with specified configuration as a Python dict.
This is shorthand for::
Expand Down Expand Up @@ -1112,7 +1107,7 @@ def get_bound_component(self) -> Any:
"""
return self.bound_component

def get_namespace(self) -> List[str]:
def get_namespace(self) -> list[str]:
"""Retrieve the complete namespace for this config object.
:returns: namespace as a list of strings
Expand All @@ -1139,7 +1134,7 @@ def clone(self) -> "ConfigManager":

return my_clone

def with_namespace(self, namespace: Union[List[str], str]) -> "ConfigManager":
def with_namespace(self, namespace: Union[list[str], str]) -> "ConfigManager":
"""Apply a namespace to this configuration.
Namespaces accumulate as you add them.
Expand Down Expand Up @@ -1200,10 +1195,10 @@ def with_options(self, component: Any) -> "ConfigManager":
def __call__(
self,
key: str,
namespace: Union[List[str], str, None] = None,
namespace: Union[list[str], str, None] = None,
default: Union[str, NoValue] = NO_VALUE,
default_if_empty: bool = True,
alternate_keys: Optional[List[str]] = None,
alternate_keys: Optional[list[str]] = None,
doc: str = "",
parser: Callable = str,
raise_error: bool = True,
Expand Down Expand Up @@ -1475,7 +1470,7 @@ def __enter__(self) -> None:

def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_type: Optional[type[BaseException]],
exc_value: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
Expand Down
Loading

0 comments on commit 787a7ec

Please sign in to comment.