Skip to content

Commit

Permalink
Merge pull request #747 from kellerza/typing
Browse files Browse the repository at this point in the history
Improve typing #2
  • Loading branch information
vgrem committed Oct 5, 2023
2 parents ad4afa8 + bc8c237 commit abbdb75
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 73 deletions.
5 changes: 0 additions & 5 deletions .flake8

This file was deleted.

15 changes: 0 additions & 15 deletions .pylintrc

This file was deleted.

2 changes: 1 addition & 1 deletion office365/directory/applications/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def remove_certificate(self, thumbprint):
Remove a certificate from an application.
:param str thumbprint: The unique identifier for the password.
"""
raise NotImplemented("")
raise NotImplementedError("")

def add_password(self, display_name):
"""Adds a strong password to an application.
Expand Down
27 changes: 20 additions & 7 deletions office365/entity.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
from typing import TYPE_CHECKING, Optional, TypeVar

from typing_extensions import Self

from office365.runtime.client_object import ClientObject
from office365.runtime.paths.entity import EntityPath
from office365.runtime.paths.resource_path import ResourcePath
from office365.runtime.queries.delete_entity import DeleteEntityQuery
from office365.runtime.queries.update_entity import UpdateEntityQuery

if TYPE_CHECKING:
from office365.graph_client import GraphClient


T = TypeVar("T")


class Entity(ClientObject):
class Entity(ClientObject[T]):
"""Base entity"""

def update(self):
# type: () -> Self
"""Updates the entity."""
qry = UpdateEntityQuery(self)
self.context.add_query(qry)
return self

def delete_object(self):
# type: () -> Self
"""Deletes the entity."""
qry = DeleteEntityQuery(self)
self.context.add_query(qry)
Expand All @@ -23,30 +35,31 @@ def delete_object(self):

@property
def context(self):
"""
:rtype: office365.graph_client.GraphClient
"""
# type: () -> GraphClient
"""Return the Graph Client context."""
return self._context

@property
def entity_type_name(self):
# type: () -> str
if self._entity_type_name is None:
name = type(self).__name__
self._entity_type_name = "microsoft.graph." + name[0].lower() + name[1:]
return self._entity_type_name

@property
def id(self):
"""The unique identifier of the entity.
:rtype: str or None
"""
# type: () -> Optional[str]
"""The unique identifier of the entity."""
return self.properties.get("id", None)

@property
def property_ref_name(self):
# type: () -> str
return "id"

def set_property(self, name, value, persist_changes=True):
# type: (str, T, bool) -> Self
super(Entity, self).set_property(name, value, persist_changes)
if name == self.property_ref_name:
if self._resource_path is None:
Expand Down
6 changes: 4 additions & 2 deletions office365/entity_collection.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from typing import TypeVar
from typing import TYPE_CHECKING, TypeVar, Any

from office365.graph_client import GraphClient
from office365.runtime.client_object_collection import ClientObjectCollection
from office365.runtime.compat import is_string_type
from office365.runtime.paths.item import ItemPath
from office365.runtime.paths.resource_path import ResourcePath
from office365.runtime.queries.create_entity import CreateEntityQuery

if TYPE_CHECKING:
from office365.graph_client import GraphClient

T = TypeVar("T")


Expand Down
3 changes: 2 additions & 1 deletion office365/graph_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from office365.runtime.auth.token_response import TokenResponse
from office365.runtime.client_runtime_context import ClientRuntimeContext
from office365.runtime.http.http_method import HttpMethod
from office365.runtime.http.request_options import RequestOptions
from office365.runtime.odata.request import ODataRequest
from office365.runtime.odata.v4.batch_request import ODataV4BatchRequest
from office365.runtime.odata.v4.json_format import V4JsonFormat
Expand All @@ -68,7 +69,7 @@ class GraphClient(ClientRuntimeContext):
"""Graph Service client"""

def __init__(self, acquire_token_callback):
# type: (Callable[None, dict]) -> None
# type: (Callable[..., dict]) -> None
"""
:param () -> dict acquire_token_callback: Acquire token function
"""
Expand Down
5 changes: 3 additions & 2 deletions office365/onedrive/driveitems/driveItem.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class DriveItem(BaseItem):
OneDrive and SharePoint are returned as driveItem resources"""

def get_by_path(self, url_path):
# type: (str) -> DriveItem
"""
Retrieve DriveItem by server relative path
Expand Down Expand Up @@ -236,8 +237,8 @@ def upload_file(self, path_or_file):

def get_content(self, format_name=None):
"""
Download the contents of the primary stream (file) of a DriveItem. O
nly driveItems with the file property can be downloaded.
Download the contents of the primary stream (file) of a DriveItem.
Only driveItems with the file property can be downloaded.
:type format_name: str or None
"""
Expand Down
65 changes: 30 additions & 35 deletions office365/runtime/client_object.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
from __future__ import annotations

import datetime
from typing import TypeVar
from typing import TYPE_CHECKING, Generic, Optional, TypeVar

from typing_extensions import Self

from office365.runtime.client_runtime_context import ClientRuntimeContext
from office365.runtime.client_value import ClientValue
from office365.runtime.odata.json_format import ODataJsonFormat
from office365.runtime.odata.query_options import QueryOptions
from office365.runtime.odata.type import ODataType
from office365.runtime.odata.v3.json_light_format import JsonLightFormat
from office365.runtime.paths.resource_path import ResourcePath

if TYPE_CHECKING:
from office365.runtime.client_object_collection import ClientObjectCollection

T = TypeVar("T", bound="ClientObject")

T = TypeVar("T")
P_T = TypeVar("P_T")
"""Property Type."""


class ClientObject(object):
class ClientObject(Generic[T]):
def __init__(self, context, resource_path=None, parent_collection=None):
"""
Base client object which define named properties and relationships of an entity
:type parent_collection: office365.runtime.client_object_collection.ClientObjectCollection or None
:type resource_path: office365.runtime.paths.resource_path.ResourcePath or None
:type context: office365.runtime.client_runtime_context.ClientRuntimeContext
"""
# type: (ClientRuntimeContext, Optional[ResourcePath], Optional[ClientObjectCollection]) -> None
"""Base client object which define named properties and relationships of an entity."""
self._properties = {}
self._ser_property_names = []
self._query_options = QueryOptions()
Expand All @@ -29,9 +35,8 @@ def __init__(self, context, resource_path=None, parent_collection=None):
self._resource_path = resource_path

def clear(self):
"""
Resets client object's state
"""
# type: () -> Self
"""Resets client object's state."""
self._properties = {
k: v
for k, v in self._properties.items()
Expand All @@ -42,11 +47,8 @@ def clear(self):
return self

def execute_query(self):
"""
Submit request(s) to the server
:type self: T
"""
# type: () -> Self
"""Submit request(s) to the server."""
self.context.execute_query()
return self

Expand Down Expand Up @@ -79,14 +81,13 @@ def after_execute(self, action, *args, **kwargs):
return self

def get(self):
"""
Retrieves a client object from the server
:type self: T
"""
# type: () -> Self
"""Retrieves a client object from the server."""
self.context.load(self)
return self

def is_property_available(self, name):
# type: (str) -> bool
"""Returns a Boolean value that indicates whether the specified property has been retrieved or set.
:param str name: A property name
Expand All @@ -96,16 +97,13 @@ def is_property_available(self, name):
return False

def expand(self, names):
"""
Specifies the related resources to be included in line with retrieved resources
:type self: T
:type names: list[str]
"""
# type: (list[str]) -> Self
"""Specifies the related resources to be included in line with retrieved resources."""
self.query_options.expand = names
return self

def select(self, names):
# type: (list[str]) -> Self
"""
Allows to request a limited set of properties
Expand All @@ -122,6 +120,7 @@ def remove_from_parent_collection(self):
return self

def _persist_changes(self, name):
# type: (str) -> Self
"""
Marks a property as a serializable
:param str name: A property name
Expand All @@ -131,19 +130,15 @@ def _persist_changes(self, name):
return self

def get_property(self, name, default_value=None):
"""
Gets property value
:type name: str
:type default_value: P_T
:rtype: P_T
"""
# type: (str, P_T) -> P_T
"""Gets property value."""
if default_value is None:
normalized_name = name[0].lower() + name[1:]
default_value = getattr(self, normalized_name, None)
return self._properties.get(name, default_value)

def set_property(self, name, value, persist_changes=True):
# type: (str, P_T, bool) -> Self
"""Sets property value
:param str name: Property name
Expand Down
2 changes: 1 addition & 1 deletion office365/runtime/client_object_collection.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Generic, Iterator, Optional, TypeVar
from typing import Generic, Iterator, List, Optional, TypeVar

from typing_extensions import Self

Expand Down
5 changes: 3 additions & 2 deletions office365/runtime/client_runtime_context.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import abc
from time import sleep
from typing import TypeVar
from typing import TYPE_CHECKING

from office365.runtime.client_request_exception import ClientRequestException
from office365.runtime.client_result import ClientResult
Expand All @@ -9,7 +9,8 @@
from office365.runtime.queries.client_query import ClientQuery
from office365.runtime.queries.read_entity import ReadEntityQuery

T = TypeVar("T", bound="ClientObject")
if TYPE_CHECKING:
from office365.runtime.client_object import T


class ClientRuntimeContext(object):
Expand Down
2 changes: 1 addition & 1 deletion office365/sharepoint/excel/excel_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ def pending_request(self):
pass

def get_workbook(self, list_name, file_name):
raise NotImplemented("get_workbook")
raise NotImplementedError("get_workbook")
24 changes: 23 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@ description-file = README.md
profile=black

[flake8]
# These error codes can be fixed, but since it touches many files the
# suggestion is to do it one code at a time to reduce review effort
# F401 - imported but unused
extend-ignore = E203, E501, W503, F401
# F841 - local variable defined but never used
extend-ignore = E203, E501, W503, F401, F841
max-line-length = 88
exclude =
generator/metadata
office365/runtime/compat.py

[pylint]
max-line-length=120
# all codes: http://pylint-messages.wikidot.com/all-codes
disable=
C0103,
C0303,
C0111,
C0415, # import-outside-toplevel
C0112, # empty-docstring
C0209, # consider-using f-string
C0114, # missing-module-docstring
R1725, # super-with-arguments

[pylint.FORMAT]
max-line-length = 121

0 comments on commit abbdb75

Please sign in to comment.