From 075841971b603bbe5774880ee1fa6abf778b84b0 Mon Sep 17 00:00:00 2001 From: Georges Toth Date: Wed, 20 Dec 2023 10:40:53 +0100 Subject: [PATCH] Code formatting / style fixes: - autoformat - update config - remove encoding line; sort imports - comparison to `True` should be `cond is True` or `if cond:` - linter fixes; cleanup __init__.py --- .pre-commit-config.yaml | 6 ++-- CHANGELOG.md | 3 +- caldav/__init__.py | 10 ++---- caldav/davclient.py | 5 ++- caldav/elements/__init__.py | 1 - caldav/elements/base.py | 2 -- caldav/elements/cdav.py | 1 - caldav/elements/dav.py | 2 +- caldav/elements/ical.py | 3 +- caldav/lib/error.py | 1 - caldav/lib/namespace.py | 1 - caldav/lib/url.py | 3 +- caldav/lib/vcal.py | 6 ++-- caldav/objects.py | 61 ++++++++++++++------------------ examples/basic_usage_examples.py | 1 - examples/scheduling_examples.py | 1 + tests/_test_absolute.py | 1 - tests/test_caldav.py | 1 - tests/test_caldav_unit.py | 4 +-- 19 files changed, 45 insertions(+), 68 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db5d5feb..247a0594 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,16 +1,16 @@ --- repos: - repo: https://github.com/asottile/reorder_python_imports - rev: v3.1.0 + rev: v3.12.0 hooks: - id: reorder-python-imports args: ["--application-directories", "src"] - repo: https://github.com/psf/black - rev: 22.6.0 + rev: 23.12.0 hooks: - id: black - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.5.0 hooks: - id: check-byte-order-marker - id: trailing-whitespace diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a38ace7..1e63f3ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,9 @@ This project should more or less adhere to [Semantic Versioning](https://semver. ## [1.4.0] - unreleased -* Georges Toth did a lot of efforts lifting up the project to more modern standards. +* Georges Toth (@sim0nx) did a lot of efforts lifting up the project to more modern standards. * A hook for collecting debug information has been in the pull request for ages. I've decided to include it in 1.4.0. +* Code formatting / style fixes. ### Added diff --git a/caldav/__init__.py b/caldav/__init__.py index 74543994..74116ab7 100644 --- a/caldav/__init__.py +++ b/caldav/__init__.py @@ -1,16 +1,8 @@ #!/usr/bin/env python import logging -import vobject.icalendar - from ._version import __version__ from .davclient import DAVClient -from .objects import * - -## Notes: -## -## * The vobject.icalendar has (or had?) to be explicitly imported due to some bug in the tBaxter fork of vobject. -## * The "import *" looks quite ugly, should be revisited at some point # Silence notification of no default logging handler log = logging.getLogger("caldav") @@ -22,3 +14,5 @@ def emit(self, record) -> None: log.addHandler(NullHandler()) + +__all__ = ["__version__", "DAVClient"] diff --git a/caldav/davclient.py b/caldav/davclient.py index ea305ce9..45d4b682 100644 --- a/caldav/davclient.py +++ b/caldav/davclient.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- import logging import sys import typing @@ -253,7 +252,7 @@ def find_objects_and_props(self) -> typing.Dict[str, typing.Dict[str, _Element]] ## I would like to do this assert here ... # error.assert_(not href in self.objects) ## but then there was https://github.com/python-caldav/caldav/issues/136 - if not href in self.objects: + if href not in self.objects: self.objects[href] = {} ## The properties may be delivered either in one @@ -745,8 +744,8 @@ def request( raise error.AuthorizationError(url=str(url_obj), reason=reason) if error.debug_dump_communication: - from tempfile import NamedTemporaryFile import datetime + from tempfile import NamedTemporaryFile with NamedTemporaryFile(prefix="caldavcomm", delete=False) as commlog: commlog.write(b"=" * 80 + b"\n") diff --git a/caldav/elements/__init__.py b/caldav/elements/__init__.py index ff6ea1ef..4265cc3e 100644 --- a/caldav/elements/__init__.py +++ b/caldav/elements/__init__.py @@ -1,2 +1 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- diff --git a/caldav/elements/base.py b/caldav/elements/base.py index e2b1862c..4c44cebb 100644 --- a/caldav/elements/base.py +++ b/caldav/elements/base.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- import sys import typing from typing import ClassVar @@ -12,7 +11,6 @@ from lxml import etree from lxml.etree import _Element - if sys.version_info < (3, 9): from typing import Iterable else: diff --git a/caldav/elements/cdav.py b/caldav/elements/cdav.py index 1efdd6da..01c100dd 100644 --- a/caldav/elements/cdav.py +++ b/caldav/elements/cdav.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- import logging from datetime import datetime from datetime import timezone diff --git a/caldav/elements/dav.py b/caldav/elements/dav.py index d9e07d4c..fb7d4369 100644 --- a/caldav/elements/dav.py +++ b/caldav/elements/dav.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- from typing import ClassVar from caldav.lib.namespace import ns @@ -27,6 +26,7 @@ class SyncCollection(BaseElement): # Filters + # Conditions class SyncToken(BaseElement): tag: ClassVar[str] = ns("D", "sync-token") diff --git a/caldav/elements/ical.py b/caldav/elements/ical.py index 721e6e2e..1578eafc 100644 --- a/caldav/elements/ical.py +++ b/caldav/elements/ical.py @@ -1,12 +1,11 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- from typing import ClassVar from caldav.lib.namespace import ns -from .base import BaseElement from .base import ValuedBaseElement + # Properties class CalendarColor(ValuedBaseElement): tag: ClassVar[str] = ns("I", "calendar-color") diff --git a/caldav/lib/error.py b/caldav/lib/error.py index e7124566..b475d04a 100644 --- a/caldav/lib/error.py +++ b/caldav/lib/error.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- import logging import typing from collections import defaultdict diff --git a/caldav/lib/namespace.py b/caldav/lib/namespace.py index 3cbd1c43..89ab053a 100644 --- a/caldav/lib/namespace.py +++ b/caldav/lib/namespace.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- import typing from typing import Dict from typing import Optional diff --git a/caldav/lib/url.py b/caldav/lib/url.py index 9dbba958..d21e0d28 100644 --- a/caldav/lib/url.py +++ b/caldav/lib/url.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- import sys import typing import urllib.parse @@ -158,7 +157,7 @@ def canonical(self) -> "URL": ## sensible defaults if not arr[0]: arr[0] = "https" - if arr[1] and not ":" in arr[1]: + if arr[1] and ":" not in arr[1]: if arr[0] == "https": portpart = ":443" elif arr[0] == "http": diff --git a/caldav/lib/vcal.py b/caldav/lib/vcal.py index 492a2e43..5e1500d9 100644 --- a/caldav/lib/vcal.py +++ b/caldav/lib/vcal.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- import datetime import logging import re @@ -23,6 +22,7 @@ ## check if this can be done in vobject or icalendar libraries instead ## of here + ## TODO: would be nice with proper documentation on what systems are ## generating broken data. Compatibility issues should also be collected ## in the documentation. somewhere. @@ -158,7 +158,7 @@ def create_ical(ical_fragment=None, objtype=None, language="en_DK", **props): objtype = "VEVENT" component = icalendar.cal.component_factory[objtype]() component.add("dtstamp", datetime.datetime.now(tz=datetime.timezone.utc)) - if not props.get("uid") and not "\nUID:" in (ical_fragment or ""): + if not props.get("uid") and "\nUID:" not in (ical_fragment or ""): component.add("uid", uuid.uuid1()) my_instance.add_component(component) ## STATUS should default to NEEDS-ACTION for tasks, if it's not set @@ -166,7 +166,7 @@ def create_ical(ical_fragment=None, objtype=None, language="en_DK", **props): ## then find it again - ref https://gitlab.com/davical-project/davical/-/issues/281 if ( not props.get("status") - and not "\nSTATUS:" in (ical_fragment or "") + and "\nSTATUS:" not in (ical_fragment or "") and objtype == "VTODO" ): props["status"] = "NEEDS-ACTION" diff --git a/caldav/objects.py b/caldav/objects.py index 785f1f2b..23ccb775 100644 --- a/caldav/objects.py +++ b/caldav/objects.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- encoding: utf-8 -*- """ A "DAV object" is anything we get from the caldav server or push into the caldav server, notably principal, calendars and calendar events. @@ -42,36 +41,30 @@ class hierarchy into a separate file) from .elements.cdav import CompFilter try: - from typing import ClassVar, Union, Optional + from typing import ClassVar, Optional, Union TimeStamp = Optional[Union[date, datetime]] except: pass -from caldav.lib import error, vcal -from caldav.lib.url import URL -from caldav.elements import dav, cdav - - import logging +from caldav.elements import cdav, dav +from caldav.lib import error, vcal +from caldav.lib.url import URL if typing.TYPE_CHECKING: - from .davclient import DAVClient from icalendar import vCalAddress + from .davclient import DAVClient + if sys.version_info < (3, 9): - from typing import Callable, Container, Iterator, Sequence - from typing import Iterable - from typing_extensions import DefaultDict - from typing_extensions import Literal + from typing import Callable, Container, Iterable, Iterator, Sequence + + from typing_extensions import DefaultDict, Literal else: - from collections.abc import Callable - from collections.abc import Container - from collections.abc import Iterable - from collections.abc import Iterator - from collections.abc import Sequence from collections import defaultdict as DefaultDict + from collections.abc import Callable, Container, Iterable, Iterator, Sequence from typing import Literal if sys.version_info < (3, 11): @@ -254,7 +247,7 @@ def _query( body = to_wire(body) if ( ret.status == 500 - and not b"getetag" in body + and b"getetag" not in body and b"" in body ): body = body.replace( @@ -659,7 +652,7 @@ def calendar_home_set(self): if ( calendar_home_set_url is not None and "@" in calendar_home_set_url - and not "://" in calendar_home_set_url + and "://" not in calendar_home_set_url ): calendar_home_set_url = quote(calendar_home_set_url) self.calendar_home_set = calendar_home_set_url @@ -846,10 +839,10 @@ def save_with_invites(self, ical: str, attendees, **attendeeoptions) -> None: def _use_or_create_ics(self, ical, objtype, **ical_data): if ical_data or ( (isinstance(ical, str) or isinstance(ical, bytes)) - and not b"BEGIN:VCALENDAR" in to_wire(ical) + and b"BEGIN:VCALENDAR" not in to_wire(ical) ): ## TODO: the ical_fragment code is not much tested - if ical and not "ical_fragment" in ical_data: + if ical and "ical_fragment" not in ical_data: ical_data["ical_fragment"] = ical return vcal.create_ical(objtype=objtype, **ical_data) return ical @@ -1203,15 +1196,15 @@ def search( objects = [] match_set = set() for item in matches1 + matches2 + matches3: - if not item.url in match_set: + if item.url not in match_set: match_set.add(item.url) ## and still, Zimbra seems to deliver too many TODOs in the ## matches2 ... let's do some post-filtering in case the ## server fails in filtering things the right way if "STATUS:NEEDS-ACTION" in item.data or ( - not "\nCOMPLETED:" in item.data - and not "\nSTATUS:COMPLETED" in item.data - and not "\nSTATUS:CANCELLED" in item.data + "\nCOMPLETED:" not in item.data + and "\nSTATUS:COMPLETED" not in item.data + and "\nSTATUS:CANCELLED" not in item.data ): objects.append(item) else: @@ -1457,7 +1450,7 @@ def build_search_xml_query( if find_not_defined: match = cdav.NotDefined() elif find_defined: - raise NotImplemented( + raise NotImplementedError( "Seems not to be supported by the CalDAV protocol? or we can negate? not supported yet, in any case" ) else: @@ -2091,7 +2084,7 @@ def get_relatives( if relfilter and not relfilter(rel): continue reltype = rel.params.get("RELTYPE", "PARENT") - if reltypes and not reltype in reltypes: + if reltypes and reltype not in reltypes: continue ret[reltype].add(str(rel)) @@ -2222,7 +2215,7 @@ def add_attendee( ) elif attendee.startswith("mailto:"): attendee_obj = vCalAddress(attendee) - elif "@" in attendee and not ":" in attendee and not ";" in attendee: + elif "@" in attendee and ":" not in attendee and ";" not in attendee: attendee_obj = vCalAddress("mailto:" + attendee) else: error.assert_(False) @@ -2233,14 +2226,14 @@ def add_attendee( if not no_default_parameters: ## Sensible defaults: attendee_obj.params["partstat"] = "NEEDS-ACTION" - if not "cutype" in attendee_obj.params: + if "cutype" not in attendee_obj.params: attendee_obj.params["cutype"] = "UNKNOWN" attendee_obj.params["rsvp"] = "TRUE" attendee_obj.params["role"] = "REQ-PARTICIPANT" params = {} for key in parameters: new_key = key.replace("_", "-") - if parameters[key] == True: + if parameters[key] is True: params[new_key] = "TRUE" else: params[new_key] = parameters[key] @@ -2274,7 +2267,7 @@ def _reply_to_invite_request(self, partstat, calendar) -> None: self.get_property(cdav.ScheduleTag(), use_cached=True) try: calendar.save_event(self.data) - except Exception as some_exception: + except Exception: ## TODO - TODO - TODO ## RFC6638 does not seem to be very clear (or ## perhaps I should read it more thoroughly) neither on @@ -2381,7 +2374,7 @@ def _put(self, retry_on_failure=True): ) if r.status == 302: path = [x[1] for x in r.headers if x[0] == "location"][0] - elif not (r.status in (204, 201)): + elif r.status not in (204, 201): if retry_on_failure: ## This looks like a noop, but the object may be "cleaned". ## See https://github.com/python-caldav/caldav/issues/43 @@ -2899,7 +2892,7 @@ def _complete_recurring_thisandfuture(self, completion_timestamp) -> None: """ recurrences = self.icalendar_instance.subcomponents orig = recurrences[0] - if not "STATUS" in orig: + if "STATUS" not in orig: orig["STATUS"] = "NEEDS-ACTION" if len(recurrences) == 1: @@ -3014,7 +3007,7 @@ def _is_pending(self, i=None) -> Optional[bool]: return True if i.get("STATUS", None) in ("CANCELLED", "COMPLETED"): return False - if not "STATUS" in i: + if "STATUS" not in i: return True ## input data does not conform to the RFC assert False diff --git a/examples/basic_usage_examples.py b/examples/basic_usage_examples.py index 0594ee5a..bf404e5e 100644 --- a/examples/basic_usage_examples.py +++ b/examples/basic_usage_examples.py @@ -36,7 +36,6 @@ def run_examples(): password=password, headers=headers, # Optional parameter to set HTTP headers on each request if needed ) as client: - ## Typically the next step is to fetch a principal object. ## This will cause communication with the server. my_principal = client.principal() diff --git a/examples/scheduling_examples.py b/examples/scheduling_examples.py index 4de46e97..09ca27dd 100644 --- a/examples/scheduling_examples.py +++ b/examples/scheduling_examples.py @@ -20,6 +20,7 @@ except: rfc6638_users = None + ## Some initial setup. We'll need three caldav client objects, with ## corresponding principal objects and calendars. class TestUser: diff --git a/tests/_test_absolute.py b/tests/_test_absolute.py index eb912951..39cb83a1 100644 --- a/tests/_test_absolute.py +++ b/tests/_test_absolute.py @@ -5,7 +5,6 @@ class TestRadicale(object): - SUMMARIES = set( ( "Godspeed You! Black Emperor at " "Cirque Royal / Koninklijk Circus", diff --git a/tests/test_caldav.py b/tests/test_caldav.py index 05eb7f09..f9ce8d7d 100644 --- a/tests/test_caldav.py +++ b/tests/test_caldav.py @@ -1258,7 +1258,6 @@ def testSearchEvent(self): ## category if not self.check_compatibility_flag("radicale_breaks_on_category_search"): - some_events = c.search(comp_class=Event, category="PERSONAL") if not self.check_compatibility_flag("category_search_yields_nothing"): assert len(some_events) == 1 diff --git a/tests/test_caldav_unit.py b/tests/test_caldav_unit.py index 349eb530..4efff154 100644 --- a/tests/test_caldav_unit.py +++ b/tests/test_caldav_unit.py @@ -350,7 +350,7 @@ def testAbsoluteURL(self): "http://cal.example.com/home/bernard/calendars/" ) - @mock.patch("caldav.CalendarObjectResource.is_loaded") + @mock.patch("caldav.objects.CalendarObjectResource.is_loaded") def testDateSearch(self, mocked): """ ## ref https://github.com/python-caldav/caldav/issues/133 @@ -1249,7 +1249,7 @@ def testFilters(self): def test_calendar_comp_class_by_data(self): calendar = Calendar() - for (ical, class_) in ( + for ical, class_ in ( (ev1, Event), (todo, Todo), (journal, Journal),