Add more type hints (#1642)

This commit is contained in:
outa 2023-01-14 22:22:31 +01:00 committed by GitHub
parent 9547411390
commit a13726d4c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 43 deletions

View file

@ -48,33 +48,33 @@ class Entry:
self._tags = list(self._parse_tags()) self._tags = list(self._parse_tags())
@property @property
def title(self): def title(self) -> str:
if self._title is None: if self._title is None:
self._parse_text() self._parse_text()
return self._title return self._title
@title.setter @title.setter
def title(self, x): def title(self, x: str):
self._title = x self._title = x
@property @property
def body(self): def body(self) -> str:
if self._body is None: if self._body is None:
self._parse_text() self._parse_text()
return self._body return self._body
@body.setter @body.setter
def body(self, x): def body(self, x: str):
self._body = x self._body = x
@property @property
def tags(self): def tags(self) -> list[str]:
if self._tags is None: if self._tags is None:
self._parse_text() self._parse_text()
return self._tags return self._tags
@tags.setter @tags.setter
def tags(self, x): def tags(self, x: list[str]):
self._tags = x self._tags = x
@staticmethod @staticmethod
@ -218,7 +218,7 @@ class Entry:
return False return False
return True return True
def __ne__(self, other): def __ne__(self, other: "Entry"):
return not self.__eq__(other) return not self.__eq__(other)

View file

@ -59,7 +59,7 @@ class Journal:
return (entry for entry in self.entries) return (entry for entry in self.entries)
@classmethod @classmethod
def from_journal(cls, other): def from_journal(cls, other: "Journal") -> "Journal":
"""Creates a new journal by copying configuration and entries from """Creates a new journal by copying configuration and entries from
another journal object""" another journal object"""
new_journal = cls(other.name, **other.config) new_journal = cls(other.name, **other.config)
@ -72,7 +72,7 @@ class Journal:
) )
return new_journal return new_journal
def import_(self, other_journal_txt): def import_(self, other_journal_txt: str) -> None:
imported_entries = self._parse(other_journal_txt) imported_entries = self._parse(other_journal_txt)
for entry in imported_entries: for entry in imported_entries:
entry.modified = True entry.modified = True
@ -96,7 +96,7 @@ class Journal:
return self.encryption_method.encrypt(text) return self.encryption_method.encrypt(text)
def open(self, filename=None): 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 defined in the config and parses it into a list of Entries.
Entries have the form (date, title, body).""" Entries have the form (date, title, body)."""
filename = filename or self.config["journal"] filename = filename or self.config["journal"]
@ -130,35 +130,35 @@ class Journal:
logging.debug("opened %s with %d entries", self.__class__.__name__, len(self)) logging.debug("opened %s with %d entries", self.__class__.__name__, len(self))
return self return self
def write(self, filename=None): def write(self, filename: str | None = None) -> None:
"""Dumps the journal into the config file, overwriting it""" """Dumps the journal into the config file, overwriting it"""
filename = filename or self.config["journal"] filename = filename or self.config["journal"]
text = self._to_text() text = self._to_text()
text = self._encrypt(text) text = self._encrypt(text)
self._store(filename, text) self._store(filename, text)
def validate_parsing(self): 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 being dumped to text."""
new_entries = self._parse(self._to_text()) new_entries = self._parse(self._to_text())
return all(entry == new_entries[i] for i, entry in enumerate(self.entries)) return all(entry == new_entries[i] for i, entry in enumerate(self.entries))
@staticmethod @staticmethod
def create_file(filename): def create_file(filename: str) -> None:
with open(filename, "w"): with open(filename, "w"):
pass pass
def _to_text(self): def _to_text(self) -> str:
return "\n".join([str(e) for e in self.entries]) return "\n".join([str(e) for e in self.entries])
def _load(self, filename): def _load(self, filename: str) -> bytes:
with open(filename, "rb") as f: with open(filename, "rb") as f:
return f.read() return f.read()
def _store(self, filename, text): def _store(self, filename: str, text: bytes) -> None:
with open(filename, "wb") as f: with open(filename, "wb") as f:
f.write(text) f.write(text)
def _parse(self, journal_txt): def _parse(self, journal_txt: str) -> list[Entry]:
"""Parses a journal that's stored in a string and returns a list of entries""" """Parses a journal that's stored in a string and returns a list of entries"""
# Return empty array if the journal is blank # Return empty array if the journal is blank
@ -197,7 +197,7 @@ class Journal:
entry._parse_text() entry._parse_text()
return entries return entries
def pprint(self, short=False): def pprint(self, short: bool = False) -> str:
"""Prettyprints the journal's entries""" """Prettyprints the journal's entries"""
return "\n".join([e.pprint(short=short) for e in self.entries]) return "\n".join([e.pprint(short=short) for e in self.entries])
@ -207,17 +207,17 @@ class Journal:
def __repr__(self): def __repr__(self):
return f"<Journal with {len(self.entries)} entries>" return f"<Journal with {len(self.entries)} entries>"
def sort(self): def sort(self) -> None:
"""Sorts the Journal's entries by date""" """Sorts the Journal's entries by date"""
self.entries = sorted(self.entries, key=lambda entry: entry.date) self.entries = sorted(self.entries, key=lambda entry: entry.date)
def limit(self, n=None): def limit(self, n: int | None = None) -> None:
"""Removes all but the last n entries""" """Removes all but the last n entries"""
if n: if n:
self.entries = self.entries[-n:] self.entries = self.entries[-n:]
@property @property
def tags(self): def tags(self) -> list[Tag]:
"""Returns a set of tuples (count, tag) for all tags present in the journal.""" """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 # 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.
@ -228,16 +228,16 @@ class Journal:
def filter( def filter(
self, self,
tags=[], tags: list = [],
month=None, month: str | int | None = None,
day=None, day: str | int | None = None,
year=None, year: str | None = None,
start_date=None, start_date: str | None = None,
end_date=None, end_date: str | None = None,
starred=False, starred: bool = False,
strict=False, strict: bool = False,
contains=None, contains: bool = None,
exclude=[], exclude: list = [],
): ):
"""Removes all entries from the journal that don't match the filter. """Removes all entries from the journal that don't match the filter.
@ -293,19 +293,19 @@ class Journal:
self.entries = result self.entries = result
def delete_entries(self, entries_to_delete): def delete_entries(self, entries_to_delete: list[Entry]) -> None:
"""Deletes specific entries from a journal.""" """Deletes specific entries from a journal."""
for entry in entries_to_delete: for entry in entries_to_delete:
self.entries.remove(entry) self.entries.remove(entry)
def change_date_entries(self, date): def change_date_entries(self, date: datetime.datetime | None) -> None:
"""Changes entry dates to given date.""" """Changes entry dates to given date."""
date = time.parse(date) date = time.parse(date)
for entry in self.entries: for entry in self.entries:
entry.date = date entry.date = date
def prompt_action_entries(self, msg: MsgText): def prompt_action_entries(self, msg: MsgText) -> list[Entry]:
"""Prompts for action for each entry in a journal, using given message. """Prompts for action for each entry in a journal, using given message.
Returns the entries the user wishes to apply the action on.""" Returns the entries the user wishes to apply the action on."""
to_act = [] to_act = []
@ -325,7 +325,7 @@ class Journal:
return to_act return to_act
def new_entry(self, raw, date=None, sort=True): def new_entry(self, raw: str, date=None, sort: bool = True) -> Entry:
"""Constructs a new entry from some raw text input. """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."""
@ -361,12 +361,12 @@ class Journal:
self.sort() self.sort()
return entry return entry
def editable_str(self): def editable_str(self) -> str:
"""Turns the journal into a string of entries that can be edited """Turns the journal into a string of entries that can be edited
manually and later be parsed with self.parse_editable_str.""" manually and later be parsed with self.parse_editable_str."""
return "\n".join([str(e) for e in self.entries]) return "\n".join([str(e) for e in self.entries])
def parse_editable_str(self, edited): def parse_editable_str(self, edited: str) -> None:
"""Parses the output of self.editable_str and updates it's entries.""" """Parses the output of self.editable_str and updates it's entries."""
mod_entries = self._parse(edited) mod_entries = self._parse(edited)
# Match those entries that can be found in self.entries and set # Match those entries that can be found in self.entries and set
@ -382,7 +382,7 @@ class LegacyJournal(Journal):
standard. Main difference here is that in 1.x, timestamps were not cuddled standard. Main difference here is that in 1.x, timestamps were not cuddled
by square brackets. You'll not be able to save these journals anymore.""" by square brackets. You'll not be able to save these journals anymore."""
def _parse(self, journal_txt): def _parse(self, journal_txt: str) -> list[Entry]:
"""Parses a journal that's stored in a string and returns a list of entries""" """Parses a journal that's stored in a string and returns a list of entries"""
# Entries start with a line that looks like 'date title' - let's figure out how # Entries start with a line that looks like 'date title' - let's figure out how
# long the date will be by constructing one # long the date will be by constructing one
@ -429,7 +429,7 @@ class LegacyJournal(Journal):
return entries return entries
def open_journal(journal_name, config, legacy=False): def open_journal(journal_name: str, config: dict, legacy: bool = False) -> Journal:
""" """
Creates a normal, encrypted or DayOne journal based on the passed config. Creates a normal, encrypted or DayOne journal based on the passed config.
If legacy is True, it will open Journals with legacy classes build for If legacy is True, it will open Journals with legacy classes build for

View file

@ -28,7 +28,7 @@ from jrnl.messages import MsgText
from jrnl.output import print_msg from jrnl.output import print_msg
def preconfig_diagnostic(_): def preconfig_diagnostic(_) -> None:
from jrnl import __title__ from jrnl import __title__
from jrnl import __version__ from jrnl import __version__
@ -39,7 +39,7 @@ def preconfig_diagnostic(_):
) )
def preconfig_version(_): def preconfig_version(_) -> None:
import textwrap import textwrap
from jrnl import __title__ from jrnl import __title__

View file

@ -4,6 +4,7 @@
from enum import Enum from enum import Enum
from importlib import import_module from importlib import import_module
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Type
if TYPE_CHECKING: if TYPE_CHECKING:
from .BaseEncryption import BaseEncryption from .BaseEncryption import BaseEncryption
@ -18,7 +19,7 @@ class EncryptionMethods(str, Enum):
JRNLV2 = "Jrnlv2Encryption" JRNLV2 = "Jrnlv2Encryption"
def determine_encryption_method(config: str | bool) -> "BaseEncryption": def determine_encryption_method(config: str | bool) -> Type["BaseEncryption"]:
ENCRYPTION_METHODS = { ENCRYPTION_METHODS = {
True: EncryptionMethods.JRNLV2, # the default True: EncryptionMethods.JRNLV2, # the default
False: EncryptionMethods.NONE, False: EncryptionMethods.NONE,

View file

@ -18,7 +18,7 @@ def get_keyring_password(journal_name: str = "default") -> str | None:
return None return None
def set_keyring_password(password: str, journal_name: str = "default"): def set_keyring_password(password: str, journal_name: str = "default") -> None:
try: try:
return keyring.set_password("jrnl", journal_name, password) return keyring.set_password("jrnl", journal_name, password)
except keyring.errors.KeyringError as e: except keyring.errors.KeyringError as e: