Skip to content

Commit

Permalink
ruff: suggest using from __future__ import annotations, switch List -…
Browse files Browse the repository at this point in the history
…> list, Dict -> dict, Optional -> | where possible
  • Loading branch information
karlicoss committed Aug 29, 2024
1 parent 35276b5 commit d5c39cd
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 53 deletions.
7 changes: 1 addition & 6 deletions ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ lint.extend-select = [
"TID", # various imports suggestions
"TRY", # various exception handling rules
"UP", # detect deprecated python stdlib stuff
# "FA", # TODO enable later after we make sure cachew works?
"FA", # suggest using from __future__ import annotations
"PTH", # pathlib migration
"ARG", # unused argument checks
"A", # builtin shadowing
Expand Down Expand Up @@ -69,11 +69,6 @@ lint.ignore = [
"F401", # imported but unused
###

### TODO should be fine to use these with from __future__ import annotations?
### there was some issue with cachew though... double check this?
"UP006", # use type instead of Type
"UP007", # use X | Y instead of Union
###
"RUF100", # unused noqa -- handle later
"RUF012", # mutable class attrs should be annotated with ClassVar... ugh pretty annoying for user configs

Expand Down
6 changes: 4 additions & 2 deletions src/orger/common.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from __future__ import annotations

import traceback
import warnings
from datetime import datetime
from pathlib import Path
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING

from .inorganic import OrgNode, TimestampStyle, timestamp, timestamp_with_style

Expand All @@ -14,7 +16,7 @@ class settings:


_timezones = set() # type: ignore
def dt_heading(dt: Optional[datetime], heading: str) -> str:
def dt_heading(dt: datetime | None, heading: str) -> str:
"""
Helper to inline datetime in heading
"""
Expand Down
38 changes: 18 additions & 20 deletions src/orger/inorganic.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import logging
import os
import re
Expand All @@ -12,12 +14,8 @@
TYPE_CHECKING,
Any,
Callable,
Dict,
List,
Mapping,
Optional,
Sequence,
Tuple,
TypeVar,
Union,
)
Expand All @@ -36,7 +34,7 @@ class TimestampStyle(Enum):
PathIsh = Union[str, Path]


def link(*, url: PathIsh, title: Optional[str]) -> str:
def link(*, url: PathIsh, title: str | None) -> str:
"""
>>> link(url='http://reddit.com', title='[R]eddit!')
'[[http://reddit.com][Reddit!]]'
Expand All @@ -53,7 +51,7 @@ def link(*, url: PathIsh, title: Optional[str]) -> str:
return f'[[{U}]]'


def docview_link(*, path: PathIsh, title: Optional[str], page1: Optional[int]=None) -> str:
def docview_link(*, path: PathIsh, title: str | None, page1: int | None = None) -> str:
"""
Generates a docview link to open pdfs.
page1: 1-indexed (!) pdf page number.
Expand Down Expand Up @@ -130,14 +128,14 @@ def quoted(self) -> str:
# TODO priority
# TODO for sanitizing, have two strategies: error and replace?
def asorgoutline(
heading: Optional[str] = None,
heading: str | None = None,
*,
todo: Optional[str] = None,
todo: str | None = None,
tags: Sequence[str] = [],
scheduled: Optional[Dateish] = None,
scheduled: Dateish | None = None,
# TODO perhaps allow list of tuples? properties might be repeating
properties: Optional[Mapping[str, str]] = None,
body: Optional[Body] = None,
properties: Mapping[str, str] | None = None,
body: Body | None = None,
level: int = 1,
escaped: bool = False,
) -> str:
Expand Down Expand Up @@ -176,7 +174,7 @@ def asorgoutline(
heading = re.sub(r'\s', ' ', heading)

# TODO not great that we always pad body I guess. maybe needs some sort of raw_body argument?
safe_body: Optional[str] = None
safe_body: str | None = None
if body is not None:
# todo https://github.com/karlicoss/orger/issues/16
# maybe need a policy for body behaviour... I guess policy could be Union[Literate]; controlled by env variables?
Expand Down Expand Up @@ -205,7 +203,7 @@ def asorgoutline(
'SCHEDULED: ' + timestamp(scheduled, active=True)
]

props_lines: List[str] = []
props_lines: list[str] = []
props = {} if properties is None else properties
if len(props) > 0:
props_lines.append(':PROPERTIES:')
Expand Down Expand Up @@ -238,13 +236,13 @@ class OrgNode:
"""

heading: Lazy[str]
todo: Optional[str] = None
todo: str | None = None
tags: Sequence[str] = ()
scheduled: Optional[Dateish] = None
properties: Optional[Mapping[str, str]] = None
scheduled: Dateish | None = None
properties: Mapping[str, str] | None = None
# TODO make body lazy as well?
body: Optional[Body] = None
children: Sequence['OrgNode'] = ()
body: Body | None = None
children: Sequence[OrgNode] = ()

# NOTE: this is a 'private' attribute
escaped: bool = False
Expand All @@ -261,7 +259,7 @@ def _render_self(self) -> str:
escaped=self.escaped,
)

def _render_hier(self) -> List[Tuple[int, str]]:
def _render_hier(self) -> list[tuple[int, str]]:
res = [(0, self._render_self())]
for ch in self.children:
# TODO make sure there is a space??
Expand Down Expand Up @@ -307,7 +305,7 @@ def _from_lazy(x: Lazy[T]) -> T:
return x


def maketrans(d: Dict[str, str]) -> Dict[int, str]:
def maketrans(d: dict[str, str]) -> dict[int, str]:
# make mypy happy... https://github.com/python/mypy/issues/4374
return str.maketrans(d)

Expand Down
16 changes: 9 additions & 7 deletions src/orger/modules/auto.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/usr/bin/env python3
from __future__ import annotations

from orger import Mirror
from orger.inorganic import node, link, Quoted
from orger.common import dt_heading, error

from datetime import datetime
from typing import Optional, List, Iterator, Any
from typing import Iterator, Any
from pprint import pformat
import string

Expand All @@ -22,12 +24,12 @@ class Auto(Mirror):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
# TODO move this functionality to base module? might be useful for all modules
self.extra_warnings: List[str] = []
self.extra_warnings: list[str] = []

# these will be set below
self.group_by_attr: Optional[str] = None
self.body_attr : Optional[str] = None
self.title_attr : Optional[str] = None
self.group_by_attr: str | None = None
self.body_attr : str | None = None
self.title_attr : str | None = None


def get_items(self) -> Mirror.Results:
Expand Down Expand Up @@ -91,7 +93,7 @@ def render_one(self, thing) -> Iterator[node]:
cls = thing.__class__

datetimes = [(k, v) for k, v in thing_dict.items() if isinstance(v, datetime)]
dt: Optional[datetime] = None
dt: datetime | None = None
if len(datetimes) == 1:
[(k, dt)] = datetimes
# todo maybe warn that datetime is guessed
Expand All @@ -107,7 +109,7 @@ def render_one(self, thing) -> Iterator[node]:
except KeyError as e:
yield error(e)

def fmt_attr(attr: Optional[str]) -> Optional[str]:
def fmt_attr(attr: str | None) -> str | None:
if attr is None:
return None

Expand Down
4 changes: 2 additions & 2 deletions src/orger/modules/pinboard.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
from typing import List
from __future__ import annotations

from orger import Mirror
from orger.common import dt_heading, error
Expand All @@ -10,7 +10,7 @@

class PinboardView(Mirror):
def get_items(self) -> Mirror.Results:
items: List[pinboard.Bookmark] = []
items: list[pinboard.Bookmark] = []
for b in pinboard.bookmarks():
if isinstance(b, Exception):
yield error(b)
Expand Down
4 changes: 2 additions & 2 deletions src/orger/modules/zotero.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env python3
from __future__ import annotations

from orger import Mirror
from orger.inorganic import node, link, docview_link, literal
from orger.common import dt_heading, error

from typing import Optional
from textwrap import indent, wrap

from more_itertools import bucket
Expand Down Expand Up @@ -77,7 +77,7 @@ def chit():
properties['ZOTERO_TAGS'] = ', '.join(a.tags) # not sure what's the best separator...

# todo not sure about it...
mtodo: Optional[str] = None
mtodo: str | None = None
if 'todo' in {t.lower() for t in tags}:
mtodo = 'TODO'

Expand Down
24 changes: 13 additions & 11 deletions src/orger/org_view.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import argparse
import inspect
import json
Expand All @@ -6,7 +8,7 @@
from collections import Counter
from pathlib import Path
from subprocess import check_call
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
from typing import Any, Callable, Iterable, Tuple, Union

from .atomic_append import assert_not_edited, atomic_append_check
from .common import orger_user_dir
Expand All @@ -21,20 +23,20 @@
OrgWithKey = Tuple[Key, OrgNode]


_style_map: Dict[str, TimestampStyle] = {
_style_map: dict[str, TimestampStyle] = {
k.lower(): v # type: ignore[misc]
for k, v in TimestampStyle._member_map_.items()
}

class OrgView:
logger_tag: Optional[str] = None
logger_tag: str | None = None
DEFAULT_HEADER: str = '# should be overridden'

# TODO cmdline args shouldn't be none?
def __init__(
self,
cmdline_args: Optional[Namespace]=None,
file_header: Optional[str]=None,
self,
cmdline_args: Namespace | None = None,
file_header: str | None = None,
) -> None:
self.cmdline_args: Namespace = cmdline_args if cmdline_args is not None else Namespace()
tag = self.name() if self.logger_tag is None else self.logger_tag
Expand Down Expand Up @@ -136,7 +138,7 @@ def _run(self, to: Path, *, stdout: bool) -> None:


def make_tree(self) -> OrgNode:
items: List[OrgNode] = []
items: list[OrgNode] = []
for p in self.get_items():
# it's ok to use items without keys in View
if isinstance(p, OrgNode):
Expand All @@ -156,9 +158,9 @@ def make_tree(self) -> OrgNode:
)

@classmethod
def make_test(cls, *, heading: str, contains: Optional[str]=None) -> Callable[[], None]:
def make_test(cls, *, heading: str, contains: str | None = None) -> Callable[[], None]:
from .inorganic import _from_lazy
def pick_heading(root: OrgNode, text: str) -> Optional[OrgNode]:
def pick_heading(root: OrgNode, text: str) -> OrgNode | None:
if text in _from_lazy(root.heading):
return root
for ch in root.children:
Expand Down Expand Up @@ -276,7 +278,7 @@ def main(cls, setup_parser=None) -> None:

def test_org_view_overwrite(tmp_path: Path):
class TestView(StaticView):
def __init__(self, items: List[OrgWithKey], *args, **kwargs) -> None:
def __init__(self, items: list[OrgWithKey], *args, **kwargs) -> None:
super().__init__(*args, file_header='# autogenerated!\n#+TITLE: sometitle\nalso text\n', **kwargs) # type: ignore
self.items = items

Expand Down Expand Up @@ -309,7 +311,7 @@ def get_items(self):

def test_org_view_append(tmp_path: Path) -> None:
class TestView(Queue):
def __init__(self, items: List[OrgWithKey], *args, **kwargs) -> None:
def __init__(self, items: list[OrgWithKey], *args, **kwargs) -> None:
super().__init__(*args, file_header='# autogenerated!', **kwargs) # type: ignore
self.items = items

Expand Down
8 changes: 5 additions & 3 deletions src/orger/state.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from __future__ import annotations

import json
import logging
import os
import sys
import warnings
from pathlib import Path
from typing import Any, Callable, Dict, List, Optional, Union
from typing import Any, Callable, Dict, List, Union

from atomicwrites import atomic_write # type: ignore[import-untyped]

Expand All @@ -20,7 +22,7 @@ def __init__(
path: PathIsh,
*,
dry_run: bool = False,
default: Optional[State] = None,
default: State | None = None,
logger: logging.Logger=logging.getLogger('orger'), # noqa: B008
) -> None:
self.path = Path(path)
Expand All @@ -30,7 +32,7 @@ def __init__(
default = {}
self.default = default

self.state: Optional[State] = None
self.state: State | None = None
self.logger = logger
# TODO for simplicity, write empty if file doesn't exist??

Expand Down

0 comments on commit d5c39cd

Please sign in to comment.