chore: fix all ruff issues

This commit is contained in:
Gergő Jedlicska
2025-01-19 16:13:21 +01:00
parent d380e6eaf8
commit ffb80457bc
39 changed files with 232 additions and 112 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ import sys
def patch(tag):
print(f"Patching version: {tag}")
with open("pyproject.toml", "r") as f:
with open("pyproject.toml") as f:
lines = f.readlines()
if "version" not in lines[2]:
+4 -2
View File
@@ -96,7 +96,8 @@ class AutomationContext:
def receive_version(self) -> Base:
"""Receive the Speckle project version that triggered this automation run."""
# TODO: this is a quick hack to keep implementation consistency. Move to proper receive many versions
# TODO: this is a quick hack to keep implementation consistency.
# Move to proper receive many versions
version_id = self.automation_run_data.triggers[0].payload.version_id
commit = self.speckle_client.commit.get(
self.automation_run_data.project_id, version_id
@@ -264,7 +265,8 @@ class AutomationContext:
if not path_obj.exists():
raise ValueError("The given file path doesn't exist")
files = {path_obj.name: open(str(path_obj), "rb")}
files = {path_obj.name: path_obj.open("rb")}
url = (
f"{self.automation_run_data.speckle_server_url}api/stream/"
+3 -2
View File
@@ -128,7 +128,8 @@ def execute_automate_function(
automate_function, # type: ignore
)
# if we've gotten this far, the execution should technically be completed as expected
# if we've gotten this far,
# the execution should technically be completed as expected
# thus exiting with 0 is the schemantically correct thing to do
exit_code = (
1 if automation_context.run_status == AutomationStatus.EXCEPTION else 0
@@ -190,4 +191,4 @@ def run_function(
if not automation_context.context_view:
automation_context.set_context_view()
automation_context.report_run_status()
return automation_context
return automation_context
+6 -4
View File
@@ -1,3 +1,5 @@
import contextlib
from deprecated import deprecated
from specklepy.api.credentials import Account
@@ -40,7 +42,8 @@ class SpeckleClient(CoreSpeckleClient):
client = SpeckleClient(host="app.speckle.systems") # or whatever your host is
# client = SpeckleClient(host="localhost:3000", use_ssl=False) or use local server
# authenticate the client with an account (account has been added in Speckle Manager)
# authenticate the client with an account
# (account has been added in Speckle Manager)
account = get_default_account()
client.authenticate_with_account(account)
@@ -74,10 +77,9 @@ class SpeckleClient(CoreSpeckleClient):
)
server_version = None
try:
with contextlib.suppress(Exception):
server_version = self.server.version()
except Exception:
pass
self.other_user = OtherUserResource(
account=self.account,
+5 -1
View File
@@ -53,7 +53,9 @@ def receive(
return _untracked_receive(obj_id, remote_transport, local_transport)
def serialize(base: Base, write_transports: List[AbstractTransport] = []) -> str:
def serialize(
base: Base, write_transports: List[AbstractTransport] | None = None
) -> str:
"""
Serialize a base object. If no write transports are provided,
the object will be serialized
@@ -67,6 +69,8 @@ def serialize(base: Base, write_transports: List[AbstractTransport] = []) -> str
Returns:
str -- the serialized object
"""
if not write_transports:
write_transports = []
metrics.track(metrics.SDK, custom_props={"name": "Serialize"})
return core_serialize(base, write_transports)
@@ -19,8 +19,10 @@ from specklepy.logging.exceptions import SpeckleException
class OtherUserResource(CoreResource):
"""
Provides API access to other users' profiles and activities on the platform.
This class enables fetching limited information about users, searching for users by name or email,
and accessing user activity logs with appropriate privacy and access control measures in place.
This class enables fetching limited information about users,
searching for users by name or email,
and accessing user activity logs with appropriate privacy
and access control measures in place.
"""
def __init__(self, account, basepath, client, server_version) -> None:
@@ -63,7 +65,8 @@ class OtherUserResource(CoreResource):
limit (int): Maximum number of search results to return.
Returns:
Union[List[LimitedUser], SpeckleException]: A list of users matching the search
Union[List[LimitedUser], SpeckleException]:
A list of users matching the search
query or an exception if the query is too short.
"""
if len(search_query) < 3:
@@ -85,8 +88,8 @@ class OtherUserResource(CoreResource):
cursor: Optional[datetime] = None,
) -> ActivityCollection:
"""
Retrieves a collection of activities for a specified user, with optional filters for activity type,
time frame, and pagination.
Retrieves a collection of activities for a specified user,
with optional filters for activity type, time frame, and pagination.
Args:
user_id (str): The ID of the user whose activities are being requested.
@@ -97,7 +100,8 @@ class OtherUserResource(CoreResource):
cursor (Optional[datetime]): Timestamp for pagination cursor.
Returns:
ActivityCollection: A collection of user activities filtered according to specified criteria.
ActivityCollection: A collection of user activities filtered
according to specified criteria.
"""
metrics.track(metrics.SDK, self.account, {"name": "Other User Activity"})
return super().activity(user_id, limit, action_type, before, after, cursor)
@@ -31,7 +31,8 @@ class ServerResource(CoreResource):
the server version in the format (major, minor, patch, (tag, build))
eg (2, 6, 3) for a stable build and (2, 6, 4, 'alpha', 4711) for alpha
"""
# not tracking as it will be called along with other mutations / queries as a check
# not tracking as it will be called along with other
# mutations / queries as a check
return super().version()
def apps(self) -> Dict:
+12 -10
View File
@@ -1,3 +1,4 @@
import contextlib
import re
from typing import Dict
from warnings import warn
@@ -49,7 +50,8 @@ class SpeckleClient:
client = SpeckleClient(host="app.speckle.systems") # or whatever your host is
# client = SpeckleClient(host="localhost:3000", use_ssl=False) or use local server
# authenticate the client with an account (account has been added in Speckle Manager)
# authenticate the client with an account
# (account has been added in Speckle Manager)
account = get_default_account()
client.authenticate_with_account(account)
@@ -102,7 +104,8 @@ class SpeckleClient:
self._init_resources()
# ? Check compatibility with the server - i think we can skip this at this point? save a request
# ? Check compatibility with the server
# - i think we can skip this at this point? save a request
# try:
# server_info = self.server.get()
# if isinstance(server_info, Exception):
@@ -187,9 +190,10 @@ class SpeckleClient:
if ex.exception.code == 403:
warn(
SpeckleWarning(
"Possibly invalid token - could not authenticate Speckle Client"
f" for server {self.url}"
)
"Possibly invalid token - could not authenticate "
f"Speckle Client for server {self.url}"
),
stacklevel=2,
)
else:
raise ex
@@ -203,10 +207,8 @@ class SpeckleClient:
)
server_version = None
try:
with contextlib.suppress(Exception):
server_version = self.server.version()
except Exception:
pass
self.other_user = OtherUserResource(
account=self.account,
@@ -283,7 +285,7 @@ class SpeckleClient:
return attr.Resource(
account=self.account, basepath=self.url, client=self.httpclient
)
except AttributeError:
except AttributeError as ex:
raise SpeckleException(
f"Method {name} is not supported by the SpeckleClient class"
)
) from ex
+2 -1
View File
@@ -55,7 +55,8 @@ class ServerConfiguration(BaseModel):
objectSizeLimitBytes: int
# Keeping this one all Optionals at the minute, because its used both as a deserialization model for GQL and Account Management
# Keeping this one all Optionals at the minute,
# because its used both as a deserialization model for GQL and Account Management
class ServerInfo(BaseModel):
name: Optional[str] = None
company: Optional[str] = None
+4 -1
View File
@@ -4,7 +4,10 @@ from typing import List, Optional
from deprecated import deprecated
from pydantic import BaseModel, Field
FE1_DEPRECATION_REASON = "Stream/Branch/Commit API is now deprecated, Use the new Project/Model/Version API functions in Client}"
FE1_DEPRECATION_REASON = (
"Stream/Branch/Commit API is now deprecated, "
"Use the new Project/Model/Version API functions in Client"
)
FE1_DEPRECATION_VERSION = "2.20"
+5 -2
View File
@@ -70,7 +70,8 @@ def receive(
serializer = BaseObjectSerializer(read_transport=local_transport)
# try local transport first. if the parent is there, we assume all the children are there and continue with deserialization using the local transport
# try local transport first. if the parent is there, we assume all the children
# are there and continue with deserialization using the local transport
obj_string = local_transport.get_object(obj_id)
if obj_string:
return serializer.read_json(obj_string=obj_string)
@@ -90,7 +91,7 @@ def receive(
return serializer.read_json(obj_string=obj_string)
def serialize(base: Base, write_transports: List[AbstractTransport] = []) -> str:
def serialize(base: Base, write_transports: List[AbstractTransport] | None) -> str:
"""
Serialize a base object. If no write transports are provided,
the object will be serialized
@@ -104,6 +105,8 @@ def serialize(base: Base, write_transports: List[AbstractTransport] = []) -> str
Returns:
str -- the serialized object
"""
if not write_transports:
write_transports = []
serializer = BaseObjectSerializer(write_transports=write_transports)
return serializer.write_json(base)[1]
+3 -2
View File
@@ -18,7 +18,7 @@ from specklepy.transports.sqlite import SQLiteTransport
T = TypeVar("T", bound=BaseModel)
class ResourceBase(object):
class ResourceBase:
def __init__(
self,
account: Account,
@@ -101,7 +101,8 @@ class ResourceBase(object):
parse_response: bool = True,
) -> Any:
"""Executes the GraphQL query"""
# This method has quite complex and ambiguous typing, and counter-intuitive error handling
# This method has quite complex and ambiguous typing,
# and counter-intuitive error handling
# We are going to phase it out in favour of `make_request_and_parse_response`
try:
with self.__lock:
@@ -36,10 +36,12 @@ class ActiveUserResource(ResourceBase):
self.schema = User
def get(self) -> Optional[User]:
"""Gets the currently active user profile (as extracted from the authorization header)
"""Gets the currently active user profile
(as extracted from the authorization header)
Returns:
User -- the requested user, or none if no authentication token is provided to the Client
User -- the requested user, or none if no authentication token
is provided to the Client
"""
QUERY = gql(
"""
@@ -75,14 +75,24 @@ class ModelResource(ResourceBase):
) -> ModelWithVersions:
QUERY = gql(
"""
query ModelGetWithVersions($modelId: String!, $projectId: String!, $versionsLimit: Int!, $versionsCursor: String, $versionsFilter: ModelVersionsFilter) {
query ModelGetWithVersions(
$modelId: String!,
$projectId: String!,
$versionsLimit: Int!,
$versionsCursor: String,
$versionsFilter: ModelVersionsFilter
) {
data:project(id: $projectId) {
data:model(id: $modelId) {
id
name
previewUrl
updatedAt
versions(limit: $versionsLimit, cursor: $versionsCursor, filter: $versionsFilter) {
versions(
limit: $versionsLimit,
cursor: $versionsCursor,
filter: $versionsFilter
) {
items {
id
referencedObject
@@ -147,9 +157,18 @@ class ModelResource(ResourceBase):
) -> ResourceCollection[Model]:
QUERY = gql(
"""
query ProjectGetWithModels($projectId: String!, $modelsLimit: Int!, $modelsCursor: String, $modelsFilter: ProjectModelsFilter) {
query ProjectGetWithModels(
$projectId: String!,
$modelsLimit: Int!,
$modelsCursor: String,
$modelsFilter: ProjectModelsFilter
) {
data:project(id: $projectId) {
data:models(limit: $modelsLimit, cursor: $modelsCursor, filter: $modelsFilter) {
data:models(
limit: $modelsLimit,
cursor: $modelsCursor,
filter: $modelsFilter
) {
items {
id
name
@@ -73,7 +73,9 @@ class OtherUserResource(ResourceBase):
archived: bool = False,
emailOnly: bool = False,
) -> UserSearchResultCollection:
"""Searches for a user on the server, by name or email. The search query must be at least
"""
Searches for a user on the server, by name or email.
The search query must be at least
3 characters long
Arguments:
@@ -88,8 +90,20 @@ class OtherUserResource(ResourceBase):
QUERY = gql(
"""
query UserSearch($query: String!, $limit: Int!, $cursor: String, $archived: Boolean, $emailOnly: Boolean) {
data:userSearch(query: $query, limit: $limit, cursor: $cursor, archived: $archived, emailOnly: $emailOnly) {
query UserSearch(
$query: String!,
$limit: Int!,
$cursor: String,
$archived: Boolean,
$emailOnly: Boolean
) {
data:userSearch(
query: $query,
limit: $limit,
cursor: $cursor,
archived: $archived,
emailOnly: $emailOnly
) {
cursor
items {
id
@@ -36,7 +36,10 @@ class ProjectInviteResource(ResourceBase):
) -> ProjectWithTeam:
QUERY = gql(
"""
mutation ProjectInviteCreate($projectId: ID!, $input: ProjectInviteCreateInput!) {
mutation ProjectInviteCreate(
$projectId: ID!,
$input: ProjectInviteCreateInput!
) {
data:projectMutations {
data:invites {
data:create(projectId: $projectId, input: $input) {
@@ -64,7 +64,12 @@ class ProjectResource(ResourceBase):
) -> ProjectWithModels:
QUERY = gql(
"""
query ProjectGetWithModels($projectId: String!, $modelsLimit: Int!, $modelsCursor: String, $modelsFilter: ProjectModelsFilter) {
query ProjectGetWithModels(
$projectId: String!,
$modelsLimit: Int!,
$modelsCursor: String,
$modelsFilter: ProjectModelsFilter
) {
data:project(id: $projectId) {
id
name
@@ -76,7 +81,11 @@ class ProjectResource(ResourceBase):
updatedAt
sourceApps
workspaceId
models(limit: $modelsLimit, cursor: $modelsCursor, filter: $modelsFilter) {
models(
limit: $modelsLimit,
cursor: $modelsCursor,
filter: $modelsFilter
) {
items {
id
name
@@ -79,7 +79,8 @@ class ServerResource(ResourceBase):
the server version in the format (major, minor, patch, (tag, build))
eg (2, 6, 3) for a stable build and (2, 6, 4, 'alpha', 4711) for alpha
"""
# not tracking as it will be called along with other mutations / queries as a check
# not tracking as it will be called along with other mutations / queries
# as a check
query = gql(
"""
query Server {
+16 -5
View File
@@ -159,11 +159,12 @@ class StreamWrapper:
try:
self.branch_name = project["project"]["model"]["name"]
except KeyError as ke:
raise SpeckleException("Project model name is not found", ke)
raise SpeckleException("Project model name is not found", ke) from ke
if not self.stream_id:
raise SpeckleException(
f"Cannot parse {url} into a stream wrapper class - no {key_stream} id found."
f"Cannot parse {url} into a stream wrapper class - no {key_stream} ",
"id found.",
)
@property
@@ -213,7 +214,11 @@ class StreamWrapper:
self._client = SpeckleClient(host=self.host, use_ssl=self.use_ssl)
if self._account.token is None and token is None:
warn(f"No local account found for server {self.host}", SpeckleWarning)
warn(
f"No local account found for server {self.host}",
SpeckleWarning,
stacklevel=2,
)
return self._client
if self._account.token:
@@ -266,14 +271,20 @@ class StreamWrapper:
if use_fe2 is False or (use_fe2 is True and not self.model_id):
base_url = f"{self.server_url}{key_streams}{self.stream_id}"
else: # fe2 is True and model_id available
base_url = f"{self.server_url}{key_streams}{self.stream_id}{key_branches}{value_branch}"
base_url = (
f"{self.server_url}{key_streams}"
f"{self.stream_id}{key_branches}{value_branch}"
)
if wrapper_type == "object":
return f"{base_url}{key_objects}{self.object_id}"
elif wrapper_type == "commit":
return f"{base_url}{key_commits}{self.commit_id}"
elif wrapper_type == "branch":
return f"{self.server_url}{key_streams}{self.stream_id}{key_branches}{value_branch}"
return (
f"{self.server_url}{key_streams}{self.stream_id}"
f"{key_branches}{value_branch}"
)
elif wrapper_type == "stream":
return f"{self.server_url}{key_streams}{self.stream_id}"
else:
@@ -99,7 +99,7 @@ def user_application_data_path() -> Path:
except Exception as ex:
raise SpeckleException(
message="Failed to initialize user application data path.", exception=ex
)
) from ex
def user_speckle_folder_path() -> Path:
+3 -2
View File
@@ -86,7 +86,8 @@ def track(
METRICS_TRACKER.queue.put_nowait(event_params)
except Exception as ex:
# wrapping this whole thing in a try except as we never want a failure here to annoy users!
# wrapping this whole thing in a try except as we never want a failure here
# to annoy users!
LOG.debug(f"Error queueing metrics request: {str(ex)}")
@@ -106,7 +107,7 @@ class Singleton(type):
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
+10 -5
View File
@@ -223,7 +223,7 @@ def _validate_type(t: Optional[type], value: Any) -> Tuple[bool, Any]:
if isinstance(t, ForwardRef):
return True, value
origin = getattr(t, "__origin__")
origin = t.__origin__
# below is what in nicer for >= py38
# origin = get_origin(t)
@@ -288,7 +288,7 @@ def _validate_type(t: Optional[type], value: Any) -> Tuple[bool, Any]:
if len(args) != len(value):
return False, value
values = []
for t_item, v_item in zip(args, value):
for t_item, v_item in zip(args, value, strict=True):
item_valid, item_value = _validate_type(t_item, v_item)
if not item_valid:
return False, value
@@ -371,7 +371,8 @@ class Base(_RegisteringBase, speckle_type="Base"):
if name == "speckle_type":
# not sure if we should raise an exception here??
# raise SpeckleException(
# "Cannot override the `speckle_type`. This is set manually by the class or on deserialisation"
# "Cannot override the `speckle_type`."
# "This is set manually by the class or on deserialisation"
# )
return
# if value is not None:
@@ -399,7 +400,10 @@ class Base(_RegisteringBase, speckle_type="Base"):
try:
cls._attr_types = get_type_hints(cls)
except Exception as e:
warn(f"Could not update forward refs for class {cls.__name__}: {e}")
warn(
f"Could not update forward refs for class {cls.__name__}: {e}",
stacklevel=2,
)
@classmethod
def validate_prop_name(cls, name: str) -> None:
@@ -464,7 +468,8 @@ class Base(_RegisteringBase, speckle_type="Base"):
# @units.setter
# def units(self, value: Union[str, Units, None]):
# """While this property accepts any string value, geometry expects units to be specific strings (see Units enum)"""
# """While this property accepts any string value,
# geometry expects units to be specific strings (see Units enum)"""
# if isinstance(value, str) or value is None:
# self._units = value
# elif isinstance(value, Units):
+4 -1
View File
@@ -23,7 +23,10 @@ class Point(Base, IHasUnits, speckle_type="Objects.Geometry.Point"):
z: float
def __repr__(self) -> str:
return f"{self.__class__.__name__}(x: {self.x}, y: {self.y}, z: {self.z}, units: {self.units})"
return (
f"{self.__class__.__name__}"
f"(x: {self.x}, y: {self.y}, z: {self.z}, units: {self.units})"
)
def to_list(self) -> List[float]:
return [self.x, self.y, self.z]
+2 -2
View File
@@ -67,7 +67,7 @@ class IHasArea(metaclass=ABCMeta):
@area.setter
def area(self, value: float):
if not isinstance(value, (int, float)):
if not isinstance(value, int | float):
raise ValueError(f"Area must be a number, got {type(value)}")
self._area = float(value)
@@ -83,7 +83,7 @@ class IHasVolume(metaclass=ABCMeta):
@volume.setter
def volume(self, value: float):
if not isinstance(value, (int, float)):
if not isinstance(value, int | float):
raise ValueError(f"Volume must be a number, got {type(value)}")
self._volume = float(value)
@@ -12,18 +12,25 @@ class Collection(
detachable={"elements"},
):
"""
A simple container for organising objects within a model and preserving object hierarchy.
A simple container for organising objects within a model
and preserving object hierarchy.
A container is defined by a human-readable name a unique applicationId and its list of contained elements.
The elements can include an unrestricted number of Base objects including additional nested Collections.
A container is defined by a human-readable name a unique applicationId and
its list of contained elements.
The elements can include an unrestricted number of Base objects including
additional nested Collections.
Note:
A Collection can be for example a Layer in Rhino/AutoCad, a collection in Blender, or a Category in Revit.
The location of each collection in the hierarchy of collections in a commit will be retrieved through commit traversal.
A Collection can be for example a Layer in Rhino/AutoCad,
a collection in Blender, or a Category in Revit.
The location of each collection in the hierarchy of collections in a commit
will be retrieved through commit traversal.
Attributes:
name: The human-readable name of the Collection. This name is not necessarily unique within a commit. Set the applicationId for a unique identifier.
elements: The elements contained in this Collection. This may include additional nested Collections
name: The human-readable name of the Collection. This name is not necessarily
unique within a commit. Set the applicationId for a unique identifier.
elements: The elements contained in this Collection.
This may include additional nested Collections
"""
name: str
+1 -1
View File
@@ -1,4 +1,4 @@
from dataclasses import dataclass, field
from dataclasses import dataclass
from typing import List, Optional
from specklepy.objects.base import Base
+1 -1
View File
@@ -148,7 +148,7 @@ cube_mesh = Mesh(
volume=0.0,
)
print(f"\nMesh Details:")
print("\nMesh Details:")
print(f"Number of vertices: {cube_mesh.vertices_count}")
print(f"Number of texture coordinates: {cube_mesh.texture_coordinates_count}")
+13 -6
View File
@@ -19,7 +19,7 @@ from warnings import warn
from stringcase import pascalcase
from specklepy.logging.exceptions import SpeckleException, SpeckleInvalidUnitException
from specklepy.objects.units import Units
from specklepy.objects_v2.units import Units
from specklepy.transports.memory import MemoryTransport
PRIMITIVES = (int, float, str, bool)
@@ -225,7 +225,7 @@ def _validate_type(t: Optional[type], value: Any) -> Tuple[bool, Any]:
if isinstance(t, ForwardRef):
return True, value
origin = getattr(t, "__origin__")
origin = t.__origin__
# below is what in nicer for >= py38
# origin = get_origin(t)
@@ -290,7 +290,7 @@ def _validate_type(t: Optional[type], value: Any) -> Tuple[bool, Any]:
if len(args) != len(value):
return False, value
values = []
for t_item, v_item in zip(args, value):
for t_item, v_item in zip(args, value, strict=True):
item_valid, item_value = _validate_type(t_item, v_item)
if not item_valid:
return False, value
@@ -387,7 +387,8 @@ class Base(_RegisteringBase, speckle_type="Base"):
if name == "speckle_type":
# not sure if we should raise an exception here??
# raise SpeckleException(
# "Cannot override the `speckle_type`. This is set manually by the class or on deserialisation"
# "Cannot override the `speckle_type`."
# "This is set manually by the class or on deserialisation"
# )
return
# if value is not None:
@@ -415,7 +416,10 @@ class Base(_RegisteringBase, speckle_type="Base"):
try:
cls._attr_types = get_type_hints(cls)
except Exception as e:
warn(f"Could not update forward refs for class {cls.__name__}: {e}")
warn(
f"Could not update forward refs for class {cls.__name__}: {e}",
stacklevel=2,
)
@classmethod
def validate_prop_name(cls, name: str) -> None:
@@ -480,7 +484,10 @@ class Base(_RegisteringBase, speckle_type="Base"):
@units.setter
def units(self, value: Union[str, Units, None]):
"""While this property accepts any string value, geometry expects units to be specific strings (see Units enum)"""
"""
While this property accepts any string value,
geometry expects units to be specific strings (see Units enum)
"""
if isinstance(value, str) or value is None:
self._units = value
elif isinstance(value, Units):
+8 -6
View File
@@ -1,10 +1,10 @@
from enum import Enum
from typing import Any, List, Optional
from specklepy.objects.base import Base
from specklepy.objects.encoding import CurveArray, CurveTypeEncoding, ObjectArray
from specklepy.objects.primitive import Interval
from specklepy.objects.units import get_encoding_from_units, get_units_from_encoding
from specklepy.objects_v2.base import Base
from specklepy.objects_v2.encoding import CurveArray, CurveTypeEncoding, ObjectArray
from specklepy.objects_v2.primitive import Interval
from specklepy.objects_v2.units import get_encoding_from_units, get_units_from_encoding
GEOMETRY = "Objects.Geometry."
@@ -918,10 +918,12 @@ class Brep(
self.Vertices = vertices
# TODO: can this be consistent with loops, edges, faces, curves, etc and prepend with the chunk list? needs to happen in sharp first
# TODO: can this be consistent with loops, edges, faces, curves,
# etc and prepend with the chunk list? needs to happen in sharp first
@property
def TrimsValue(self) -> List[float]:
# return None if self.Trims is None else ObjectArray.from_objects(self.Trims).data
# return None if self.Trims is None else
# ObjectArray.from_objects(self.Trims).data
if not self.Trims:
return
value = []
@@ -57,9 +57,7 @@ class CommitObjectBuilder(ABC, Generic[T]):
if parent_id == ROOT:
parent = root_commit_object
else:
parent = (
self.converted[parent_id] if parent_id in self.converted else None
)
parent = self.converted.get(parent_id, None)
if not parent:
continue
@@ -73,13 +71,15 @@ class CommitObjectBuilder(ABC, Generic[T]):
elements.append(current)
return
except Exception as ex:
# A parent was found, but it was invalid (Likely because of a type mismatch on a `elements` property)
# A parent was found, but it was invalid
# (Likely because of a type mismatch on a `elements` property)
print(
f"Failed to add object {type(current)} to a converted parent; {ex}"
)
raise Exception(
f"Could not find a valid parent for object of type {type(current)}. Checked {len(parents)} potential parent, and non were converted!"
f"Could not find a valid parent for object of type {type(current)}."
f"Checked {len(parents)} potential parent, and non were converted!"
)
@@ -57,12 +57,16 @@ class GraphTraversal:
for child_prop in members_to_traverse:
try:
if child_prop in {"speckle_type", "units", "applicationId"}:
continue # debug: to avoid noisy exceptions, explicitly avoid checking ones we know will fail, this is not exhaustive
# debug: to avoid noisy exceptions,
# explicitly avoid checking ones we know will fail,
# this is not exhaustive
continue
if getattr(current, child_prop, None):
value = current[child_prop]
self._traverse_member_to_stack(stack, value, child_prop, head)
except KeyError:
# Unset application ids, and class variables like SpeckleType will throw when __getitem__ is called
# Unset application ids, and class variables like SpeckleType will
# throw when __getitem__ is called
pass
@staticmethod
@@ -118,7 +122,4 @@ class TraversalRule:
return set(self._members_to_traverse(o))
def does_rule_hold(self, o: Base) -> bool:
for condition in self._conditions:
if condition(o):
return True
return False
return any(condition(o) for condition in self._conditions)
@@ -30,6 +30,7 @@ def safe_json_loads(obj: str, obj_id=None) -> Any:
f"Failed to deserialise object (id: {obj_id}). This is likely a ujson big"
f" int error - falling back to json. \nError: {err}",
SpeckleWarning,
stacklevel=2,
)
return json.loads(obj)
@@ -140,7 +141,8 @@ class BaseObjectSerializer:
object_builder[prop] = value
continue
# NOTE: for dynamic props, this won't be re-serialised as an enum but as an int
# NOTE: for dynamic props, this won't be re-serialised
# as an enum but as an int
if isinstance(value, Enum):
object_builder[prop] = value.value
continue
@@ -222,7 +224,7 @@ class BaseObjectSerializer:
if isinstance(obj, Enum):
return obj.value
elif isinstance(obj, (list, tuple, set)):
elif isinstance(obj, list | tuple | set):
if not detach:
return [self.traverse_value(o) for o in obj]
@@ -257,6 +259,7 @@ class BaseObjectSerializer:
f"Failed to handle {type(obj)} in"
" `BaseObjectSerializer.traverse_value`",
SpeckleWarning,
stacklevel=2,
)
return str(obj)
@@ -374,6 +377,7 @@ class BaseObjectSerializer:
f"Could not find the referenced child object of id `{ref_id}`"
f" in the given read transport: {self.read_transport.name}",
SpeckleWarning,
stacklevel=2,
)
base.__setattr__(prop, self.handle_value(value))
@@ -437,6 +441,7 @@ class BaseObjectSerializer:
f"Could not find the referenced child object of id `{ref_id}` in the"
f" given read transport: {self.read_transport.name}",
SpeckleWarning,
stacklevel=2,
)
return obj
+2 -2
View File
@@ -27,8 +27,8 @@ class MemoryTransport(AbstractTransport):
) -> None:
raise NotImplementedError
def get_object(self, id: str) -> str or None:
return self.objects[id] if id in self.objects else None
def get_object(self, id: str) -> str | None:
return self.objects.get(id, None)
def has_objects(self, id_list: List[str]) -> Dict[str, bool]:
return {id: (id in self.objects) for id in id_list}
@@ -11,7 +11,7 @@ from specklepy.logging.exceptions import SpeckleException
LOG = logging.getLogger(__name__)
class BatchSender(object):
class BatchSender:
def __init__(
self,
server_url,
@@ -123,8 +123,14 @@ class BatchSender(object):
upload_data = "[" + ",".join(new_objects) + "]"
upload_data_gzip = gzip.compress(upload_data.encode())
LOG.info(
"Uploading batch of %s objects (%s new): (size: %s, compressed size: %s)"
% (len(batch), len(new_objects), len(upload_data), len(upload_data_gzip))
"Uploading batch of {batch_size} objects {new_object_count}: ",
"(size: {upload_size}, compressed size: {upload_data_size})",
{
"batch_size": len(batch),
"new_object_count": len(new_objects),
"upload_size": len(upload_data),
"upload_data_size": len(upload_data_gzip),
},
)
try:
+2 -1
View File
@@ -74,7 +74,8 @@ class ServerTransport(AbstractTransport):
SpeckleWarning(
"Unauthenticated Speckle Client provided to Server Transport"
f" for {url}. Receiving from private streams will fail."
)
),
stacklevel=2,
)
else:
self.account = client.account
+3 -5
View File
@@ -39,8 +39,7 @@ class SQLiteTransport(AbstractTransport):
f"SQLiteTransport could not initialise {self.scope}.db at"
f" {self._base_path}. Either provide a different `base_path` or use an"
" alternative transport.",
ex,
)
) from ex
def __repr__(self) -> str:
return f"SQLiteTransport(app: '{self.app_name}', scope: '{self.scope}')"
@@ -105,10 +104,9 @@ class SQLiteTransport(AbstractTransport):
raise SpeckleException(
"Could not save the batch of objects to the local db. Inner exception:"
f" {ex}",
ex,
)
) from ex
def get_object(self, id: str) -> str or None:
def get_object(self, id: str) -> str | None:
self.__check_connection()
with closing(self.__connection.cursor()) as c:
row = c.execute(
@@ -44,7 +44,8 @@ class TestActiveUserResource:
def test_active_user_get_projects_with_filter(self, client: SpeckleClient):
# Since the client may be reused for other tests,
# this test does rely on no other test creating a project with "Search for me" in its name
# this test does rely on no other test creating a project
# with "Search for me" in its name
p1 = client.project.create(
ProjectCreateInput(name="Search for me!", description=None, visibility=None)
)
@@ -32,8 +32,8 @@ class TestOtherUser:
assert isinstance(fetched_user, LimitedUser)
assert fetched_user.name == second_user_dict["name"]
# changed in the server, now you cannot get emails of other users
# not checking this, since the first user could or could not be an admin on the server
# admins can get emails of others, regular users can't
# not checking this, since the first user could or could not be an admin
# on the server, admins can get emails of others, regular users can't
# assert fetched_user.email == None
second_user_dict["id"] = fetched_user.id
@@ -35,8 +35,8 @@ class TestUser:
assert isinstance(fetched_user, User)
assert fetched_user.name == second_user_dict["name"]
# changed in the server, now you cannot get emails of other users
# not checking this, since the first user could or could not be an admin on the server
# admins can get emails of others, regular users can't
# not checking this, since the first user could or could not be an admin
# on the server, admins can get emails of others, regular users can't
# assert fetched_user.email == None
second_user_dict["id"] = fetched_user.id