Skip to content

Commit

Permalink
Type base and project configs (#3414)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmreed authored Oct 31, 2022
1 parent 133a623 commit f003d5f
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 59 deletions.
23 changes: 13 additions & 10 deletions cumulusci/core/config/base_config.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import json
import logging
import os
import typing as T
import warnings
from datetime import date, datetime
from functools import lru_cache
from typing import Any, Dict, Optional

# turn on strictness.
# delete this when strictness is mandatory
Expand All @@ -19,13 +19,14 @@ def load_dates(x):
return {"$type": "date", "$value": x.isoformat()}


class BaseConfig(object):
class BaseConfig:
"""BaseConfig provides a common interface for nested access for all Config objects in CCI."""

defaults = {}
config: dict
logger: logging.Logger

def __init__(self, config=None, keychain=None):
def __init__(self, config: Optional[dict] = None, keychain=None):
if config is None:
self.config = {}
else:
Expand All @@ -52,15 +53,15 @@ def _load_config(self):
"""Subclasses may override this method to initialize :py:attr:`~config`"""
pass

def _serialize(self):
def _serialize(self) -> bytes:
return json.dumps(self.config, default=load_dates).encode("utf-8")

@classmethod
def _allowed_names(cls) -> T.Dict[str, type]:
def _allowed_names(cls) -> Dict[str, type]:
return getattr(cls, "__annotations__", {})

# long term plan is to get rid of this
def __getattr__(self, name):
def __getattr__(self, name: str) -> Any:
"""Look up a property in a sub-dictionary
Property names should be declared in each Config class with type annotations.
Expand All @@ -82,10 +83,10 @@ def __getattr__(self, name):

@classmethod
@lru_cache
def _all_allowed_names(cls):
def _all_allowed_names(cls) -> Dict[str, type]:
"Allowed names from this class and its base classes"
allowed_names_from_all_base_classes = (
baseclass._allowed_names()
baseclass._allowed_names() # type: ignore
for baseclass in cls.__mro__
if hasattr(baseclass, "_allowed_names")
)
Expand All @@ -94,11 +95,13 @@ def _all_allowed_names(cls):
ret.update(d)
return ret

def lookup(self, name, default=None, already_called_getattr=False):
def lookup(
self, name: str, default: Any = None, already_called_getattr: bool = False
) -> Any:
tree = name.split("__")
if name.startswith("_"):
raise AttributeError(f"Attribute {name} not found")
value = None
value: Any = None
value_found = False
config = self.config
if len(tree) > 1:
Expand Down
Loading

0 comments on commit f003d5f

Please sign in to comment.