Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pyupgrade hook #759

Merged
merged 5 commits into from Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 7 additions & 2 deletions .pre-commit-config.yaml
Expand Up @@ -3,7 +3,7 @@ default_language_version:
python: python3
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -16,6 +16,11 @@ repos:
rev: v3.1.0
hooks:
- id: reorder-python-imports
- repo: https://github.com/asottile/pyupgrade
rev: v2.34.0
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/ambv/black
rev: 22.3.0
hooks:
Expand All @@ -26,7 +31,7 @@ repos:
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.960
rev: v0.961
hooks:
- id: mypy
files: ^dynaconf/
10 changes: 5 additions & 5 deletions dynaconf/base.py
Expand Up @@ -66,7 +66,7 @@ def __init__(self, wrapped=None, **kwargs):
self.__resolve_config_aliases(kwargs)
compat_kwargs(kwargs)
self._kwargs = kwargs
super(LazySettings, self).__init__()
super().__init__()

if wrapped:
if self._django_override:
Expand Down Expand Up @@ -267,15 +267,15 @@ def __setattr__(self, name, value):
"""Allow `settings.FOO = 'value'` while keeping internal attrs."""

if name in RESERVED_ATTRS:
super(Settings, self).__setattr__(name, value)
super().__setattr__(name, value)
else:
self.set(name, value)

def __delattr__(self, name):
"""stores reference in `_deleted` for proper error management"""
self._deleted.add(name)
if hasattr(self, name):
super(Settings, self).__delattr__(name)
super().__delattr__(name)

def __contains__(self, item):
"""Respond to `item in settings`"""
Expand Down Expand Up @@ -902,7 +902,7 @@ def set(

self.store[key] = value
self._deleted.discard(key)
super(Settings, self).__setattr__(key, value)
super().__setattr__(key, value)

# set loader identifiers so cleaners know which keys to clean
if loader_identifier and loader_identifier in self.loaded_by_loaders:
Expand Down Expand Up @@ -1215,7 +1215,7 @@ def dynaconf(self):
internal methods and attrs.
"""

class AttrProxy(object):
class AttrProxy:
def __init__(self, obj):
self.obj = obj

Expand Down
7 changes: 3 additions & 4 deletions dynaconf/cli.py
Expand Up @@ -366,15 +366,14 @@ def init(ctx, fileformat, path, env, _vars, _secrets, wg, y, django):
ignore_line = ".secrets.*"
comment = "\n# Ignore dynaconf secret files\n"
if not gitignore_path.exists():
with io.open(str(gitignore_path), "w", encoding=ENC) as f:
with open(str(gitignore_path), "w", encoding=ENC) as f:
f.writelines([comment, ignore_line, "\n"])
else:
existing = (
ignore_line
in io.open(str(gitignore_path), encoding=ENC).read()
ignore_line in open(str(gitignore_path), encoding=ENC).read()
)
if not existing: # pragma: no cover
with io.open(str(gitignore_path), "a+", encoding=ENC) as f:
with open(str(gitignore_path), "a+", encoding=ENC) as f:
f.writelines([comment, ignore_line, "\n"])

click.echo(
Expand Down
2 changes: 1 addition & 1 deletion dynaconf/contrib/flask_dynaconf.py
Expand Up @@ -142,7 +142,7 @@ class DynaconfConfig(Config):

def __init__(self, _settings, _app, *args, **kwargs):
"""perform the initial load"""
super(DynaconfConfig, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

# Bring Dynaconf instance value to Flask Config
Config.update(self, _settings.store)
Expand Down
2 changes: 1 addition & 1 deletion dynaconf/loaders/__init__.py
Expand Up @@ -266,7 +266,7 @@ def write(filename, data, env=None):
loader_name = f"{filename.rpartition('.')[-1]}_loader"
loader = globals().get(loader_name)
if not loader:
raise IOError(f"{loader_name} cannot be found.")
raise OSError(f"{loader_name} cannot be found.")

data = DynaBox(data, box_settings={}).to_dict()
if loader is not py_loader and env and env not in data:
Expand Down
4 changes: 2 additions & 2 deletions dynaconf/loaders/base.py
Expand Up @@ -75,7 +75,7 @@ def get_source_data(self, files):
for source_file in files:
if source_file.endswith(self.extensions):
try:
with io.open(
with open(
source_file,
encoding=self.obj.get(
"ENCODING_FOR_DYNACONF", "utf-8"
Expand All @@ -85,7 +85,7 @@ def get_source_data(self, files):
self.obj._loaded_files.append(source_file)
if content:
data[source_file] = content
except IOError as e:
except OSError as e:
if ".local." not in source_file:
warnings.warn(
f"{self.identifier}_loader: {source_file} "
Expand Down
2 changes: 1 addition & 1 deletion dynaconf/loaders/ini_loader.py
Expand Up @@ -51,7 +51,7 @@ def write(settings_path, settings_data, merge=True):
"""
settings_path = Path(settings_path)
if settings_path.exists() and merge: # pragma: no cover
with io.open(
with open(
str(settings_path), encoding=default_settings.ENCODING_FOR_DYNACONF
) as open_file:
object_merge(ConfigObj(open_file).dict(), settings_data)
Expand Down
4 changes: 2 additions & 2 deletions dynaconf/loaders/json_loader.py
Expand Up @@ -58,12 +58,12 @@ def write(settings_path, settings_data, merge=True):
"""
settings_path = Path(settings_path)
if settings_path.exists() and merge: # pragma: no cover
with io.open(
with open(
str(settings_path), encoding=default_settings.ENCODING_FOR_DYNACONF
) as open_file:
object_merge(json.load(open_file), settings_data)

with io.open(
with open(
str(settings_path),
"w",
encoding=default_settings.ENCODING_FOR_DYNACONF,
Expand Down
6 changes: 3 additions & 3 deletions dynaconf/loaders/py_loader.py
Expand Up @@ -108,12 +108,12 @@ def import_from_filename(obj, filename, silent=False): # pragma: no cover
mod._is_error = False
mod._error = None
try:
with io.open(
with open(
_find_file(filename),
encoding=default_settings.ENCODING_FOR_DYNACONF,
) as config_file:
exec(compile(config_file.read(), filename, "exec"), mod.__dict__)
except IOError as e:
except OSError as e:
e.strerror = (
f"py_loader: error loading file " f"({e.strerror} {filename})\n"
)
Expand All @@ -136,7 +136,7 @@ def write(settings_path, settings_data, merge=True):
existing = DynaconfDict()
load(existing, str(settings_path))
object_merge(existing, settings_data)
with io.open(
with open(
str(settings_path),
"w",
encoding=default_settings.ENCODING_FOR_DYNACONF,
Expand Down
4 changes: 2 additions & 2 deletions dynaconf/loaders/toml_loader.py
Expand Up @@ -44,12 +44,12 @@ def write(settings_path, settings_data, merge=True):
"""
settings_path = Path(settings_path)
if settings_path.exists() and merge: # pragma: no cover
with io.open(
with open(
str(settings_path), encoding=default_settings.ENCODING_FOR_DYNACONF
) as open_file:
object_merge(toml.load(open_file), settings_data)

with io.open(
with open(
str(settings_path),
"w",
encoding=default_settings.ENCODING_FOR_DYNACONF,
Expand Down
4 changes: 2 additions & 2 deletions dynaconf/loaders/yaml_loader.py
Expand Up @@ -65,12 +65,12 @@ def write(settings_path, settings_data, merge=True):
"""
settings_path = Path(settings_path)
if settings_path.exists() and merge: # pragma: no cover
with io.open(
with open(
str(settings_path), encoding=default_settings.ENCODING_FOR_DYNACONF
) as open_file:
object_merge(yaml.safe_load(open_file), settings_data)

with io.open(
with open(
str(settings_path),
"w",
encoding=default_settings.ENCODING_FOR_DYNACONF,
Expand Down
2 changes: 1 addition & 1 deletion dynaconf/strategies/filtering.py
Expand Up @@ -5,7 +5,7 @@ class PrefixFilter:
def __init__(self, prefix):
if not isinstance(prefix, str):
raise TypeError("`SETTINGS_FILE_PREFIX` must be str")
self.prefix = "{}_".format(upperfy(prefix))
self.prefix = f"{upperfy(prefix)}_"

def __call__(self, data):
"""Filter incoming data by prefix"""
Expand Down
37 changes: 15 additions & 22 deletions dynaconf/utils/__init__.py
Expand Up @@ -5,13 +5,8 @@
from collections import defaultdict
from json import JSONDecoder
from typing import Any
from typing import Dict
from typing import Iterator
from typing import List
from typing import Optional
from typing import Tuple
from typing import TYPE_CHECKING
from typing import Union


if TYPE_CHECKING: # pragma: no cover
Expand All @@ -34,7 +29,7 @@


def object_merge(
old: Any, new: Any, unique: bool = False, full_path: List[str] = None
old: Any, new: Any, unique: bool = False, full_path: list[str] = None
johnnv1 marked this conversation as resolved.
Show resolved Hide resolved
) -> Any:
"""
Recursively merge two data structures, new is mutated in-place.
Expand Down Expand Up @@ -86,8 +81,8 @@ def object_merge(


def recursive_get(
obj: Union[DynaBox, Dict[str, int], Dict[str, Union[str, int]]],
names: Optional[List[str]],
obj: DynaBox | dict[str, int] | dict[str, str | int],
names: list[str] | None,
johnnv1 marked this conversation as resolved.
Show resolved Hide resolved
) -> Any:
"""Given a dot accessible object and a list of names `foo.bar.zaz`
gets recursivelly all names one by one obj.foo.bar.zaz.
Expand All @@ -102,7 +97,7 @@ def recursive_get(


def handle_metavalues(
old: Union[DynaBox, Dict[str, int], Dict[str, Union[str, int]]], new: Any
old: DynaBox | dict[str, int] | dict[str, str | int], new: Any
) -> None:
"""Cleanup of MetaValues on new dict"""

Expand Down Expand Up @@ -178,7 +173,7 @@ def __init__(self, *args, **kwargs):
self._not_installed_warnings = []
self._validate_only = kwargs.pop("validate_only", None)
self._validate_exclude = kwargs.pop("validate_exclude", None)
super(DynaconfDict, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def set(self, key: str, value: str, *args, **kwargs) -> None:
self[key] = value
Expand Down Expand Up @@ -208,7 +203,7 @@ def exists(self, key: str, **kwargs) -> bool:
}


def compat_kwargs(kwargs: Dict[str, Any]) -> None:
def compat_kwargs(kwargs: dict[str, Any]) -> None:
"""To keep backwards compat change the kwargs to new names"""
warn_deprecations(kwargs)
for old, new in RENAMED_VARS.items():
Expand All @@ -230,7 +225,7 @@ def __bool__(self) -> bool:
"""Respond to boolean duck-typing."""
return False

def __eq__(self, other: Union[DynaBox, Missing]) -> bool:
def __eq__(self, other: DynaBox | Missing) -> bool:
"""Equality check for a singleton."""

return isinstance(other, self.__class__)
Expand All @@ -249,7 +244,7 @@ def __repr__(self) -> str:
missing = Missing()


def deduplicate(list_object: List[str]) -> List[str]:
def deduplicate(list_object: list[str]) -> list[str]:
"""Rebuild `list_object` removing duplicated and keeping order"""
new = []
for item in list_object:
Expand All @@ -269,8 +264,8 @@ def warn_deprecations(data: Any) -> None:


def trimmed_split(
s: str, seps: Union[str, Tuple[str, str]] = (";", ",")
) -> List[str]:
s: str, seps: str | tuple[str, str] = (";", ",")
) -> list[str]:
"""Given a string s, split is by one of one of the seps."""
for sep in seps:
if sep not in s:
Expand All @@ -280,7 +275,7 @@ def trimmed_split(
return [s] # raw un-splitted


def ensure_a_list(data: Any) -> Union[List[int], List[str]]:
def ensure_a_list(data: Any) -> list[int] | list[str]:
"""Ensure data is a list or wrap it in a list"""
if not data:
return []
Expand All @@ -292,9 +287,7 @@ def ensure_a_list(data: Any) -> Union[List[int], List[str]]:
return [data]


def build_env_list(
obj: Union[Settings, LazySettings], env: Optional[str]
) -> List[str]:
def build_env_list(obj: Settings | LazySettings, env: str | None) -> list[str]:
"""Build env list for loaders to iterate.

Arguments:
Expand Down Expand Up @@ -355,7 +348,7 @@ def upperfy(key: str) -> str:
return key.upper()


def multi_replace(text: str, patterns: Dict[str, str]) -> str:
def multi_replace(text: str, patterns: dict[str, str]) -> str:
"""Replaces multiple pairs in a string

Arguments:
Expand All @@ -372,7 +365,7 @@ def multi_replace(text: str, patterns: Dict[str, str]) -> str:

def extract_json_objects(
text: str, decoder: JSONDecoder = JSONDecoder()
) -> Iterator[Dict[str, Union[int, Dict[Any, Any]]]]:
) -> Iterator[dict[str, int | dict[Any, Any]]]:
"""Find JSON objects in text, and yield the decoded JSON data

Does not attempt to look for JSON arrays, text, or other JSON types outside
Expand All @@ -393,7 +386,7 @@ def extract_json_objects(


def recursively_evaluate_lazy_format(
value: Any, settings: Union[Settings, LazySettings]
value: Any, settings: Settings | LazySettings
) -> Any:
"""Given a value as a data structure, traverse all its members
to find Lazy values and evaluate it.
Expand Down
10 changes: 5 additions & 5 deletions dynaconf/utils/boxing.py
Expand Up @@ -33,18 +33,18 @@ class DynaBox(Box):
@evaluate_lazy_format
def __getattr__(self, item, *args, **kwargs):
try:
return super(DynaBox, self).__getattr__(item, *args, **kwargs)
return super().__getattr__(item, *args, **kwargs)
except (AttributeError, KeyError):
n_item = item.lower() if item.isupper() else upperfy(item)
return super(DynaBox, self).__getattr__(n_item, *args, **kwargs)
return super().__getattr__(n_item, *args, **kwargs)

@evaluate_lazy_format
def __getitem__(self, item, *args, **kwargs):
try:
return super(DynaBox, self).__getitem__(item, *args, **kwargs)
return super().__getitem__(item, *args, **kwargs)
except (AttributeError, KeyError):
n_item = item.lower() if item.isupper() else upperfy(item)
return super(DynaBox, self).__getitem__(n_item, *args, **kwargs)
return super().__getitem__(n_item, *args, **kwargs)

def __copy__(self):
return self.__class__(
Expand All @@ -69,7 +69,7 @@ def _case_insensitive_get(self, item, default=None):
def get(self, item, default=None, *args, **kwargs):
if item not in self: # toggle case
item = item.lower() if item.isupper() else upperfy(item)
value = super(DynaBox, self).get(item, empty, *args, **kwargs)
value = super().get(item, empty, *args, **kwargs)
if value is empty:
# see Issue: #486
return self._case_insensitive_get(item, default)
Expand Down