Skip to content

Commit

Permalink
Merge pull request #15 from mosquito/feature/poetry
Browse files Browse the repository at this point in the history
Feature/poetry
  • Loading branch information
mosquito committed Dec 8, 2022
2 parents 473980f + c11ad19 commit dbb3f2e
Show file tree
Hide file tree
Showing 12 changed files with 826 additions and 226 deletions.
95 changes: 95 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: tests

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
pylama:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup python3.10
uses: actions/setup-python@v2
with:
python-version: "3.10"
- run: python -m pip install poetry
- run: poetry install
- run: poetry run pylama
env:
FORCE_COLOR: 1
mypy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup python3.10
uses: actions/setup-python@v2
with:
python-version: "3.10"
- run: python -m pip install poetry
- run: poetry install
- run: poetry run mypy
env:
FORCE_COLOR: 1
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup python3.10
uses: actions/setup-python@v2
with:
python-version: "3.10"
- run: python -m pip install poetry
- run: poetry install
- run: poetry run pytest -svv README.rst
env:
FORCE_COLOR: 1

tests:
runs-on: ubuntu-latest

strategy:
fail-fast: false

matrix:
python:
- '3.7'
- '3.8'
- '3.9'
- '3.10'
- '3.11'
steps:
- uses: actions/checkout@v2
- name: Setup python${{ matrix.python }}
uses: actions/setup-python@v2
with:
python-version: "${{ matrix.python }}"
- run: python -m pip install poetry
- run: poetry install
- run: >-
poetry run pytest \
-vv \
--cov=argclass \
--cov-report=term-missing \
--doctest-modules \
tests
env:
FORCE_COLOR: 1
- run: poetry run coveralls
env:
COVERALLS_PARALLEL: 'true'
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

finish:
needs:
- tests
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.github_token }}
parallel-finished: true
87 changes: 0 additions & 87 deletions .github/workflows/tox.yml

This file was deleted.

File renamed without changes.
2 changes: 0 additions & 2 deletions MANIFEST.in

This file was deleted.

56 changes: 30 additions & 26 deletions src/argclass.py → argclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
import logging
import os
import sys
import typing
from abc import ABCMeta
from argparse import Action, ArgumentParser
from enum import Enum
from pathlib import Path
from types import MappingProxyType
from typing import (
Any, Callable, Dict, Iterable, Mapping, MutableMapping, NamedTuple,
Optional, Sequence, Set, Tuple, Type, TypeVar, Union,
Optional, Sequence, Set, Tuple, Type, TypeVar, Union, List,
)


Expand Down Expand Up @@ -65,14 +64,17 @@ def __init__(
option_strings, dest, type=Path, help=help, default=default,
required=required,
)
self.search_paths = list(map(Path, search_paths))
self._result = None
self.search_paths: List[Path] = list(map(Path, search_paths))
self._result: Optional[Any] = None

def __call__(self, parser, namespace, values, option_string=None):
def __call__(
self, parser: argparse.ArgumentParser, namespace: argparse.Namespace,
values: Optional[Union[str, Any]], option_string: Optional[str] = None
) -> None:
if not self._result:
filenames = list(self.search_paths)
filenames: Sequence[Path] = list(self.search_paths)
if values:
filenames.insert(0, Path(values))
filenames = [Path(values)] + list(filenames)
self._result, filenames = read_config(*filenames)
if self.required and not filenames:
raise argparse.ArgumentError(
Expand All @@ -98,7 +100,7 @@ class Actions(str, Enum):
EXTEND = "extend"

@classmethod
def default(cls):
def default(cls) -> "Actions":
return cls.STORE


Expand All @@ -109,11 +111,11 @@ class Nargs(Enum):
ZERO_OR_MORE = "*"

@classmethod
def default(cls):
def default(cls) -> "Nargs":
return cls.ANY


def deep_getattr(name, attrs: Dict[str, Any], *bases: Type) -> Any:
def deep_getattr(name: str, attrs: Dict[str, Any], *bases: Type) -> Any:
if name in attrs:
return attrs[name]
for base in bases:
Expand All @@ -134,7 +136,8 @@ def merge_annotations(


class StoreMeta(type):
def __new__(mcs, name, bases, attrs: Dict[str, Any]):
def __new__(mcs, name: str, bases: Tuple[Type["StoreMeta"], ...],
attrs: Dict[str, Any]) -> "StoreMeta":
annotations = merge_annotations(
attrs.get("__annotations__", {}), *bases
)
Expand All @@ -152,7 +155,7 @@ class Store(metaclass=StoreMeta):
_default_value = object()
_fields: Tuple[str, ...]

def __new__(cls, **kwargs) -> "Store":
def __new__(cls, **kwargs: Any) -> "Store":
obj = super().__new__(cls)

type_map: Dict[str, Tuple[Type, Any]] = {}
Expand All @@ -168,7 +171,7 @@ def __new__(cls, **kwargs) -> "Store":
setattr(obj, key, value)
return obj

def copy(self, **overrides):
def copy(self, **overrides: Any) -> Any:
kwargs = self.as_dict()
for key, value in overrides.items():
kwargs[key] = value
Expand All @@ -188,14 +191,14 @@ def __repr__(self) -> str:


class ArgumentBase(Store):
def __init__(self, **kwargs):
def __init__(self, **kwargs: Any):
self._values = collections.OrderedDict()

# noinspection PyUnresolvedReferences
for key in self._fields:
self._values[key] = kwargs.get(key, getattr(self.__class__, key))

def __getattr__(self, item):
def __getattr__(self, item: str) -> Any:
try:
return self._values[item]
except KeyError as e:
Expand All @@ -208,7 +211,7 @@ def is_positional(self) -> bool:
return False
return True

def get_kwargs(self):
def get_kwargs(self) -> Dict[str, Any]:
nargs = self.nargs
if isinstance(nargs, Nargs):
nargs = nargs.value
Expand Down Expand Up @@ -294,7 +297,7 @@ def unwrap_optional(typespec: Any) -> Optional[Any]:


def _make_action_true_argument(
kind: typing.Type, default: Any = None,
kind: Type, default: Any = None,
) -> _Argument:
kw: Dict[str, Any] = {"type": kind}
if kind is bool:
Expand All @@ -304,19 +307,20 @@ def _make_action_true_argument(
kw["action"] = Actions.STORE_FALSE
else:
raise TypeError(f"Can not set default {default!r} for bool")
elif kind == typing.Optional[bool]:
elif kind == Optional[bool]:
kw["action"] = Actions.STORE
kw["type"] = parse_bool
kw["default"] = None
return _Argument(**kw)


def _type_is_bool(kind: typing.Type) -> bool:
return kind is bool or kind == typing.Optional[bool]
def _type_is_bool(kind: Type) -> bool:
return kind is bool or kind == Optional[bool]


class Meta(ABCMeta):
def __new__(mcs, name, bases, attrs: Dict[str, Any]):
def __new__(mcs, name: str, bases: Tuple[Type["Meta"], ...],
attrs: Dict[str, Any]) -> "Meta":
annotations = merge_annotations(
attrs.get("__annotations__", {}), *bases
)
Expand Down Expand Up @@ -434,21 +438,21 @@ def __init__(

# noinspection PyProtectedMember
class Parser(AbstractParser, Base):
HELP_APPENDIX_PREAMBLE: str = (
HELP_APPENDIX_PREAMBLE = (
" Default values will based on following "
"configuration files {configs}. "
)
HELP_APPENDIX_CURRENT: str = (
HELP_APPENDIX_CURRENT = (
"Now {num_existent} files has been applied {existent}. "
)
HELP_APPENDIX_END: str = (
HELP_APPENDIX_END = (
"The configuration files is INI-formatted files "
"where configuration groups is INI sections."
"See more https://pypi.org/project/argclass/#configs"
)

def _add_argument(
self, parser: Any, argument: _Argument, dest: str, *aliases,
self, parser: Any, argument: _Argument, dest: str, *aliases: str,
) -> Tuple[str, Action]:
kwargs = argument.get_kwargs()

Expand Down Expand Up @@ -498,7 +502,7 @@ def get_env_var(self, name: str, argument: _Argument) -> Optional[str]:
def __init__(
self, config_files: Iterable[Union[str, Path]] = (),
auto_env_var_prefix: Optional[str] = None,
**kwargs,
**kwargs: Any,
):
super().__init__()
self.current_subparser = None
Expand Down
Loading

0 comments on commit dbb3f2e

Please sign in to comment.