Repository: aws-powertools/powertools-lambda-python

Issue:
`BaseSegment` defines `put_annotation` as having return type `NoReturn`
### Expected Behaviour

The return type should be `None`. `NoReturn` means that the function never returns (e.g. it always throws an exception) and makes type checkers (e.g. mypy) mark all code following `put_annotation` as unreachable.

Also applies to `put_metadata`, `patch`, and `patch_all`.


### Current Behaviour

These methods breaks type checking in any modules they're used because all code following a call to e.g. `put_annotation` is marked as unreachable.

### Code snippet

```python
with Tracer().provider.in_subsegment('test') as subsegment:
    subsegment.put_metadata('x', 1)
    print("hi")  # marked as unreachable
```


### Possible Solution

Change the return type to `None`.

### Steps to Reproduce

Use the code snippet above and run `mypy` on the file.

### AWS Lambda Powertools for Python version

latest

### AWS Lambda function runtime

3.9

### Packaging format used

PyPi

### Debugging logs

_No response_


Discussion:
Thanks a lot for filling this Johan, definitely overlooked it. If you have
the bandwidth to make a PR, we can include it in the next release.

Thank you!

On Mon, 13 Mar 2023 at 12:06, Johan Tibell ***@***.***> wrote:

> Expected Behaviour
>
> The return type should be None. NoReturn means that the function never
> returns (e.g. it always throws an exception) and makes type checkers (e.g.
> mypy) mark all code following put_annotation as unreachable.
>
> Also applies to put_metadata, patch, and patch_all.
> Current Behaviour
>
> These methods breaks type checking in any modules they're used because all
> code following a call to e.g. put_annotation is marked as unreachable.
> Code snippet
>
> with Tracer().provider.in_subsegment('test') as subsegment:
>     subsegment.put_metadata('x', 1)
>     print("hi"). # marked as unreachable
>
> Possible Solution
>
> Change the return type to None.
> Steps to Reproduce
>
> Use the code snippet above and run mypy on the file.
> AWS Lambda Powertools for Python version
>
> latest
> AWS Lambda function runtime
>
> 3.9
> Packaging format used
>
> PyPi
> Debugging logs
>
> *No response*
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/awslabs/aws-lambda-powertools-python/issues/2002>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAZPQBEEDTGLIBZ26P62YT3W335RRANCNFSM6AAAAAAVY5JAIM>
> .
> You are receiving this because you are subscribed to this thread.Message
> ID: ***@***.***>
>


Resolving patch:
diff --git a/aws_lambda_powertools/tracing/base.py b/aws_lambda_powertools/tracing/base.py
--- a/aws_lambda_powertools/tracing/base.py
+++ b/aws_lambda_powertools/tracing/base.py
@@ -2,7 +2,7 @@
 import numbers
 import traceback
 from contextlib import contextmanager
-from typing import Any, Generator, List, NoReturn, Optional, Sequence, Union
+from typing import Any, Generator, List, Optional, Sequence, Union
 
 
 class BaseSegment(abc.ABC):
@@ -28,7 +28,7 @@ def remove_subsegment(self, subsegment: Any):
         """Remove input subsegment from child subsegments."""
 
     @abc.abstractmethod
-    def put_annotation(self, key: str, value: Union[str, numbers.Number, bool]) -> NoReturn:
+    def put_annotation(self, key: str, value: Union[str, numbers.Number, bool]) -> None:
         """Annotate segment or subsegment with a key-value pair.
 
         Note: Annotations will be indexed for later search query.
@@ -42,7 +42,7 @@ def put_annotation(self, key: str, value: Union[str, numbers.Number, bool]) -> N
         """
 
     @abc.abstractmethod
-    def put_metadata(self, key: str, value: Any, namespace: str = "default") -> NoReturn:
+    def put_metadata(self, key: str, value: Any, namespace: str = "default") -> None:
         """Add metadata to segment or subsegment. Metadata is not indexed
         but can be later retrieved by BatchGetTraces API.
 
@@ -101,7 +101,7 @@ def in_subsegment_async(self, name=None, **kwargs) -> Generator[BaseSegment, Non
         """
 
     @abc.abstractmethod
-    def put_annotation(self, key: str, value: Union[str, numbers.Number, bool]) -> NoReturn:
+    def put_annotation(self, key: str, value: Union[str, numbers.Number, bool]) -> None:
         """Annotate current active trace entity with a key-value pair.
 
         Note: Annotations will be indexed for later search query.
@@ -115,7 +115,7 @@ def put_annotation(self, key: str, value: Union[str, numbers.Number, bool]) -> N
         """
 
     @abc.abstractmethod
-    def put_metadata(self, key: str, value: Any, namespace: str = "default") -> NoReturn:
+    def put_metadata(self, key: str, value: Any, namespace: str = "default") -> None:
         """Add metadata to the current active trace entity.
 
         Note: Metadata is not indexed but can be later retrieved by BatchGetTraces API.
@@ -131,7 +131,7 @@ def put_metadata(self, key: str, value: Any, namespace: str = "default") -> NoRe
         """
 
     @abc.abstractmethod
-    def patch(self, modules: Sequence[str]) -> NoReturn:
+    def patch(self, modules: Sequence[str]) -> None:
         """Instrument a set of supported libraries
 
         Parameters
@@ -141,5 +141,5 @@ def patch(self, modules: Sequence[str]) -> NoReturn:
         """
 
     @abc.abstractmethod
-    def patch_all(self) -> NoReturn:
+    def patch_all(self) -> None:
         """Instrument all supported libraries"""


Test patch: