Skip to content

Commit

Permalink
Add typing
Browse files Browse the repository at this point in the history
  • Loading branch information
lbolla committed Mar 11, 2019
1 parent 6f5fb94 commit 26352a5
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 11 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include yamlenv/py.typed
18 changes: 18 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.PHONY: develop

develop:
@pip install -qe .

test: tox mypy flake8

tox: requirements_tests
tox

mypy: requirements_tests
mypy yamlenv

flake8: requirements_tests
flake8 yamlenv

requirements_tests: develop
@pip install -qUr requirements_tests.txt
17 changes: 17 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[mypy]
python_version = 3.6
# strict mode
disallow_subclassing_any = True
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
check_untyped_defs = True
disallow_untyped_decorators = True
no_implicit_optional = True
warn_redundant_casts = True
warn_unused_ignores = True
warn_return_any = True

[mypy-setuptools]
ignore_missing_imports = True
3 changes: 3 additions & 0 deletions requirements_tests.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
flake8
mypy
tox
7 changes: 7 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,12 @@
install_requires=[
'PyYAML>=3.12',
'six>=1.10',
'typing; python_version<"3.6"',
],
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
],
)
1 change: 0 additions & 1 deletion tests/test_env.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pylint: disable=no-self-use
import os
import unittest

Expand Down
1 change: 0 additions & 1 deletion tests/test_include.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pylint: disable=no-self-use
import tempfile
import unittest

Expand Down
6 changes: 5 additions & 1 deletion yamlenv/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import typing as T
import yaml

from . import env, loader
from yamlenv import env, loader
from yamlenv.types import Stream


__version__ = '0.6.0'


def load(stream):
# type: (Stream) -> T.Any
data = yaml.load(stream, loader.Loader)
return env.interpolate(data)


def load_all(stream):
# type: (Stream) -> T.Iterator[T.Any]
for data in yaml.load_all(stream, loader.Loader):
yield env.interpolate(data)
21 changes: 16 additions & 5 deletions yamlenv/env.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pylint: disable=undefined-variable
import os
import re
import yaml
Expand All @@ -10,12 +9,18 @@
from collections import Mapping, Sequence, Set # noqa

import six
import typing as T

from yamlenv.types import Cache, Obj, ObjIFunc, Path, WalkType

def objwalk(obj, path=(), memo=None):

def objwalk(obj, path=None, memo=None):
# type: (Obj, T.Optional[Path], T.Optional[Cache]) -> WalkType
if path is None:
path = tuple()
if memo is None:
memo = set()
iterator = None
iterator = None # type: T.Optional[ObjIFunc]
if isinstance(obj, Mapping):
iterator = six.iteritems
elif isinstance(
Expand Down Expand Up @@ -44,17 +49,20 @@ class EnvVar(object):
r'\$\{(?P<name>[^:-]+)((?P<separator>:?)-(?P<default>.*))?\}')

def __init__(self, name, separator, default, string):
# type: (str, str, str, str) -> None
self.name = name
self.separator = separator
self.default = default
self.string = string

@property
def allow_null_default(self):
# type: () -> bool
return self.separator == ''

@property
def value(self):
# type: () -> str
value = os.environ.get(self.name)
if value:
return self.RE.sub(value, self.string)
Expand All @@ -64,20 +72,23 @@ def value(self):

@property
def yaml_value(self):
# type: () -> T.Any
return yaml.safe_load(self.value)

@classmethod
def from_string(cls, s):
# type: (str) -> T.Optional[EnvVar]
if not isinstance(s, six.string_types):
return None
data = cls.RE.search(s)
if not data:
return None
data = data.groupdict()
return cls(data['name'], data['separator'], data['default'], s)
gd = data.groupdict()
return cls(gd['name'], gd['separator'], gd['default'], s)


def interpolate(data):
# type: (T.Any) -> Obj
for path, obj in objwalk(data):
e = EnvVar.from_string(obj)
if e is not None:
Expand Down
11 changes: 8 additions & 3 deletions yamlenv/loader.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# pylint: disable=redefined-builtin
import os
import json
import typing as T

import six
import yaml


class LoaderMeta(type):

def __new__(mcs, __name__, __bases__, __dict__):
def __new__(mcs, __name__, __bases__, __dict__): # type: ignore
"""Add include constructer to class."""

# register the include constructor on the class
Expand All @@ -23,6 +23,7 @@ class Loader(yaml.Loader):
"""YAML Loader with `!include` constructor."""

def __init__(self, stream, filenames_seen=None):
# type: (T.IO[str], T.Optional[T.Set[str]]) -> None
"""Initialise Loader."""

try:
Expand All @@ -34,16 +35,20 @@ def __init__(self, stream, filenames_seen=None):
yaml.Loader.__init__(self, stream)

def _remeber(self):
# type: () -> T.Callable[[T.IO[str]], Loader]
"""Create a loader with the same filenames cache."""
def loader(stream):
# type: (T.IO[str]) -> Loader
return Loader(stream, self._filenames_seen)
return loader

def construct_include(self, node):
# type: (T.Any) -> T.Any
"""Include file referenced at node."""

filename = os.path.abspath(
os.path.join(self._root, self.construct_scalar(node)))
os.path.join(
self._root, self.construct_scalar(node))) # type: ignore
extension = os.path.splitext(filename)[1].lstrip('.')

if filename in self._filenames_seen:
Expand Down
Empty file added yamlenv/py.typed
Empty file.
9 changes: 9 additions & 0 deletions yamlenv/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from typing import Any, Callable, IO, Iterator, Set, Tuple, Union

Obj = Any
Path = Tuple[Any, ...]
WalkType = Iterator[Tuple[Path, Obj]]
Cache = Set[int]
ObjI = Iterator[Tuple[Any, Any]]
ObjIFunc = Callable[[Obj], ObjI]
Stream = Union[str, IO[str]]

0 comments on commit 26352a5

Please sign in to comment.