Skip to content

Commit b5f9c60

Browse files
authored
Small fixes and improvements (#35)
- Add a core module with RepositoryType - Add test to check for unexpected changes in repo types - Add test for the `nox.default` module - Test that pyproject.toml handles all repository types - Improve description of supported repository types - Sort repository types alphabetically - Add support for "model" repositories - Use sets for config paths and sessions - Make imports private when only used internally
2 parents c3239e4 + f46b349 commit b5f9c60

File tree

15 files changed

+230
-107
lines changed

15 files changed

+230
-107
lines changed

noxfile.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,4 @@
55

66
from frequenz.repo.config import nox
77

8-
# Remove the pytest sessions because we don't have tests yet
9-
config = nox.default.lib_config.copy()
10-
config.sessions = [s for s in config.sessions if not s.startswith("pytest")]
11-
12-
nox.configure(config)
8+
nox.configure(nox.default.lib_config)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ api = [
4848
]
4949
app = []
5050
lib = []
51+
model = []
5152
dev-docs-gen = [
5253
"mike == 1.1.2",
5354
"mkdocs-gen-files == 0.4.0",

src/frequenz/repo/config/__init__.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33

44
"""Frequenz project setup tools and common configuration.
55
6-
The tools are provided to configure 4 main types of repositories:
6+
The tools are provided to configure the main types of repositories most commonly used at
7+
Frequenz, defined in
8+
[`freq.repo.config.RepositoryType`][freq.repo.config.RepositoryType].
79
8-
- APIs (api)
9-
- Actors (actor)
10-
- Applications (app)
11-
- Libraries (lib)
10+
- actor: SDK actors
11+
- api: gRPC APIs
12+
- app: SDK applications
13+
- lib: General purpose Python libraries
14+
- model: SDK machine learning models
1215
1316
# Common
1417
@@ -32,8 +35,8 @@
3235
nox.configure(nox.default.lib_config)
3336
```
3437
35-
Again, make sure to pick the correct default configuration based on the type of
36-
your project (`api_config`, `actor_config`, `app_config`, `lib_config`).
38+
Again, make sure to pick the correct default configuration based on the type of your
39+
project (`actor_config`, `api_config`, `app_config`, `lib_config`, `model_config`).
3740
3841
If you need to modify the configuration, you can copy one of the default
3942
configurations by using the
@@ -227,8 +230,10 @@
227230
"""
228231

229232
from . import nox, setuptools
233+
from ._core import RepositoryType
230234

231235
__all__ = [
236+
"RepositoryType",
232237
"nox",
233238
"setuptools",
234239
]

src/frequenz/repo/config/_core.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# License: MIT
2+
# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
3+
4+
"""Base types used accross the project."""
5+
6+
import enum as _enum
7+
8+
9+
class RepositoryType(_enum.Enum):
10+
"""Supported types of repository."""
11+
12+
ACTOR = "actor"
13+
"""SDK actor repository."""
14+
15+
API = "api"
16+
"""gRPC API repository."""
17+
18+
APP = "app"
19+
"""SDK application repository."""
20+
21+
LIB = "lib"
22+
"""General purpose library repository."""
23+
24+
MODEL = "model"
25+
"""SDK machine learning model repository."""

src/frequenz/repo/config/nox/config.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,37 @@
1212
The `configure()` function must be called before `get()` is used.
1313
"""
1414

15-
import dataclasses
15+
import dataclasses as _dataclasses
1616
from typing import Self
1717

18-
import nox
18+
import nox as _nox
1919

20-
from . import util
20+
from . import util as _util
2121

2222

23-
@dataclasses.dataclass(kw_only=True, slots=True)
23+
@_dataclasses.dataclass(kw_only=True, slots=True)
2424
class CommandsOptions:
2525
"""Command-line options for each command."""
2626

27-
black: list[str] = dataclasses.field(default_factory=lambda: [])
27+
black: list[str] = _dataclasses.field(default_factory=lambda: [])
2828
"""Command-line options for the `black` command."""
2929

30-
darglint: list[str] = dataclasses.field(default_factory=lambda: [])
30+
darglint: list[str] = _dataclasses.field(default_factory=lambda: [])
3131
"""Command-line options for the `darglint` command."""
3232

33-
isort: list[str] = dataclasses.field(default_factory=lambda: [])
33+
isort: list[str] = _dataclasses.field(default_factory=lambda: [])
3434
"""Command-line options for the `isort` command."""
3535

36-
mypy: list[str] = dataclasses.field(default_factory=lambda: [])
36+
mypy: list[str] = _dataclasses.field(default_factory=lambda: [])
3737
"""Command-line options for the `mypy` command."""
3838

39-
pydocstyle: list[str] = dataclasses.field(default_factory=lambda: [])
39+
pydocstyle: list[str] = _dataclasses.field(default_factory=lambda: [])
4040
"""Command-line options for the `pydocstyle` command."""
4141

42-
pylint: list[str] = dataclasses.field(default_factory=lambda: [])
42+
pylint: list[str] = _dataclasses.field(default_factory=lambda: [])
4343
"""Command-line options for the `pylint` command."""
4444

45-
pytest: list[str] = dataclasses.field(default_factory=lambda: [])
45+
pytest: list[str] = _dataclasses.field(default_factory=lambda: [])
4646
"""Command-line options for the `pytest` command."""
4747

4848
def copy(self) -> Self:
@@ -51,20 +51,20 @@ def copy(self) -> Self:
5151
Returns:
5252
The copy of self.
5353
"""
54-
return dataclasses.replace(self)
54+
return _dataclasses.replace(self)
5555

5656

57-
@dataclasses.dataclass(kw_only=True, slots=True)
57+
@_dataclasses.dataclass(kw_only=True, slots=True)
5858
class Config:
5959
"""Configuration for nox sessions."""
6060

61-
opts: CommandsOptions = dataclasses.field(default_factory=CommandsOptions)
61+
opts: CommandsOptions = _dataclasses.field(default_factory=CommandsOptions)
6262
"""Command-line options for each command used by sessions."""
6363

64-
sessions: list[str] = dataclasses.field(default_factory=lambda: [])
64+
sessions: set[str] = _dataclasses.field(default_factory=set)
6565
"""List of sessions to run."""
6666

67-
source_paths: list[str] = dataclasses.field(default_factory=lambda: [])
67+
source_paths: set[str] = _dataclasses.field(default_factory=set)
6868
"""List of paths containing source files that should be analyzed by the sessions.
6969
7070
Source paths are inspected for `__init__.py` files to look for packages.
@@ -77,7 +77,7 @@ class Config:
7777
checking.
7878
"""
7979

80-
extra_paths: list[str] = dataclasses.field(default_factory=lambda: [])
80+
extra_paths: set[str] = _dataclasses.field(default_factory=set)
8181
"""List of extra paths to be analyzed by the sessions.
8282
8383
These are not inspected for packages, as they are passed verbatim to the
@@ -89,19 +89,19 @@ def __post_init__(self) -> None:
8989
9090
This will add extra paths discovered in config files and other sources.
9191
"""
92-
for path in util.discover_paths():
92+
for path in _util.discover_paths():
9393
if path not in self.extra_paths:
94-
self.extra_paths.append(path)
94+
self.extra_paths.add(path)
9595

9696
def copy(self, /) -> Self:
9797
"""Create a new object as a copy of self.
9898
9999
Returns:
100100
The copy of self.
101101
"""
102-
return dataclasses.replace(self)
102+
return _dataclasses.replace(self)
103103

104-
def path_args(self, session: nox.Session, /) -> list[str]:
104+
def path_args(self, session: _nox.Session, /) -> set[str]:
105105
"""Return the file paths to run the checks on.
106106
107107
If positional arguments are present in the nox session, those are used
@@ -115,13 +115,13 @@ def path_args(self, session: nox.Session, /) -> list[str]:
115115
The file paths to run the checks on.
116116
"""
117117
if session.posargs:
118-
return session.posargs
118+
return set(session.posargs)
119119

120-
return [
121-
str(p) for p in util.existing_paths(self.source_paths + self.extra_paths)
122-
]
120+
return {
121+
str(p) for p in _util.existing_paths(self.source_paths | self.extra_paths)
122+
}
123123

124-
def package_args(self, session: nox.Session, /) -> list[str]:
124+
def package_args(self, session: _nox.Session, /) -> set[str]:
125125
"""Return the package names to run the checks on.
126126
127127
If positional arguments are present in the nox session, those are used
@@ -138,24 +138,24 @@ def package_args(self, session: nox.Session, /) -> list[str]:
138138
The package names found in the `source_paths`.
139139
"""
140140
if session.posargs:
141-
return session.posargs
141+
return set(session.posargs)
142142

143143
sources_package_dirs_with_roots = (
144-
(p, util.find_toplevel_package_dirs(p))
145-
for p in util.existing_paths(self.source_paths)
144+
(p, _util.find_toplevel_package_dirs(p))
145+
for p in _util.existing_paths(self.source_paths)
146146
)
147147

148148
source_packages = (
149-
util.path_to_package(pkg_path, root=root)
149+
_util.path_to_package(pkg_path, root=root)
150150
for root, pkg_paths in sources_package_dirs_with_roots
151151
for pkg_path in pkg_paths
152152
)
153153

154154
extra_packages = (
155-
util.path_to_package(p) for p in util.existing_paths(self.extra_paths)
155+
_util.path_to_package(p) for p in _util.existing_paths(self.extra_paths)
156156
)
157157

158-
return [*source_packages, *extra_packages]
158+
return {*source_packages, *extra_packages}
159159

160160

161161
_config: Config | None = None
@@ -182,4 +182,4 @@ def configure(conf: Config, /) -> None:
182182
"""
183183
global _config # pylint: disable=global-statement
184184
_config = conf
185-
nox.options.sessions = _config.sessions
185+
_nox.options.sessions = _config.sessions

src/frequenz/repo/config/nox/default.py

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,20 @@
33

44
"""Default nox configuration for different types of repositories.
55
6-
This module provides the default configuration for different types of
7-
repositories:
6+
This module provides the default configuration for the different types of
7+
repositories defined by
8+
[`frequenz.repo.config.RepositoryType`][frequenz.repo.config.RepositoryType].
89
9-
- Libraries (lib)
10-
- APIs (api)
11-
- Actors (actor)
12-
- Applications (app)
10+
The `actor_config`, `api_config`, `app_config`, `lib_config`, and `model_config`
11+
variables are the default configurations for libraries, APIs, actors and applications,
12+
respectively. The `common_config` variable is the default configuration for all types of
13+
repositories.
1314
14-
The `lib_config`, `api_config`, `actor_config` and `app_config`
15-
variables are the default configurations for libraries, APIs, actors and
16-
applications, respectively. The `common_config` variable is the default
17-
configuration for all types of repositories.
18-
19-
The `lib_command_options`, `api_command_options`, `actor_command_options` and
20-
`app_command_options` variables are the default command-line options for the same
21-
types of repositories, and the `common_command_options` variable is the default
22-
command-line options for all types of repositories.
15+
The `actor_command_options`, `api_command_options`, `app_command_options`,
16+
`lib_command_options`, and `model_command_options` variables are the default
17+
command-line options for the same types of repositories, and the
18+
`common_command_options` variable is the default command-line options for all types of
19+
repositories.
2320
2421
They can be modified before being passed to
2522
[`nox.configure()`][frequenz.repo.config.nox.configure] by using the
@@ -30,7 +27,7 @@
3027
import dataclasses
3128

3229
from . import config as _config
33-
from . import util
30+
from . import util as _util
3431

3532
common_command_options: _config.CommandsOptions = _config.CommandsOptions(
3633
black=[
@@ -59,32 +56,32 @@
5956

6057
common_config = _config.Config(
6158
opts=common_command_options.copy(),
62-
sessions=[
59+
sessions={
6360
"formatting",
6461
"mypy",
6562
"pylint",
6663
"docstrings",
6764
"pytest_min",
6865
"pytest_max",
69-
],
70-
source_paths=[
66+
},
67+
source_paths={
7168
"src",
72-
],
73-
extra_paths=[
69+
},
70+
extra_paths={
7471
"benchmarks",
7572
"docs",
7673
"examples",
7774
"noxfile.py",
7875
"tests",
79-
],
76+
},
8077
)
8178
"""Default configuration for all types of repositories."""
8279

83-
lib_command_options: _config.CommandsOptions = common_command_options.copy()
84-
"""Default command-line options for libraries."""
80+
actor_command_options: _config.CommandsOptions = common_command_options.copy()
81+
"""Default command-line options for actors."""
8582

86-
lib_config: _config.Config = common_config.copy()
87-
"""Default configuration for libraries."""
83+
actor_config: _config.Config = common_config.copy()
84+
"""Default configuration for actors."""
8885

8986
api_command_options: _config.CommandsOptions = common_command_options.copy()
9087
"""Default command-line options for APIs."""
@@ -93,24 +90,30 @@
9390
common_config,
9491
opts=api_command_options,
9592
# We don't check the sources at all because they are automatically generated.
96-
source_paths=[],
93+
source_paths=set(),
9794
# We adapt the path to the tests.
98-
extra_paths=list(util.replace(common_config.extra_paths, {"tests": "pytests"})),
95+
extra_paths=set(_util.replace(common_config.extra_paths, {"tests": "pytests"})),
9996
)
10097
"""Default configuration for APIs.
10198
10299
Same as `common_config`, but with `source_paths` replacing `"src"` with `"py"`
103100
and `extra_paths` replacing `"tests"` with `"pytests"`.
104101
"""
105102

106-
actor_command_options: _config.CommandsOptions = common_command_options.copy()
107-
"""Default command-line options for actors."""
108-
109-
actor_config: _config.Config = common_config.copy()
110-
"""Default configuration for actors."""
111-
112103
app_command_options: _config.CommandsOptions = common_command_options.copy()
113104
"""Default command-line options for applications."""
114105

115106
app_config: _config.Config = common_config.copy()
116107
"""Default configuration for applications."""
108+
109+
lib_command_options: _config.CommandsOptions = common_command_options.copy()
110+
"""Default command-line options for libraries."""
111+
112+
lib_config: _config.Config = common_config.copy()
113+
"""Default configuration for libraries."""
114+
115+
model_command_options: _config.CommandsOptions = common_command_options.copy()
116+
"""Default command-line options for models."""
117+
118+
model_config: _config.Config = common_config.copy()
119+
"""Default configuration for models."""

0 commit comments

Comments
 (0)