Skip to content

Commit a1ed48a

Browse files
committed
Add "British English" and "Import modules, not objects" rules
Also a few other code review updates
1 parent d326572 commit a1ed48a

File tree

1 file changed

+52
-6
lines changed

1 file changed

+52
-6
lines changed

STYLE.md

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
21
# Ops Python style guide
32

43
This is the Python style guide we use for the Ops project. However, it's also the style we're converging on for other projects maintained by the Charm Tech team.
54

65
We use Ruff for formatting, and run our code through the Pyright type checker. We also try to follow [PEP 8](https://peps.python.org/pep-0008/), the official Python style guide. However, PEP 8 is fairly low-level, so in addition we've come up with the following style guidelines.
76

7+
New code should follow these guidelines, unless there's a good reason not to. Sometimes existing code doesn't follow these rules, but we're happy for it to be updated to do so (either all at once or as nearby code is changed).
8+
89
Of course, this is just a start! We add to this list as things come up in code review and we make a team decision.
910

1011

@@ -17,7 +18,7 @@ Of course, this is just a start! We add to this list as things come up in code r
1718

1819
## Simplicity
1920

20-
### Avoid nested comprehensions
21+
### Avoid nested comprehensions and generators
2122

2223
"Flat is better than nested."
2324

@@ -27,7 +28,7 @@ Of course, this is just a start! We add to this list as things come up in code r
2728
units = [units for app in model.apps for unit in app.units]
2829

2930
for current in (
30-
status for status in pebble.ServiceStatus if status is not pebble.ServiceStatus.ACTIVE
31+
status for status in pebble.ServiceStatus if status != pebble.ServiceStatus.ACTIVE
3132
):
3233
...
3334
```
@@ -40,13 +41,51 @@ for app in model.apps:
4041
for unit in app.units:
4142
units.append(unit)
4243

43-
active_statuses = [status for status in pebble.ServiceStatus if status != pebble.ServiceStatus.ACTIVE]
44-
for current in active_statuses:
44+
for current in pebble.ServiceStatus:
45+
if status == pebble.ServiceStatus.ACTIVE:
46+
continue
4547
...
4648
```
4749

4850
## Specific decisions
4951

52+
### Import modules, not objects
53+
54+
"Namespaces are one honking great idea -- let's do more of those!"
55+
56+
When reading code, it's significantly easier to tell where a name came from if it is prefixed with the package name.
57+
58+
An exception is names from `typing` -- type annotations get too verbose if these all have to be prefixed with `typing.`.
59+
60+
**Don't:**
61+
62+
```python
63+
from subprocess import run
64+
from ops import CharmBase, PebbleReadyEvent
65+
import typing
66+
67+
class MyCharm(CharmBase):
68+
counts: typing.Optional[typing.Tuple[str, int]]
69+
70+
def _pebble_ready(self, event: PebbleReadyEvent):
71+
run(['echo', 'foo'])
72+
```
73+
74+
**Do:**
75+
76+
```python
77+
import subprocess
78+
import ops
79+
from typing import Optional, Tuple
80+
81+
class MyCharm(ops.CharmBase):
82+
counts: Optional[Tuple[str, int]]
83+
84+
def _pebble_ready(self, event: ops.PebbleReadyEvent):
85+
run(['echo', 'foo'])
86+
```
87+
88+
5089
### Compare enum values by equality
5190

5291
This is six of one, half a dozen of the other, but we've decided that saying `if color == Color.RED` is nicer than `if color is Color.RED` as `==` is more typical for integer- and string-like values, and if you do use an `IntEnum` or `StrEnum` you should use `==` anyway.
@@ -76,6 +115,13 @@ if status != pebble.ServiceStatus.ACTIVE:
76115

77116
## Docs and docstrings
78117

118+
### Use British English
119+
120+
[Canonical's documentation style](https://docs.ubuntu.com/styleguide/en/) is to use British spellings, and we try to follow that here. For example, "colour" rather than "color", "labelled" rather than "labeled", "serialise" rather than "serialize", and so on.
121+
122+
It's a bit less clear when we're dealing with code and APIs, as those normally use US English, for example, `pytest.mark.parametrize`, and `color: #fff`.
123+
124+
79125
### Spell out abbreviations
80126

81-
Prefer spelling out abbreviations and acronyms in docstrings, for example, "for example" rather than "e.g.", "that is" rather than "i.e.", and "unit testing" rather than UT.
127+
Prefer spelling out abbreviations and acronyms in docstrings, for example, "for example" rather than "e.g.", "that is" rather than "i.e.", "and so on" rather than "etc", and "unit testing" rather than UT.

0 commit comments

Comments
 (0)