From 23d81f5cb23a546eea7e6daffbeb7ad941ceaea9 Mon Sep 17 00:00:00 2001 From: Mike A Date: Tue, 2 Jan 2024 21:05:44 +0100 Subject: [PATCH] Decide on conflicting ruff rules --- findmy/account.py | 21 ++++++++++++++------- findmy/anisette.py | 3 ++- findmy/base.py | 39 ++++++++++++++++++++++++++------------- findmy/http.py | 6 ++++-- findmy/keys.py | 6 ++++-- findmy/reports.py | 6 ++++-- pyproject.toml | 3 +++ 7 files changed, 57 insertions(+), 27 deletions(-) diff --git a/findmy/account.py b/findmy/account.py index 43215bc..234f304 100644 --- a/findmy/account.py +++ b/findmy/account.py @@ -53,7 +53,8 @@ class LoginError(Exception): class InvalidStateError(RuntimeError): - """Raised when a method is used that is in conflict with the internal account state. + """ + Raised when a method is used that is in conflict with the internal account state. For example: calling `BaseAppleAccount.login` while already logged in. """ @@ -133,7 +134,8 @@ class AsyncSmsSecondFactor(BaseSecondFactorMethod): number_id: int, phone_number: str, ) -> None: - """Initialize the second factor method. + """ + Initialize the second factor method. Should not be done manually; use `BaseAppleAccount.get_2fa_methods` instead. """ @@ -149,7 +151,8 @@ class AsyncSmsSecondFactor(BaseSecondFactorMethod): @property def phone_number(self) -> str: - """The 2FA method's phone number. + """ + The 2FA method's phone number. May be masked using unicode characters; should only be used for identification purposes. """ @@ -165,7 +168,8 @@ class AsyncSmsSecondFactor(BaseSecondFactorMethod): class SmsSecondFactor(BaseSecondFactorMethod): - """A sync implementation of `BaseSecondFactorMethod`. + """ + A sync implementation of `BaseSecondFactorMethod`. Uses `AsyncSmsSecondFactor` internally. """ @@ -210,7 +214,8 @@ class AsyncAppleAccount(BaseAppleAccount): user_id: str | None = None, device_id: str | None = None, ) -> None: - """Initialize the apple account. + """ + Initialize the apple account. :param anisette: An instance of `AsyncAnisetteProvider`. :param user_id: An optional user ID to use. Will be auto-generated if missing. @@ -313,7 +318,8 @@ class AsyncAppleAccount(BaseAppleAccount): raise ExportRestoreError(msg) from None async def close(self) -> None: - """Close any sessions or other resources in use by this object. + """ + Close any sessions or other resources in use by this object. Should be called when the object will no longer be used. """ @@ -620,7 +626,8 @@ class AsyncAppleAccount(BaseAppleAccount): class AppleAccount(BaseAppleAccount): - """A sync implementation of `BaseappleAccount`. + """ + A sync implementation of `BaseappleAccount`. Uses `AsyncappleAccount` internally. """ diff --git a/findmy/anisette.py b/findmy/anisette.py index 6fe172d..c1c3f14 100644 --- a/findmy/anisette.py +++ b/findmy/anisette.py @@ -48,7 +48,8 @@ class BaseAnisetteProvider(ABC): device_id: str, serial: str = "0", ) -> dict[str, str]: - """Retrieve a complete dictionary of Anisette headers. + """ + Retrieve a complete dictionary of Anisette headers. Consider using `BaseAppleAccount.get_anisette_headers` instead. """ diff --git a/findmy/base.py b/findmy/base.py index 50224d4..1071692 100644 --- a/findmy/base.py +++ b/findmy/base.py @@ -21,7 +21,8 @@ class LoginState(Enum): LOGGED_IN = 3 def __lt__(self, other: LoginState) -> bool: - """Compare against another `LoginState`. + """ + Compare against another `LoginState`. A `LoginState` is said to be "less than" another `LoginState` iff it is in an "earlier" stage of the login process, going from LOGGED_OUT to LOGGED_IN. @@ -53,7 +54,8 @@ class BaseSecondFactorMethod(ABC): @abstractmethod def request(self) -> None: - """Put in a request for the second-factor challenge. + """ + Put in a request for the second-factor challenge. Exact meaning is up to the implementing class. """ @@ -77,7 +79,8 @@ class BaseAppleAccount(ABC): @property @abstractmethod def account_name(self) -> str: - """The name of the account as reported by Apple. + """ + The name of the account as reported by Apple. This is usually an e-mail address. May be None in some cases, such as when not logged in. @@ -87,7 +90,8 @@ class BaseAppleAccount(ABC): @property @abstractmethod def first_name(self) -> str | None: - """First name of the account holder as reported by Apple. + """ + First name of the account holder as reported by Apple. May be None in some cases, such as when not logged in. """ @@ -96,7 +100,8 @@ class BaseAppleAccount(ABC): @property @abstractmethod def last_name(self) -> str | None: - """Last name of the account holder as reported by Apple. + """ + Last name of the account holder as reported by Apple. May be None in some cases, such as when not logged in. """ @@ -104,7 +109,8 @@ class BaseAppleAccount(ABC): @abstractmethod def export(self) -> dict: - """Export a representation of the current state of the account as a dictionary. + """ + Export a representation of the current state of the account as a dictionary. The output of this method is guaranteed to be JSON-serializable, and passing the return value of this function as an argument to `BaseAppleAccount.restore` @@ -116,7 +122,8 @@ class BaseAppleAccount(ABC): @abstractmethod def restore(self, data: dict) -> None: - """Restore a previous export of the internal state of the account. + """ + Restore a previous export of the internal state of the account. See `BaseAppleAccount.export` for more information. """ @@ -129,7 +136,8 @@ class BaseAppleAccount(ABC): @abstractmethod def get_2fa_methods(self) -> list[BaseSecondFactorMethod]: - """Get a list of 2FA methods that can be used as a secondary challenge. + """ + Get a list of 2FA methods that can be used as a secondary challenge. Currently, only SMS-based 2FA methods are supported. """ @@ -137,7 +145,8 @@ class BaseAppleAccount(ABC): @abstractmethod def sms_2fa_request(self, phone_number_id: int) -> None: - """Request a 2FA code to be sent to a specific phone number ID. + """ + Request a 2FA code to be sent to a specific phone number ID. Consider using `BaseSecondFactorMethod.request` instead. """ @@ -145,7 +154,8 @@ class BaseAppleAccount(ABC): @abstractmethod def sms_2fa_submit(self, phone_number_id: int, code: str) -> LoginState: - """Submit a 2FA code that was sent to a specific phone number ID. + """ + Submit a 2FA code that was sent to a specific phone number ID. Consider using `BaseSecondFactorMethod.submit` instead. """ @@ -158,7 +168,8 @@ class BaseAppleAccount(ABC): date_from: datetime, date_to: datetime, ) -> dict[KeyPair, list[KeyReport]]: - """Fetch location reports for a sequence of `KeyPair`s between `date_from` and `date_end`. + """ + Fetch location reports for a sequence of `KeyPair`s between `date_from` and `date_end`. Returns a dictionary mapping `KeyPair`s to a list of their location reports. """ @@ -170,7 +181,8 @@ class BaseAppleAccount(ABC): keys: Sequence[KeyPair], hours: int = 7 * 24, ) -> dict[KeyPair, list[KeyReport]]: - """Fetch location reports for a sequence of `KeyPair`s for the last `hours` hours. + """ + Fetch location reports for a sequence of `KeyPair`s for the last `hours` hours. Utility method as an alternative to using `BaseAppleAccount.fetch_reports` directly. """ @@ -178,7 +190,8 @@ class BaseAppleAccount(ABC): @abstractmethod def get_anisette_headers(self, serial: str = "0") -> dict[str, str]: - """Retrieve a complete dictionary of Anisette headers. + """ + Retrieve a complete dictionary of Anisette headers. Utility method for `AnisetteProvider.get_headers` using this account's user and device ID. """ diff --git a/findmy/http.py b/findmy/http.py index 06d274e..11913d9 100644 --- a/findmy/http.py +++ b/findmy/http.py @@ -83,7 +83,8 @@ class HttpSession: self._session = None def __del__(self) -> None: - """Attempt to gracefully close the session. + """ + Attempt to gracefully close the session. Ideally this should be done by manually calling close(). """ @@ -103,7 +104,8 @@ class HttpSession: auth: tuple[str] | None = None, **kwargs: P.kwargs, ) -> HttpResponse: - """Make an HTTP request. + """ + Make an HTTP request. Keyword arguments will directly be passed to `aiohttp.ClientSession.request`. """ diff --git a/findmy/keys.py b/findmy/keys.py index d489122..f806b68 100644 --- a/findmy/keys.py +++ b/findmy/keys.py @@ -27,7 +27,8 @@ class KeyPair: @classmethod def from_b64(cls, key_b64: str) -> "KeyPair": - """Import an existing `KeyPair` from its base64-encoded representation. + """ + Import an existing `KeyPair` from its base64-encoded representation. Same format as returned by `KeyPair.private_key_b64`. """ @@ -41,7 +42,8 @@ class KeyPair: @property def private_key_b64(self) -> str: - """Return the private key as a base64-encoded string. + """ + Return the private key as a base64-encoded string. Can be re-imported using `KeyPair.from_b64`. """ diff --git a/findmy/reports.py b/findmy/reports.py index 6996683..ebd30cf 100644 --- a/findmy/reports.py +++ b/findmy/reports.py @@ -120,7 +120,8 @@ class KeyReport: description: str, payload: bytes, ) -> KeyReport: - """Create a `KeyReport` from fields and a payload as reported by Apple. + """ + Create a `KeyReport` from fields and a payload as reported by Apple. Requires a `KeyPair` to decrypt the report's payload. """ @@ -145,7 +146,8 @@ class KeyReport: ) def __lt__(self, other: KeyReport) -> bool: - """Compare against another `KeyReport`. + """ + Compare against another `KeyReport`. A `KeyReport` is said to be "less than" another `KeyReport` iff its recorded timestamp is strictly less than the other report. diff --git a/pyproject.toml b/pyproject.toml index 918551a..260f972 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,9 @@ ignore = [ "ANN101", # annotations on `self` "ANN102", # annotations on `cls` "FIX002", # resolving TODOs + + "D203", # one blank line before class docstring + "D212", # multi-line docstring start at first line ] line-length = 100