diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 0000000..b231667 --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,25 @@ +# Codespell configuration is within pyproject.toml +--- +name: Codespell + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Annotate locations with typos + uses: codespell-project/codespell-problem-matcher@v1 + - name: Codespell + uses: codespell-project/actions-codespell@v2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1d0d688..7b1f6b6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,3 +28,10 @@ repos: entry: pdm run lint-mypy pass_filenames: false language: system + - repo: https://github.com/codespell-project/codespell + # Configuration for codespell is in pyproject.toml + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: + - tomli diff --git a/examples/4_service_to_service/example_client.py b/examples/4_service_to_service/example_client.py index e0e2ec8..685e765 100644 --- a/examples/4_service_to_service/example_client.py +++ b/examples/4_service_to_service/example_client.py @@ -1,6 +1,6 @@ """Client for service to service example. -Kicks off exmaple by sending message to service one, and then +Kicks off example by sending message to service one, and then waits for an event from service one to confirm the messages were passed between the two services properly. """ diff --git a/pyproject.toml b/pyproject.toml index 5532d4d..9ada934 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -197,3 +197,10 @@ exclude_also = [ [build-system] requires = ["pdm-backend"] build-backend = "pdm.backend" + +[tool.codespell] +# Ref: https://github.com/codespell-project/codespell#using-a-config-file +skip = '.git*,*.lock' +check-hidden = true +# ignore-regex = '' +# ignore-words-list = '' diff --git a/src/intersect_sdk/_internal/control_plane/brokers/mqtt_client.py b/src/intersect_sdk/_internal/control_plane/brokers/mqtt_client.py index a6afa71..2ae9dc3 100644 --- a/src/intersect_sdk/_internal/control_plane/brokers/mqtt_client.py +++ b/src/intersect_sdk/_internal/control_plane/brokers/mqtt_client.py @@ -113,7 +113,7 @@ def publish(self, topic: str, payload: bytes, persist: bool) -> None: topic: The topic on which to publish the message as a string. payload: The message to publish, as raw bytes. persist: Determine if the message should live until queue consumers or available (True), or - if it should be removed immediatedly (False) + if it should be removed immediately (False) """ # NOTE: RabbitMQ only works with QOS of 1 and 0, and seems to convert QOS2 to QOS1 self._connection.publish(topic, payload, qos=2 if persist else 0) diff --git a/src/intersect_sdk/_internal/event_metadata.py b/src/intersect_sdk/_internal/event_metadata.py index 53dfd6e..731eaaa 100644 --- a/src/intersect_sdk/_internal/event_metadata.py +++ b/src/intersect_sdk/_internal/event_metadata.py @@ -42,7 +42,7 @@ def definition_metadata_differences( ) -> list[tuple[str, str, str]]: """Return a list of differences between 'definition' and 'metadata'. - First tuple value = defintion key + First tuple value = definition key Second tuple value = second value Third tuple value = already cached value """ diff --git a/src/intersect_sdk/_internal/interfaces.py b/src/intersect_sdk/_internal/interfaces.py index 7cd1fec..1634e7d 100644 --- a/src/intersect_sdk/_internal/interfaces.py +++ b/src/intersect_sdk/_internal/interfaces.py @@ -38,7 +38,7 @@ def create_external_request( response_handler: INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE | None = None, timeout: float = 300.0, ) -> UUID: - """Observed entity (capabilitiy) tells observer (i.e. service) to send an external request. + """Observed entity (capability) tells observer (i.e. service) to send an external request. Params: - request: the request we want to send out, encapsulated as an IntersectDirectMessageParams object diff --git a/src/intersect_sdk/_internal/schema.py b/src/intersect_sdk/_internal/schema.py index fca314d..7cca18b 100644 --- a/src/intersect_sdk/_internal/schema.py +++ b/src/intersect_sdk/_internal/schema.py @@ -557,7 +557,7 @@ def get_schema_and_functions_from_capability_implementations( if cap_status_fn_name and cap_status_schema and cap_status_type_adapter: if status_function_name is not None: # TODO may want to change this later - die('Only one capabilitiy may have an @intersect_status function') + die('Only one capability may have an @intersect_status function') status_function_cap = capability_type status_function_name = cap_status_fn_name status_function_schema = cap_status_schema diff --git a/src/intersect_sdk/config/shared.py b/src/intersect_sdk/config/shared.py index 8ca2fed..a23b348 100644 --- a/src/intersect_sdk/config/shared.py +++ b/src/intersect_sdk/config/shared.py @@ -28,7 +28,7 @@ class HierarchyConfig(BaseModel): - """Configuration for registring this service in a system-of-system architecture.""" + """Configuration for registering this service in a system-of-system architecture.""" service: Annotated[str, Field(pattern=HIERARCHY_REGEX)] """ diff --git a/tests/unit/test_annotations.py b/tests/unit/test_annotations.py index cc98e98..6685203 100644 --- a/tests/unit/test_annotations.py +++ b/tests/unit/test_annotations.py @@ -62,7 +62,7 @@ def some_func(self) -> bool: ... assert len(errors) == 1 assert {'type': 'missing', 'loc': ('event_type',)} in errors - # special case: we have a custom vaildator for event_type which fails on some common instantiations + # special case: we have a custom validator for event_type which fails on some common instantiations with pytest.raises(ValidationError) as ex: class BadEventArgs4(IntersectBaseCapabilityImplementation): diff --git a/tests/unit/test_schema_invalids.py b/tests/unit/test_schema_invalids.py index 392dd92..7d28c33 100644 --- a/tests/unit/test_schema_invalids.py +++ b/tests/unit/test_schema_invalids.py @@ -132,12 +132,12 @@ class PydanticUnparsableInner: three: str @intersect_message() - def cant_parse_annotation(self, unparseable: PydanticUnparsableInner) -> None: ... + def cant_parse_annotation(self, unparsable: PydanticUnparsableInner) -> None: ... with pytest.raises(SystemExit): get_schema_helper([PydanticUnparsable]) assert ( - "On capability 'PydanticUnparsable', parameter 'unparseable' type annotation" in caplog.text + "On capability 'PydanticUnparsable', parameter 'unparsable' type annotation" in caplog.text ) assert "on function 'cant_parse_annotation' is invalid" in caplog.text @@ -158,7 +158,7 @@ def mock_message(self) -> object: ... def test_disallow_object_subtyping(caplog: pytest.LogCaptureFixture): # should fail because return type has a subtyping object (dynamic typing) - # note that 'object' is evalutated exactly like it is as a root type + # note that 'object' is evaluated exactly like it is as a root type class MockObjectSubtype(IntersectBaseCapabilityImplementation): intersect_sdk_capability_name = 'unused' @@ -456,7 +456,7 @@ def mock_message(self, param: Inner) -> None: ... def test_disallow_ambiguous_typealiastype(caplog: pytest.LogCaptureFixture): - # should fail because the TypeVar is ambigous and would resolve to "Any" + # should fail because the TypeVar is ambiguous and would resolve to "Any" class AmbiguousTypeAliasType(IntersectBaseCapabilityImplementation): intersect_sdk_capability_name = 'unused' T = TypeVar('T') @@ -975,4 +975,4 @@ def status_function_2(self) -> str: ... with pytest.raises(SystemExit): get_schema_helper([CapabilityName1, CapabilityName2]) - assert 'Only one capabilitiy may have an @intersect_status function' in caplog.text + assert 'Only one capability may have an @intersect_status function' in caplog.text