Skip to content

Commit

Permalink
Replace flake8 and isort with ruff linter and add black --check to …
Browse files Browse the repository at this point in the history
…linting step (#1763)

* Add ruff

* Add ruff config

* Add ruff rules that look useful and are already passing

* Add more ruff rules after talking with Jonathan

* Add line length exception for acceptably long indented line

* Resolve ruff line length 88 rule in args. Changing small lines but adding a noqa ignore directive to longer lines that look best as they are. Their dedented length is still less than 88

* poe format

* Resolve all remaining ruff line length errors

* Replace flake* and isort with ruff calls

* Add black --check as final lint step. ruff catches most but not all black formatting issues

* Remove unneeded flakeheaven setting

* Remove flake* and isort now that ruff is handling all their business

* Update pyproject, lockfile with latest version of ruff

* Document each ruff rule with comment

* Add black --version call before black --check

* Remove extraneous period
  • Loading branch information
micahellison authored Jul 15, 2023
1 parent dd09ece commit 34c7903
Show file tree
Hide file tree
Showing 20 changed files with 162 additions and 396 deletions.
29 changes: 19 additions & 10 deletions jrnl/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
"""
We gratefully thank all contributors!
Come see the whole list of code and financial contributors at https://github.com/jrnl-org/jrnl
And special thanks to Bad Lip Reading for the Yoda joke in the Writing section above :)"""
And special thanks to Bad Lip Reading for the Yoda joke in the Writing section above :)""" # noqa: E501
),
)

Expand Down Expand Up @@ -214,7 +214,8 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
composing.add_argument(
"--template",
dest="template",
help="Path to template file. Can be a local path, absolute path, or a path relative to $XDG_DATA_HOME/jrnl/templates/",
help="Path to template file. Can be a local path, absolute path, or a path "
"relative to $XDG_DATA_HOME/jrnl/templates/",
)

read_msg = (
Expand Down Expand Up @@ -265,13 +266,15 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
"-contains",
dest="contains",
metavar="TEXT",
help="Show entries containing specific text (put quotes around text with spaces)",
help="Show entries containing specific text (put quotes around text with "
"spaces)",
)
reading.add_argument(
"-and",
dest="strict",
action="store_true",
help='Show only entries that match all conditions, like saying "x AND y" (default: OR)',
help='Show only entries that match all conditions, like saying "x AND y" '
"(default: OR)",
)
reading.add_argument(
"-starred",
Expand All @@ -290,7 +293,8 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
dest="limit",
default=None,
metavar="NUMBER",
help="Show a maximum of NUMBER entries (note: '-n 3' and '-3' have the same effect)",
help="Show a maximum of NUMBER entries (note: '-n 3' and '-3' have the same "
"effect)",
nargs="?",
type=int,
)
Expand All @@ -308,8 +312,12 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
),
)

search_options_msg = """ These help you do various tasks with the selected entries from your search.
If used on their own (with no search), they will act on your entire journal"""
search_options_msg = (
" " # Preserves indentation
"""
These help you do various tasks with the selected entries from your search.
If used on their own (with no search), they will act on your entire journal"""
)
exporting = parser.add_argument_group(
"Searching Options", textwrap.dedent(search_options_msg)
)
Expand Down Expand Up @@ -360,7 +368,8 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
"--tags",
dest="tags",
action="store_true",
help="Alias for '--format tags'. Returns a list of all tags and number of occurrences",
help="Alias for '--format tags'. Returns a list of all tags and number of "
"occurrences",
)
exporting.add_argument(
"--short",
Expand Down Expand Up @@ -400,7 +409,7 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
\t jrnl --config-override editor "nano" \n
\t - Override color selections\n
\t jrnl --config-override colors.body blue --config-override colors.title green
""",
""", # noqa: E501
)
config_overrides.add_argument(
"--co",
Expand Down Expand Up @@ -430,7 +439,7 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
\t jrnl --config-file /home/user1/work_config.yaml
\t - Use a personal config file stored on a thumb drive: \n
\t jrnl --config-file /media/user1/my-thumb-drive/personal_config.yaml
""",
""", # noqa: E501
)

alternate_config.add_argument(
Expand Down
2 changes: 1 addition & 1 deletion jrnl/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def postconfig_encrypt(
def postconfig_decrypt(
args: argparse.Namespace, config: dict, original_config: dict
) -> int:
"""Decrypts into new file. If filename is not set, we encrypt the journal file itself."""
"""Decrypts to file. If filename is not set, we encrypt the journal file itself."""
from jrnl.config import update_config
from jrnl.install import save_config
from jrnl.journals import open_journal
Expand Down
5 changes: 3 additions & 2 deletions jrnl/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ def make_yaml_valid_dict(input: list) -> dict:
The dict is created through the yaml loader, with the assumption that
"input[0]: input[1]" is valid yaml.
:param input: list of configuration keys in dot-notation and their respective values.
:param input: list of configuration keys in dot-notation and their respective values
:type input: list
:return: A single level dict of the configuration keys in dot-notation and their respective desired values
:return: A single level dict of the configuration keys in dot-notation and their
respective desired values
:rtype: dict
"""

Expand Down
8 changes: 5 additions & 3 deletions jrnl/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
def run(args: "Namespace"):
"""
Flow:
1. Run standalone command if it doesn't require config (help, version, etc), then exit
1. Run standalone command if it doesn't need config (help, version, etc), then exit
2. Load config
3. Run standalone command if it does require config (encrypt, decrypt, etc), then exit
3. Run standalone command if it does need config (encrypt, decrypt, etc), then exit
4. Load specified journal
5. Start append mode, or search mode
6. Perform actions with results from search mode (if needed)
Expand Down Expand Up @@ -181,7 +181,9 @@ def append_mode(args: "Namespace", config: dict, journal: "Journal", **kwargs) -
def _get_template(args, config) -> str:
# Read template file and pass as raw text into the composer
logging.debug(
f"Get template:\n--template: {args.template}\nfrom config: {config.get('template')}"
"Get template:\n"
f"--template: {args.template}\n"
f"from config: {config.get('template')}"
)
template_path = args.template or config.get("template")

Expand Down
3 changes: 2 additions & 1 deletion jrnl/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ def get_template_path(template_path: str, jrnl_template_dir: str) -> str:
actual_template_path = os.path.join(jrnl_template_dir, template_path)
if not os.path.exists(actual_template_path):
logging.debug(
f"Couldn't open {actual_template_path}. Treating template path like a local / abs path."
f"Couldn't open {actual_template_path}. "
"Treating template path like a local / abs path."
)
actual_template_path = absolute_path(template_path)

Expand Down
12 changes: 6 additions & 6 deletions jrnl/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@


def upgrade_config(config_data: dict, alt_config_path: str | None = None) -> None:
"""Checks if there are keys missing in a given config dict, and if so, updates the config file accordingly.
This essentially automatically ports jrnl installations if new config parameters are introduced in later
versions.
Also checks for existence of and difference in version number between config dict and current jrnl version,
and if so, update the config file accordingly.
"""Checks if there are keys missing in a given config dict, and if so, updates the
config file accordingly. This essentially automatically ports jrnl installations
if new config parameters are introduced in later versions. Also checks for
existence of and difference in version number between config dict
and current jrnl version, and if so, update the config file accordingly.
Supply alt_config_path if using an alternate config through --config-file."""
default_config = get_default_config()
missing_keys = set(default_config).difference(config_data)
Expand Down Expand Up @@ -167,7 +167,7 @@ def install() -> dict:


def _initialize_autocomplete() -> None:
# readline is not included in Windows Active Python and perhaps some other distributions
# readline is not included in Windows Active Python and perhaps some other distss
if sys.modules.get("readline"):
import readline

Expand Down
4 changes: 2 additions & 2 deletions jrnl/journals/Entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def _parse_tags(self) -> set[str]:
}

def __str__(self):
"""Returns a string representation of the entry to be written into a journal file."""
"""Returns string representation of the entry to be written to journal file."""
date_str = self.date.strftime(self.journal.config["timeformat"])
title = "[{}] {}".format(date_str, self.title.rstrip("\n "))
if self.starred:
Expand Down Expand Up @@ -233,7 +233,7 @@ def __ne__(self, other: "Entry"):
\s+ # AND a sequence of required spaces.
)
|[\uFF01\uFF0E\uFF1F\uFF61\u3002] # CJK full/half width terminals usually do not have following spaces.
""",
""", # noqa: E501
re.VERBOSE,
)

Expand Down
3 changes: 2 additions & 1 deletion jrnl/journals/FolderJournal.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ def parse_editable_str(self, edited: str) -> None:

@staticmethod
def _get_files(journal_path: str) -> list[str]:
"""Searches through sub directories starting with journal_path and find all text files that look like entries"""
"""Searches through sub directories starting with journal_path and find all text
files that look like entries"""
for year_folder in Folder._get_year_folders(pathlib.Path(journal_path)):
for month_folder in Folder._get_month_folders(year_folder):
yield from Folder._get_day_files(month_folder)
Expand Down
12 changes: 7 additions & 5 deletions jrnl/journals/Journal.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def _encrypt(self, text: str) -> bytes:
return self.encryption_method.encrypt(text)

def open(self, filename: str | None = None) -> "Journal":
"""Opens the journal file defined in the config and parses it into a list of Entries.
"""Opens the journal file and parses it into a list of Entries
Entries have the form (date, title, body)."""
filename = filename or self.config["journal"]
dirname = os.path.dirname(filename)
Expand Down Expand Up @@ -144,7 +144,7 @@ def write(self, filename: str | None = None) -> None:
self._store(filename, text)

def validate_parsing(self) -> bool:
"""Confirms that the jrnl is still parsed correctly after being dumped to text."""
"""Confirms that the jrnl is still parsed correctly after conversion to text."""
new_entries = self._parse(self._to_text())
return all(entry == new_entries[i] for i, entry in enumerate(self.entries))

Expand Down Expand Up @@ -225,8 +225,9 @@ def limit(self, n: int | None = None) -> None:
@property
def tags(self) -> list[Tag]:
"""Returns a set of tuples (count, tag) for all tags present in the journal."""
# Astute reader: should the following line leave you as puzzled as me the first time
# I came across this construction, worry not and embrace the ensuing moment of enlightment.
# Astute reader: should the following line leave you as puzzled as me the first
# time I came across this construction, worry not and embrace the ensuing moment
# of enlightment.
tags = [tag for entry in self.entries for tag in set(entry.tags)]
# To be read: [for entry in journal.entries: for tag in set(entry.tags): tag]
tag_counts = {(tags.count(tag), tag) for tag in tags}
Expand Down Expand Up @@ -343,7 +344,8 @@ def ask_action(entry):

def new_entry(self, raw: str, date=None, sort: bool = True) -> Entry:
"""Constructs a new entry from some raw text input.
If a date is given, it will parse and use this, otherwise scan for a date in the input first.
If a date is given, it will parse and use this, otherwise scan for a date in
the input first.
"""

raw = raw.replace("\\n ", "\n").replace("\\n", "\n")
Expand Down
4 changes: 2 additions & 2 deletions jrnl/messages/MsgText.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def __str__(self) -> str:
Do you want to encrypt your journal? (You can always change this later)
"""
UseColorsQuestion = """
Do you want jrnl to use colors when displaying entries? (You can always change this later)
"""
Do you want jrnl to use colors to display entries? (You can always change this later)
""" # noqa: E501 - the line is still under 88 when dedented
YesOrNoPromptDefaultYes = "[Y/n]"
YesOrNoPromptDefaultNo = "[y/N]"
ContinueUpgrade = "Continue upgrading jrnl?"
Expand Down
3 changes: 2 additions & 1 deletion jrnl/override.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def _recursively_apply(tree: dict, nodes: list, override_value) -> dict:
Args:
config (dict): Configuration to modify
nodes (list): Vector of override keys; the length of the vector indicates tree depth
nodes (list): Vector of override keys; the length of the vector indicates tree
depth
override_value (str): Runtime override passed from the command-line
"""
key = nodes[0]
Expand Down
2 changes: 1 addition & 1 deletion jrnl/plugins/fancy_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


class FancyExporter(TextExporter):
"""This Exporter can convert entries and journals into text with unicode box drawing characters."""
"""This Exporter converts entries and journals into text with unicode boxes."""

names = ["fancy", "boxed"]
extension = "txt"
Expand Down
2 changes: 1 addition & 1 deletion jrnl/plugins/tag_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


class TagExporter(TextExporter):
"""This Exporter can lists the tags for entries and journals, exported as a plain text file."""
"""This Exporter lists the tags for entries and journals."""

names = ["tags"]
extension = "tags"
Expand Down
3 changes: 2 additions & 1 deletion jrnl/plugins/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
def get_tags_count(journal: "Journal") -> set[tuple[int, str]]:
"""Returns a set of tuples (count, tag) for all tags present in the journal."""
# Astute reader: should the following line leave you as puzzled as me the first time
# I came across this construction, worry not and embrace the ensuing moment of enlightment.
# I came across this construction, worry not and embrace the ensuing moment of
# enlightment.
tags = [tag for entry in journal.entries for tag in set(entry.tags)]
# To be read: [for entry in journal.entries: for tag in set(entry.tags): tag]
tag_counts = {(tags.count(tag), tag) for tag in tags}
Expand Down
14 changes: 11 additions & 3 deletions jrnl/plugins/yaml_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@


class YAMLExporter(TextExporter):
"""This Exporter can convert entries and journals into Markdown formatted text with YAML front matter."""
"""This Exporter converts entries and journals into Markdown formatted text with
YAML front matter."""

names = ["yaml"]
extension = "md"

@classmethod
def export_entry(cls, entry: "Entry", to_multifile: bool = True) -> str:
"""Returns a markdown representation of a single entry, with YAML front matter."""
"""Returns a markdown representation of an entry, with YAML front matter."""
if to_multifile is False:
raise JrnlException(Message(MsgText.YamlMustBeDirectory, MsgStyle.ERROR))

Expand Down Expand Up @@ -117,7 +118,14 @@ def export_entry(cls, entry: "Entry", to_multifile: bool = True) -> str:
# source directory is entry.journal.config['journal']
# output directory is...?

return "{start}\ntitle: {title}\ndate: {date}\nstarred: {starred}\ntags: {tags}\n{dayone}body: |{body}{end}".format(
return (
"{start}\n"
"title: {title}\n"
"date: {date}\n"
"starred: {starred}\n"
"tags: {tags}\n"
"{dayone}body: |{body}{end}"
).format(
start="---",
date=date_str,
title=entry.title,
Expand Down
10 changes: 5 additions & 5 deletions jrnl/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ def parse(
elif isinstance(date_str, datetime.datetime):
return date_str

# Don't try to parse anything with 6 or fewer characters and was parsed from the existing journal.
# It's probably a markdown footnote
# Don't try to parse anything with 6 or fewer characters and was parsed from the
# existing journal. It's probably a markdown footnote
if len(date_str) <= 6 and bracketed:
return None

Expand Down Expand Up @@ -82,9 +82,9 @@ def parse(
else:
date = datetime.datetime(*date[:6])

# Ugly heuristic: if the date is more than 4 weeks in the future, we got the year wrong.
# Rather than this, we would like to see parsedatetime patched so we can tell it to prefer
# past dates
# Ugly heuristic: if the date is more than 4 weeks in the future, we got the year
# wrong. Rather than this, we would like to see parsedatetime patched so we can
# tell it to prefer past dates
dt = datetime.datetime.now() - date
if dt.days < -28 and not year_present:
date = date.replace(date.year - 1)
Expand Down
Loading

0 comments on commit 34c7903

Please sign in to comment.