You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

envier

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

envier - pypi Package Compare versions

Comparing version
0.5.2
to
0.6.0
+2
-1
envier/__init__.py
from envier.env import Env
from envier.env import HelpInfo
En = Env
__all__ = ["En", "Env"]
__all__ = ["En", "Env", "HelpInfo"]

@@ -15,3 +15,3 @@ # file generated by setuptools_scm

__version__ = version = '0.5.2'
__version_tuple__ = version_tuple = (0, 5, 2)
__version__ = version = '0.6.0'
__version_tuple__ = version_tuple = (0, 6, 0)

@@ -0,1 +1,3 @@

from collections import deque
from collections import namedtuple
import os

@@ -20,3 +22,3 @@ import typing as t

MapType = t.Union[t.Callable[[str], V], t.Callable[[str, str], t.Tuple[K, V]]]
HelpInfo = t.Tuple[str, str, str, str]
HelpInfo = namedtuple("HelpInfo", ("name", "type", "default", "help"))

@@ -71,2 +73,8 @@

self._full_name = _normalized(name) # Will be set by the EnvMeta metaclass
@property
def full_name(self) -> str:
return f"_{self._full_name}" if self.private else self._full_name
def _cast(self, _type: t.Any, raw: str, env: "Env") -> t.Any:

@@ -104,5 +112,3 @@ if _type is bool:

full_name = prefix + _normalized(self.name)
if self.private:
full_name = f"_{full_name}"
full_name = self.full_name
raw = source.get(full_name.format(**env.dynamic))

@@ -172,6 +178,4 @@ if raw is None and self.deprecations:

except ValueError as e:
full_name = prefix + _normalized(self.name)
raise ValueError(
"Invalid value for environment variable %s: %s" % (full_name, e)
)
msg = f"Invalid value for environment variable {self.full_name}: {e}"
raise ValueError(msg)

@@ -197,3 +201,18 @@ return value

class Env(object):
class EnvMeta(type):
def __new__(
cls, name: str, bases: t.Tuple[t.Type], ns: t.Dict[str, t.Any]
) -> t.Any:
env = t.cast("Env", super().__new__(cls, name, bases, ns))
prefix = ns.get("__prefix__")
if prefix:
for v in env.values(recursive=True):
if isinstance(v, EnvVariable):
v._full_name = f"{_normalized(prefix)}_{v._full_name}".upper()
return env
class Env(metaclass=EnvMeta):
"""Env base class.

@@ -343,24 +362,40 @@

@classmethod
def keys(cls) -> t.Iterator[str]:
"""Return the names of all the items."""
return (
k
for k, v in cls.__dict__.items()
if isinstance(v, (EnvVariable, DerivedVariable))
or isinstance(v, type)
and issubclass(v, Env)
)
def items(
cls, recursive: bool = False, include_derived: bool = False
) -> t.Iterator[t.Tuple[str, t.Union[EnvVariable, DerivedVariable]]]:
classes = (EnvVariable, DerivedVariable) if include_derived else (EnvVariable,)
q: t.Deque[t.Tuple[t.Tuple[str], t.Type["Env"]]] = deque()
path: t.Tuple[str] = tuple() # type: ignore[assignment]
q.append((path, cls))
while q:
path, env = q.popleft()
for k, v in env.__dict__.items():
if isinstance(v, classes):
yield (
".".join((*path, k)),
t.cast(t.Union[EnvVariable, DerivedVariable], v),
)
elif isinstance(v, type) and issubclass(v, Env) and recursive:
item_name = getattr(v, "__item__", k)
if item_name is None:
item_name = k
q.append(((*path, item_name), v)) # type: ignore[arg-type]
@classmethod
def values(cls) -> t.Iterator[t.Union[EnvVariable, DerivedVariable, t.Type["Env"]]]:
"""Return the names of all the items."""
return (
v
for v in cls.__dict__.values()
if isinstance(v, (EnvVariable, DerivedVariable))
or isinstance(v, type)
and issubclass(v, Env)
)
def keys(
cls, recursive: bool = False, include_derived: bool = False
) -> t.Iterator[str]:
"""Return the name of all the configuration items."""
for k, _ in cls.items(recursive, include_derived):
yield k
@classmethod
def values(
cls, recursive: bool = False, include_derived: bool = False
) -> t.Iterator[t.Union[EnvVariable, DerivedVariable, t.Type["Env"]]]:
"""Return the value of all the configuration items."""
for _, v in cls.items(recursive, include_derived):
yield v
@classmethod
def include(

@@ -379,10 +414,2 @@ cls,

"""
if namespace is not None:
if not overwrite and hasattr(cls, namespace):
raise ValueError("Namespace already in use: {}".format(namespace))
setattr(cls, namespace, env_spec)
return None
# Pick only the attributes that define variables.

@@ -396,3 +423,2 @@ to_include = {

}
if not overwrite:

@@ -403,4 +429,27 @@ overlap = set(cls.__dict__.keys()) & set(to_include.keys())

own_prefix = _normalized(getattr(cls, "__prefix__", ""))
if namespace is not None:
if not overwrite and hasattr(cls, namespace):
raise ValueError("Namespace already in use: {}".format(namespace))
if getattr(cls, namespace, None) is not env_spec:
setattr(cls, namespace, env_spec)
if own_prefix:
for _, v in to_include.items():
if isinstance(v, EnvVariable):
v._full_name = f"{own_prefix}_{v._full_name}"
return None
other_prefix = getattr(env_spec, "__prefix__", "")
for k, v in to_include.items():
setattr(cls, k, v)
if getattr(cls, k, None) is not v:
setattr(cls, k, v)
if isinstance(v, EnvVariable):
if other_prefix:
v._full_name = v._full_name[len(other_prefix) + 1 :] # noqa
if own_prefix:
v._full_name = f"{own_prefix}_{v._full_name}"

@@ -444,3 +493,3 @@ @classmethod

try:
help_type = "``%s``" % v.type.__name__ # type: ignore[attr-defined]
help_type = v.type.__name__ # type: ignore[attr-defined]
except AttributeError:

@@ -453,4 +502,4 @@ # typing.t.Union[<type>, NoneType]

entries.append(
(
f"``{private_prefix}{full_prefix}{_normalized(v.name)}``",
HelpInfo(
f"{private_prefix}{full_prefix}{_normalized(v.name)}",
help_type, # type: ignore[attr-defined]

@@ -457,0 +506,0 @@ (

Metadata-Version: 2.3
Name: envier
Version: 0.5.2
Version: 0.6.0
Summary: Python application configuration via the environment

@@ -37,2 +37,3 @@ Project-URL: Homepage, https://github.com/DataDog/envier

Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.7

@@ -39,0 +40,0 @@ Provides-Extra: mypy

@@ -23,2 +23,3 @@ [build-system]

"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"License :: OSI Approved :: MIT License",

@@ -80,3 +81,3 @@ ]

[[tool.hatch.envs.tests.matrix]]
python = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
python = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

@@ -83,0 +84,0 @@ [tool.hatch.envs.checks]