Skip to content

Commit 8f8d883

Browse files
committed
update
1 parent 953158c commit 8f8d883

7 files changed

Lines changed: 525 additions & 13 deletions

File tree

Changelog.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# 0.1.2
2+
3+
## 新增特性
4+
5+
+ `EntryPoint`类可以直接在实例化时通过参数定义其`description`, `epilog`, `usage`, `name`等属性.这样我们就可以直接实例化`EntryPoint`构造节点而不用继承了.这一特性适合用在构造非叶子节点时.
6+
+ 与其对应的,`.regist_sub`方法现在可以添加参数用于在实例化节点时放入参数
7+
18
# 0.1.1
29

310
## bug修复

schema_entry/entrypoint.py

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from yaml import load as yaml_load
2424

2525
from .protocol import SUPPORT_SCHEMA
26-
from .utils import get_parent_tree, parse_value_string_by_schema, parse_schema_as_cmd
26+
from .utils import SchemaType, get_parent_tree, parse_value_string_by_schema, parse_schema_as_cmd
2727
from .entrypoint_base import EntryPointABC
2828

2929

@@ -55,7 +55,77 @@ def _check_schema(self) -> None:
5555
raise e
5656
# sys.exit(1)
5757

58-
def __init__(self) -> None:
58+
def __init__(self, *,
59+
description: Optional[str] = None,
60+
epilog: Optional[str] = None,
61+
usage: Optional[str] = None,
62+
name: Optional[str] = None,
63+
schema: Optional[SchemaType] = None,
64+
verify_schema: Optional[bool] = None,
65+
default_config_file_paths: Optional[List[str]] = None,
66+
config_file_only_get_need: Optional[bool] = None,
67+
load_all_config_file: Optional[bool] = None,
68+
env_prefix: Optional[str] = None,
69+
parse_env: Optional[bool] = None,
70+
argparse_check_required: Optional[bool] = None,
71+
argparse_noflag: Optional[str] = None,
72+
config_file_parser_map: Optional[Dict[str, Callable[[Path], Dict[str, Any]]]] = None,
73+
main: Optional[Callable[..., None]] = None
74+
) -> None:
75+
"""初始化时定义配置.
76+
77+
使用这一特性我们就可以不用继承也可以定义节点了.这一特性比较适合用于那些非叶子节点.
78+
79+
Args:
80+
description (Optional[str], optional): 节点命令行的描述信息. Defaults to None.
81+
epilog (Optional[str], optional): 节点命令行的epilog信息. Defaults to None.
82+
usage (Optional[str], optional): 节点命令行的usage信息. Defaults to None.
83+
name (Optional[str], optional): 节点的name属性. Defaults to None.
84+
schema (Optional[Dict[str, Union[str, List[str], Dict[str, Dict[str, Any]]]]], optional): 节点的校验json schema. Defaults to None.
85+
verify_schema (Optional[bool], optional): 配置是否校验schema. Defaults to None.
86+
default_config_file_paths (Optional[List[str]], optional): 默认配置文件路径列表. Defaults to None.
87+
config_file_only_get_need (Optional[bool], optional): 设置是否在加载配置文件时只获取schema中定义的内容. Defaults to None.
88+
load_all_config_file (Optional[bool], optional): 是否尝试加载全部指定的配置文件路径下的配置文件. Defaults to None.
89+
env_prefix (Optional[str], optional): 设置环境变量的前缀. Defaults to None.
90+
parse_env (Optional[bool], optional): 设置是否加载环境变量. Defaults to None.
91+
argparse_check_required (Optional[bool], optional): 设置是否构造叶子节点命令行时指定schema中定义为必须的参数项为必填项. Defaults to None.
92+
argparse_noflag (Optional[str], optional): 指定命令行中noflag的参数. Defaults to None.
93+
config_file_parser_map (Optional[Dict[str, Callable[[Path], Dict[str, Any]]]], optional): 设置自定义配置文件名的解析映射. Defaults to None.
94+
main (Optional[Callable[..., None]], optional): 设置作为入口的执行函数. Defaults to None.
95+
"""
96+
if description is not None:
97+
self.__doc__ = description
98+
if epilog is not None:
99+
self.epilog = epilog
100+
if usage is not None:
101+
self.usage = usage
102+
if name is not None:
103+
self._name = name
104+
if schema is not None:
105+
self.schema = schema
106+
if verify_schema is not None:
107+
self.verify_schema = verify_schema
108+
if default_config_file_paths is not None:
109+
self.default_config_file_paths = default_config_file_paths
110+
if config_file_only_get_need is not None:
111+
self.config_file_only_get_need = config_file_only_get_need
112+
if load_all_config_file is not None:
113+
self.load_all_config_file = load_all_config_file
114+
if env_prefix is not None:
115+
self.env_prefix = env_prefix
116+
if parse_env is not None:
117+
self.parse_env = parse_env
118+
if argparse_check_required is not None:
119+
self.argparse_check_required = argparse_check_required
120+
if argparse_noflag is not None:
121+
self.argparse_noflag = argparse_noflag
122+
if config_file_parser_map is not None:
123+
self._config_file_parser_map = config_file_parser_map
124+
if config_file_parser_map is not None:
125+
self._config_file_parser_map = config_file_parser_map
126+
if main is not None:
127+
self._main = main
128+
59129
self._check_schema()
60130
self._subcmds = {}
61131
self._main = None
@@ -79,8 +149,8 @@ def regist_subcmd(self, subcmd: EntryPointABC) -> None:
79149
subcmd.parent = self
80150
self._subcmds[subcmd.name] = subcmd
81151

82-
def regist_sub(self, subcmdclz: type) -> EntryPointABC:
83-
instance = subcmdclz()
152+
def regist_sub(self, subcmdclz: type, **kwargs: Any) -> EntryPointABC:
153+
instance = subcmdclz(**kwargs)
84154
self.regist_subcmd(instance)
85155
return instance
86156

@@ -139,7 +209,7 @@ def _make_commandline_parse_by_schema(self, parser: argparse.ArgumentParser) ->
139209
if self.schema is None:
140210
raise AttributeError("此处不该被执行")
141211
else:
142-
properties: Dict[str, Any] = self.schema.get("properties", {})
212+
properties: Dict[str, Dict[str, Any]] = self.schema.get("properties", {})
143213
requireds: List[str] = self.schema.get("required", [])
144214
for key, prop in properties.items():
145215
required = False
@@ -235,7 +305,7 @@ def file_config_filter(self, file_param: Dict[str, Any]) -> Dict[str, Any]:
235305
Dict[str, Any]: 筛选过后的参数
236306
"""
237307
if self.config_file_only_get_need and self.schema is not None and self.schema.get("properties") is not None:
238-
needs = list(self.schema.get("properties").keys())
308+
needs = list(self.schema["properties"].keys())
239309
res = {}
240310
for key in needs:
241311
if file_param.get(key) is not None:

schema_entry/entrypoint_base.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import abc
33
import argparse
44
from pathlib import Path
5-
from typing import Callable, Sequence, Dict, Any, Optional, List, Union, Tuple
5+
from typing import Callable, Sequence, Dict, Any, Optional, Tuple
6+
from .utils import SchemaType
67

78

89
class EntryPointABC(abc.ABC):
@@ -28,7 +29,7 @@ class EntryPointABC(abc.ABC):
2829
_name: str
2930
parent: Optional["EntryPointABC"]
3031

31-
schema: Optional[Dict[str, Union[str, List[str], Dict[str, Dict[str, Any]]]]]
32+
schema: Optional[SchemaType] # Optional[Dict[str, Union[str, List[str], Dict[str, Dict[str, Any]]]]]
3233
verify_schema: bool
3334

3435
default_config_file_paths: Sequence[str]
@@ -71,7 +72,7 @@ def regist_subcmd(self, subcmd: "EntryPointABC") -> None:
7172
7273
"""
7374
@abc.abstractmethod
74-
def regist_sub(self, subcmdclz: type) -> "EntryPointABC":
75+
def regist_sub(self, subcmdclz: type, **kwargs: Any) -> "EntryPointABC":
7576
'''注册子命令.
7677
7778
Args:

schema_entry/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@
55
import warnings
66
import argparse
77
from typing import List, Dict, Any, Optional
8+
from mypy_extensions import TypedDict
89
from .entrypoint_base import EntryPointABC
910

1011

12+
class SchemaType(TypedDict):
13+
required: List[str]
14+
type: str
15+
properties: Dict[str, Dict[str, Any]]
16+
17+
1118
def _get_parent_tree(c: EntryPointABC, result: List[str]) -> None:
1219
if c.parent:
1320
result.append(c.parent.name)

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ packages = find:
2424
install_requires =
2525
jsonschema >= 3.2.0
2626
pyyaml >= 5.0.0
27+
mypy >= 0.800
2728

2829
[options.packages.find]
2930
include = schema_entry

tests/test_entrypoint.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ def tearDownModule() -> None:
1919
class CMDTest(unittest.TestCase):
2020
@classmethod
2121
def setUpClass(cls) -> None:
22-
print("setUp GetParentTree test context")
22+
print("setUp CMDTest test context")
2323

2424
@classmethod
2525
def tearDownClass(cls) -> None:
26-
print("tearDown GetParentTree test context")
26+
print("tearDown CMDTest test context")
2727

2828
def test_default_name(self) -> None:
2929
class Test_A(EntryPoint):
@@ -140,11 +140,11 @@ def _(a: int) -> None:
140140
class LoadConfigTest(unittest.TestCase):
141141
@classmethod
142142
def setUpClass(cls) -> None:
143-
print("setUp GetParentTree test context")
143+
print("setUp LoadConfigTest test context")
144144

145145
@classmethod
146146
def tearDownClass(cls) -> None:
147-
print("tearDown GetParentTree test context")
147+
print("tearDown LoadConfigTest test context")
148148

149149
def test_load_default_config(self) -> None:
150150
class Test_A(EntryPoint):

0 commit comments

Comments
 (0)