Skip to content

Commit 65d79ed

Browse files
authored
Merge pull request #1292 from gallardoalba/Annotate_modules_oct_13
Planemo type annotation: config, context and factory
2 parents 69e3cbf + d0f35c0 commit 65d79ed

File tree

3 files changed

+57
-37
lines changed

3 files changed

+57
-37
lines changed

planemo/config.py

+28-16
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,24 @@
44
from enum import Enum
55
from typing import (
66
Any,
7+
Callable,
78
Dict,
9+
List,
10+
Optional,
11+
Tuple,
12+
TYPE_CHECKING,
13+
Union,
814
)
915

1016
import click
1117
import yaml
18+
from click.core import Option
19+
20+
if TYPE_CHECKING:
21+
from planemo.cli import PlanemoCliContext
1222

1323
PLANEMO_CONFIG_ENV_PROP = "PLANEMO_GLOBAL_CONFIG_PATH"
14-
DEFAULT_CONFIG = {} # type: Dict[str, Any]
24+
DEFAULT_CONFIG: Dict[str, Any] = {}
1525

1626
VALUE_UNSET = object()
1727

@@ -20,11 +30,11 @@
2030

2131

2232
def _default_callback(
23-
default,
24-
use_global_config=False,
25-
resolve_path=False,
26-
extra_global_config_vars=[],
27-
):
33+
default: Any,
34+
use_global_config: bool = False,
35+
resolve_path: bool = False,
36+
extra_global_config_vars: List[str] = [],
37+
) -> Callable:
2838
def callback(ctx, param, value):
2939
planemo_ctx = ctx.obj
3040
param_name = param.name
@@ -55,10 +65,12 @@ def callback(ctx, param, value):
5565
return callback
5666

5767

58-
def _find_default(ctx, param, use_global_config, extra_global_config_vars):
68+
def _find_default(
69+
ctx: "PlanemoCliContext", param: Option, use_global_config: bool, extra_global_config_vars: List[str]
70+
) -> Union[Tuple[Any, OptionSource], Tuple[object, None]]:
5971
if use_global_config:
6072
global_config = ctx.global_config
61-
global_config_keys = ["default_%s" % param.name] + extra_global_config_vars
73+
global_config_keys = [f"default_{param.name}"] + extra_global_config_vars
6274
for global_config_key in global_config_keys:
6375
if global_config_key in global_config:
6476
default_value = global_config[global_config_key]
@@ -67,15 +79,15 @@ def _find_default(ctx, param, use_global_config, extra_global_config_vars):
6779
return VALUE_UNSET, None
6880

6981

70-
def planemo_option(*args, **kwargs):
82+
def planemo_option(*args, **kwargs) -> Callable:
7183
"""Extend ``click.option`` with planemo-config aware configuration.
7284
7385
This extends click.option to use a callback when assigning default
7486
values, add ``use_global_config`` keyword argument to allow reading
7587
defaults from ~/.planemo.yml, and tracks how parameters are specified
7688
using the Planemo Context object.
7789
"""
78-
option_type = kwargs.get("type", None)
90+
option_type = kwargs.get("type")
7991
use_global_config = kwargs.pop("use_global_config", False)
8092
use_env_var = kwargs.pop("use_env_var", False)
8193
extra_global_config_vars = kwargs.pop("extra_global_config_vars", [])
@@ -89,7 +101,7 @@ def planemo_option(*args, **kwargs):
89101
outer_callback = kwargs.pop("callback", None)
90102

91103
def callback(ctx, param, value):
92-
resolve_path = option_type and getattr(option_type, "resolve_path", False)
104+
resolve_path = bool(option_type and getattr(option_type, "resolve_path", False))
93105
result = _default_callback(
94106
default,
95107
use_global_config=use_global_config,
@@ -113,20 +125,20 @@ def callback(ctx, param, value):
113125
if arg.startswith("--"):
114126
name = arg[len("--") :]
115127
assert name
116-
kwargs["envvar"] = "PLANEMO_%s" % name.upper()
128+
kwargs["envvar"] = f"PLANEMO_{name.upper()}"
117129

118130
option = click.option(*args, **kwargs)
119131
return option
120132

121133

122-
def global_config_path(config_path=None):
134+
def global_config_path(config_path: Optional[str] = None) -> str:
123135
if not config_path:
124-
config_path = os.environ.get(PLANEMO_CONFIG_ENV_PROP, "~/.planemo.yml")
125-
config_path = os.path.expanduser(config_path)
136+
planemo_config_env_prop = os.environ.get(PLANEMO_CONFIG_ENV_PROP, "~/.planemo.yml")
137+
config_path = os.path.expanduser(planemo_config_env_prop)
126138
return config_path
127139

128140

129-
def read_global_config(config_path: str):
141+
def read_global_config(config_path: Optional[str]) -> Dict[str, Any]:
130142
config_path = global_config_path(config_path)
131143
if not os.path.exists(config_path):
132144
return DEFAULT_CONFIG

planemo/context.py

+26-19
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,19 @@
99
import shutil
1010
import sys
1111
import traceback
12+
from typing import (
13+
Any,
14+
Dict,
15+
Optional,
16+
TYPE_CHECKING,
17+
)
1218
from urllib.request import urlopen
1319

1420
from planemo.config import read_global_config
1521

22+
if TYPE_CHECKING:
23+
from planemo.config import OptionSource
24+
1625

1726
class PlanemoContextInterface(metaclass=abc.ABCMeta):
1827
"""Interface Planemo operations use to access workspace context."""
@@ -53,29 +62,29 @@ def cache_download(self, url, destination):
5362
class PlanemoContext(PlanemoContextInterface):
5463
"""Implementation of ``PlanemoContextInterface``"""
5564

56-
def __init__(self):
65+
def __init__(self) -> None:
5766
"""Construct a Context object using execution environment."""
5867
self.home = os.getcwd()
59-
self._global_config = None
68+
self._global_config: Optional[Dict] = None
6069
# Will be set by planemo CLI driver
6170
self.verbose = False
62-
self.planemo_config = None
71+
self.planemo_config: Optional[str] = None
6372
self.planemo_directory = None
64-
self.option_source = {}
73+
self.option_source: Dict[str, "OptionSource"] = {}
6574

66-
def set_option_source(self, param_name, option_source, force=False):
75+
def set_option_source(self, param_name: str, option_source: "OptionSource", force: bool = False) -> None:
6776
"""Specify how an option was set."""
6877
if not force:
69-
assert param_name not in self.option_source, "No option source for [%s]" % param_name
78+
assert param_name not in self.option_source, f"Option source for [{param_name}] already set"
7079
self.option_source[param_name] = option_source
7180

72-
def get_option_source(self, param_name):
81+
def get_option_source(self, param_name: str) -> "OptionSource":
7382
"""Return OptionSource value indicating how the option was set."""
74-
assert param_name in self.option_source, "No option source for [%s]" % param_name
83+
assert param_name in self.option_source, f"No option source for [{param_name}]"
7584
return self.option_source[param_name]
7685

7786
@property
78-
def global_config(self):
87+
def global_config(self) -> Dict[str, Any]:
7988
"""Read Planemo's global configuration.
8089
8190
As defined most simply by ~/.planemo.yml.
@@ -84,21 +93,21 @@ def global_config(self):
8493
self._global_config = read_global_config(self.planemo_config)
8594
return self._global_config or {}
8695

87-
def log(self, msg, *args):
96+
def log(self, msg: str, *args) -> None:
8897
"""Log a message."""
8998
if args:
9099
msg %= args
91100
self._log_message(msg)
92101

93-
def vlog(self, msg, *args, **kwds):
102+
def vlog(self, msg: str, *args, **kwds) -> None:
94103
"""Log a message only if verbose is enabled."""
95104
if self.verbose:
96105
self.log(msg, *args)
97106
if kwds.get("exception", False):
98107
traceback.print_exc(file=sys.stderr)
99108

100109
@property
101-
def workspace(self):
110+
def workspace(self) -> str:
102111
"""Create and return Planemo's workspace.
103112
104113
By default this will be ``~/.planemo``.
@@ -109,7 +118,7 @@ def workspace(self):
109118
return self._ensure_directory(workspace, "workspace")
110119

111120
@property
112-
def galaxy_profiles_directory(self):
121+
def galaxy_profiles_directory(self) -> str:
113122
"""Create a return a directory for storing Galaxy profiles."""
114123
path = os.path.join(self.workspace, "profiles")
115124
return self._ensure_directory(path, "Galaxy profiles")
@@ -125,27 +134,25 @@ def cache_download(self, url, destination):
125134
with urlopen(url) as fh:
126135
content = fh.read()
127136
if len(content) == 0:
128-
raise Exception("Failed to download [%s]." % url)
137+
raise Exception(f"Failed to download [{url}].")
129138
with open(cache_destination, "wb") as f:
130139
f.write(content)
131140

132141
shutil.copy(cache_destination, destination)
133142

134-
def _ensure_directory(self, path, name):
143+
def _ensure_directory(self, path: str, name: str) -> str:
135144
if not os.path.exists(path):
136145
os.makedirs(path)
137146
if not os.path.isdir(path):
138-
template = "Planemo %s directory [%s] unavailable."
139-
message = template % (name, path)
140-
raise Exception(message)
147+
raise Exception(f"Planemo {name} directory [{path}] unavailable.")
141148
return path
142149

143150
def _log_message(self, message):
144151
"""Extension point for overriding I/O."""
145152
print(message)
146153

147154

148-
def configure_standard_planemo_logging(verbose):
155+
def configure_standard_planemo_logging(verbose: bool) -> None:
149156
"""Configure Planemo's default logging rules."""
150157
logging_config = {
151158
"version": 1,

planemo/database/factory.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"""Create a DatabaseSource from supplied planemo configuration."""
22
from galaxy.util.commands import which
33

4+
from .interface import DatabaseSource
45
from .postgres import LocalPostgresDatabaseSource
56
from .postgres_docker import DockerPostgresDatabaseSource
67

78

8-
def create_database_source(**kwds):
9-
"""Return a :class:`planemo.database.DatabaseSource` for configuration."""
9+
def create_database_source(**kwds) -> DatabaseSource:
10+
"""Return a :class:`planemo.database.interface.DatabaseSource` for configuration."""
1011
database_type = kwds.get("database_type", "auto")
1112
if database_type == "auto":
1213
if which("psql"):

0 commit comments

Comments
 (0)