From 8ef845cd8f688c9aba5ed7b96f0951cba4856e12 Mon Sep 17 00:00:00 2001 From: Varad Meru Date: Wed, 1 Jul 2020 12:10:22 -0700 Subject: [PATCH] Minor code smell refactoring, updating pipelines and description added. (#64) --- azure-pipelines.yml | 81 +++++++++++-------- azure/__init__.py | 2 + azure/functions/__init__.py | 2 + azure/functions/_abc.py | 1 + azure/functions/_cosmosdb.py | 1 + azure/functions/_durable_functions.py | 4 +- azure/functions/_eventgrid.py | 1 + azure/functions/_eventhub.py | 5 +- azure/functions/_http.py | 1 + azure/functions/_http_wsgi.py | 1 + azure/functions/_kafka.py | 1 + azure/functions/_queue.py | 1 + azure/functions/_thirdparty/typing_inspect.py | 2 +- azure/functions/_utils.py | 1 + azure/functions/blob.py | 6 +- azure/functions/cosmosdb.py | 6 +- azure/functions/durable_functions.py | 3 +- azure/functions/eventgrid.py | 1 + azure/functions/eventhub.py | 21 ++--- azure/functions/http.py | 1 + azure/functions/kafka.py | 28 ++----- azure/functions/meta.py | 1 + azure/functions/queue.py | 6 +- azure/functions/servicebus.py | 6 +- azure/functions/timer.py | 1 + setup.py | 12 +-- tests/__init__.py | 4 +- tests/test_code_quality.py | 1 + tests/test_cosmosdb.py | 1 + tests/test_durable_functions.py | 1 + tests/test_eventgrid.py | 1 + tests/test_eventhub.py | 1 + tests/test_http.py | 1 + tests/test_http_wsgi.py | 1 + tests/test_kafka.py | 1 + tests/test_meta.py | 1 + tests/test_queue.py | 1 + tests/test_servicebus.py | 1 + 38 files changed, 113 insertions(+), 98 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 957d8eae..aefb4997 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,38 +1,49 @@ trigger: -- master -- dev + - master + - dev + +schedules: + - cron: "0 8 * * 1,3,5" + displayName: Monday, Wednesday and Friday - 1 AM (PDT) build + branches: + include: + - dev + - master + exclude: + - release/* + - releases/ancient/* jobs: -- job: Tests - pool: - vmImage: 'ubuntu-16.04' - strategy: - matrix: - Python36: - pythonVersion: '3.6' - Python37: - pythonVersion: '3.7' - Python38: - pythonVersion: '3.8' - maxParallel: 3 - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(pythonVersion)' - addToPath: true - - task: ShellScript@2 - inputs: - disableAutoCwd: true - scriptPath: .ci/build.sh - displayName: 'Build' - - bash: | - chmod +x .ci/run_tests.sh - .ci/run_tests.sh - displayName: 'Run Tests' - - task: PublishCodeCoverageResults@1 - inputs: - codeCoverageTool: cobertura - summaryFileLocation: coverage.xml - - bash: | - rm coverage.xml - displayName: 'Clearing coverage.xml file' + - job: Tests + pool: + vmImage: 'ubuntu-16.04' + strategy: + matrix: + Python36: + pythonVersion: '3.6' + Python37: + pythonVersion: '3.7' + Python38: + pythonVersion: '3.8' + maxParallel: 3 + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '$(pythonVersion)' + addToPath: true + - task: ShellScript@2 + inputs: + disableAutoCwd: true + scriptPath: .ci/build.sh + displayName: 'Build' + - bash: | + chmod +x .ci/run_tests.sh + .ci/run_tests.sh + displayName: 'Run Tests' + - task: PublishCodeCoverageResults@1 + inputs: + codeCoverageTool: cobertura + summaryFileLocation: coverage.xml + - bash: | + rm coverage.xml + displayName: 'Clearing coverage.xml file' diff --git a/azure/__init__.py b/azure/__init__.py index 163771cd..634f69bc 100644 --- a/azure/__init__.py +++ b/azure/__init__.py @@ -1,5 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from pkgutil import extend_path import typing + __path__: typing.Iterable[str] = extend_path(__path__, __name__) diff --git a/azure/functions/__init__.py b/azure/functions/__init__.py index 46d04429..0b1b3e38 100644 --- a/azure/functions/__init__.py +++ b/azure/functions/__init__.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from ._abc import TimerRequest, InputStream, Context, Out # NoQA from ._eventhub import EventHubEvent # NoQA from ._eventgrid import EventGridEvent, EventGridOutputEvent # NoQA @@ -12,6 +13,7 @@ from ._servicebus import ServiceBusMessage # NoQA from ._durable_functions import OrchestrationContext # NoQA from .meta import get_binding_registry # NoQA + # Import binding implementations to register them from . import blob # NoQA from . import cosmosdb # NoQA diff --git a/azure/functions/_abc.py b/azure/functions/_abc.py index 5b3a9ed5..25672a1e 100644 --- a/azure/functions/_abc.py +++ b/azure/functions/_abc.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import abc import datetime import io diff --git a/azure/functions/_cosmosdb.py b/azure/functions/_cosmosdb.py index f2518716..a4cbedc6 100644 --- a/azure/functions/_cosmosdb.py +++ b/azure/functions/_cosmosdb.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import collections import json diff --git a/azure/functions/_durable_functions.py b/azure/functions/_durable_functions.py index 1deffe4a..7a14e32b 100644 --- a/azure/functions/_durable_functions.py +++ b/azure/functions/_durable_functions.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from typing import Union from . import _abc from importlib import import_module @@ -35,12 +36,11 @@ def _serialize_custom_object(obj): "function") # Encode to json using the object's `to_json` obj_type = type(obj) - dict_obj = { + return { "__class__": obj.__class__.__name__, "__module__": obj.__module__, "__data__": obj_type.to_json(obj) } - return dict_obj def _deserialize_custom_object(obj: dict) -> object: diff --git a/azure/functions/_eventgrid.py b/azure/functions/_eventgrid.py index 45b77cde..9ebc29cc 100644 --- a/azure/functions/_eventgrid.py +++ b/azure/functions/_eventgrid.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import datetime import typing diff --git a/azure/functions/_eventhub.py b/azure/functions/_eventhub.py index 4c200b6c..d3cdfbdf 100644 --- a/azure/functions/_eventhub.py +++ b/azure/functions/_eventhub.py @@ -1,13 +1,14 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import datetime import typing -from azure.functions import _abc as funcabc +from azure.functions import _abc as func_abc from azure.functions import meta -class EventHubEvent(funcabc.EventHubEvent): +class EventHubEvent(func_abc.EventHubEvent): """A concrete implementation of Event Hub message type.""" def __init__(self, *, diff --git a/azure/functions/_http.py b/azure/functions/_http.py index be16dc9a..748efa24 100644 --- a/azure/functions/_http.py +++ b/azure/functions/_http.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import collections.abc import io import json diff --git a/azure/functions/_http_wsgi.py b/azure/functions/_http_wsgi.py index 354ad324..d91672b7 100644 --- a/azure/functions/_http_wsgi.py +++ b/azure/functions/_http_wsgi.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from typing import Callable, Dict, List, Optional, Any from io import BytesIO, StringIO from os import linesep diff --git a/azure/functions/_kafka.py b/azure/functions/_kafka.py index 08378aab..8d3b3ece 100644 --- a/azure/functions/_kafka.py +++ b/azure/functions/_kafka.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import abc import typing diff --git a/azure/functions/_queue.py b/azure/functions/_queue.py index eba1bce7..c6c7d094 100644 --- a/azure/functions/_queue.py +++ b/azure/functions/_queue.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import datetime import json import typing diff --git a/azure/functions/_thirdparty/typing_inspect.py b/azure/functions/_thirdparty/typing_inspect.py index bd70c49a..4cb6d0c3 100644 --- a/azure/functions/_thirdparty/typing_inspect.py +++ b/azure/functions/_thirdparty/typing_inspect.py @@ -301,7 +301,7 @@ def get_args(tp, evaluate=None): get_args(Callable[[], T][int], evaluate=True) == ([], int,) """ if NEW_TYPING: - if evaluate is not None and not evaluate: + if not (evaluate is None or evaluate): raise ValueError('evaluate can only be True in Python 3.7') if isinstance(tp, _GenericAlias): res = tp.__args__ diff --git a/azure/functions/_utils.py b/azure/functions/_utils.py index 40b188b0..723bf4e7 100644 --- a/azure/functions/_utils.py +++ b/azure/functions/_utils.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from typing import List, Tuple, Optional from datetime import datetime diff --git a/azure/functions/blob.py b/azure/functions/blob.py index 30a20891..69c6e410 100644 --- a/azure/functions/blob.py +++ b/azure/functions/blob.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import io from typing import Optional, Union, Any @@ -96,10 +97,7 @@ def decode(cls, data: meta.Datum, *, trigger_metadata) -> Any: trigger_metadata, 'Properties', python_type=dict) if properties: length = properties.get('Length') - if length: - length = int(length) - else: - length = None + length = int(length) if length else None else: length = None diff --git a/azure/functions/cosmosdb.py b/azure/functions/cosmosdb.py index f0ef6ee7..1edc78af 100644 --- a/azure/functions/cosmosdb.py +++ b/azure/functions/cosmosdb.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import collections.abc import json import typing @@ -30,15 +31,12 @@ def decode(cls, data_type = data.type - if data_type == 'string': + if data_type in ['string', 'json']: body = data.value elif data_type == 'bytes': body = data.value.decode('utf-8') - elif data_type == 'json': - body = data.value - else: raise NotImplementedError( f'unsupported queue payload type: {data_type}') diff --git a/azure/functions/durable_functions.py b/azure/functions/durable_functions.py index d7b062ad..7b230135 100644 --- a/azure/functions/durable_functions.py +++ b/azure/functions/durable_functions.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import typing import json @@ -61,7 +62,7 @@ def decode(cls, # Durable functions extension always returns a string of json # See durable functions library's call_activity_task docs - if data_type == 'string' or data_type == 'json': + if data_type in ['string', 'json']: try: callback = _durable_functions._deserialize_custom_object result = json.loads(data.value, object_hook=callback) diff --git a/azure/functions/eventgrid.py b/azure/functions/eventgrid.py index f9e26935..e76f5dde 100644 --- a/azure/functions/eventgrid.py +++ b/azure/functions/eventgrid.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import collections import datetime import json diff --git a/azure/functions/eventhub.py b/azure/functions/eventhub.py index 93c1b64e..0498d60a 100644 --- a/azure/functions/eventhub.py +++ b/azure/functions/eventhub.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import json from typing import Dict, Any, List, Union, Optional, Mapping @@ -33,12 +34,10 @@ def decode( ) -> Union[_eventhub.EventHubEvent, List[_eventhub.EventHubEvent]]: data_type = data.type - if (data_type == 'string' or data_type == 'bytes' - or data_type == 'json'): + if data_type in ['string', 'bytes', 'json']: return cls.decode_single_event(data, trigger_metadata) - elif (data_type == 'collection_bytes' - or data_type == 'collection_string'): + elif data_type in ['collection_bytes', 'collection_string']: return cls.decode_multiple_events(data, trigger_metadata) else: @@ -48,15 +47,12 @@ def decode( @classmethod def decode_single_event(cls, data, trigger_metadata) -> _eventhub.EventHubEvent: - if data.type == 'string': + if data.type in ['string', 'json']: body = data.value.encode('utf-8') elif data.type == 'bytes': body = data.value - elif data.type == 'json': - body = data.value.encode('utf-8') - return _eventhub.EventHubEvent(body=body) @classmethod @@ -70,8 +66,8 @@ def decode_multiple_events( parsed_data = data.value.string events = [] - for i in range(len(parsed_data)): - event = _eventhub.EventHubEvent(body=parsed_data[i]) + for parsed_datum in parsed_data: + event = _eventhub.EventHubEvent(body=parsed_datum) events.append(event) return events @@ -119,15 +115,12 @@ def decode( def decode_single_event( cls, data, trigger_metadata: Mapping[str, meta.Datum] ) -> _eventhub.EventHubEvent: - if data.type == 'string': + if data.type in ['string', 'json']: body = data.value.encode('utf-8') elif data.type == 'bytes': body = data.value - elif data.type == 'json': - body = data.value.encode('utf-8') - return _eventhub.EventHubEvent( body=body, trigger_metadata=trigger_metadata, diff --git a/azure/functions/http.py b/azure/functions/http.py index 25233a94..211711d6 100644 --- a/azure/functions/http.py +++ b/azure/functions/http.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import json import typing diff --git a/azure/functions/kafka.py b/azure/functions/kafka.py index 8c8f871e..adbcf2a9 100644 --- a/azure/functions/kafka.py +++ b/azure/functions/kafka.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import typing import json @@ -90,7 +91,6 @@ def check_input_type_annotation(cls, pytype) -> bool: meta.is_iterable_type_annotation(pytype, valid_types) or (isinstance(pytype, type) and issubclass(pytype, valid_types)) ) - return issubclass(pytype, KafkaEvent) @classmethod def check_output_type_annotation(cls, pytype) -> bool: @@ -106,12 +106,10 @@ def decode( ) -> typing.Union[KafkaEvent, typing.List[KafkaEvent]]: data_type = data.type - if (data_type == 'string' or data_type == 'bytes' - or data_type == 'json'): + if data_type in ['string', 'bytes', 'json']: return cls.decode_single_event(data, trigger_metadata) - elif (data_type == 'collection_bytes' - or data_type == 'collection_string'): + elif data_type in ['collection_bytes', 'collection_string']: return cls.decode_multiple_events(data, trigger_metadata) else: @@ -123,15 +121,12 @@ def decode_single_event(cls, data: meta.Datum, trigger_metadata) -> KafkaEvent: data_type = data.type - if data_type == 'string': + if data_type in ['string', 'json']: body = data.value.encode('utf-8') elif data_type == 'bytes': body = data.value - elif data_type == 'json': - body = data.value.encode('utf-8') - else: raise NotImplementedError( f'unsupported event data payload type: {data_type}') @@ -147,9 +142,7 @@ def decode_multiple_events(cls, data: meta.Datum, elif data.type == 'collection_string': parsed_data = data.value.string - events = [KafkaEvent(body=pd) for pd in parsed_data] - - return events + return [KafkaEvent(body=pd) for pd in parsed_data] @classmethod def encode(cls, obj: typing.Any, *, @@ -168,11 +161,9 @@ def decode( data_type = data.type - if (data_type == 'string' or data_type == 'bytes' - or data_type == 'json'): + if data_type in ['string', 'bytes', 'json']: return cls.decode_single_event(data, trigger_metadata) - elif (data_type == 'collection_bytes' - or data_type == 'collection_string'): + elif data_type in ['collection_bytes', 'collection_string']: return cls.decode_multiple_events(data, trigger_metadata) else: raise NotImplementedError( @@ -183,15 +174,12 @@ def decode_single_event(cls, data: meta.Datum, trigger_metadata) -> KafkaEvent: data_type = data.type - if data_type == 'string': + if data_type in ['string', 'json']: body = data.value.encode('utf-8') elif data_type == 'bytes': body = data.value - elif data_type == 'json': - body = data.value.encode('utf-8') - else: raise NotImplementedError( f'unsupported event data payload type: {data_type}') diff --git a/azure/functions/meta.py b/azure/functions/meta.py index cbf0a2f8..68826051 100644 --- a/azure/functions/meta.py +++ b/azure/functions/meta.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import abc import collections.abc import datetime diff --git a/azure/functions/queue.py b/azure/functions/queue.py index 5eccf250..98286609 100644 --- a/azure/functions/queue.py +++ b/azure/functions/queue.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import collections.abc import datetime import json @@ -65,10 +66,7 @@ def decode(cls, data: meta.Datum, *, trigger_metadata) -> Any: data_type = data.type - if data_type == 'string': - body = data.value - - elif data_type == 'bytes': + if data_type in ['string', 'bytes']: body = data.value else: diff --git a/azure/functions/servicebus.py b/azure/functions/servicebus.py index 1f9fd0c6..17afbc62 100644 --- a/azure/functions/servicebus.py +++ b/azure/functions/servicebus.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import datetime import typing @@ -172,15 +173,12 @@ def decode(cls, data: meta.Datum, *, # See Azure/azure-functions-python-worker#330 body = b'' - elif data.type == 'string': + elif data.type in ['string', 'json']: body = data.value.encode('utf-8') elif data.type == 'bytes': body = data.value - elif data.type == 'json': - body = data.value.encode('utf-8') - else: raise NotImplementedError( f'unsupported queue payload type: {data.type}') diff --git a/azure/functions/timer.py b/azure/functions/timer.py index e7a3da26..69b9898d 100644 --- a/azure/functions/timer.py +++ b/azure/functions/timer.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import json import typing diff --git a/setup.py b/setup.py index b336ac30..07c97711 100644 --- a/setup.py +++ b/setup.py @@ -1,16 +1,18 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + from setuptools import setup from azure.functions import __version__ +with open("README.md") as readme: + long_description = readme.read() setup( name='azure-functions', version=__version__, description='Azure Functions for Python', - long_description='Python support for Azure Functions is based on ' - 'Python3.[6|7|8], serverless hosting on Linux and the ' - 'Functions 2.0 and 3.0 runtime. This module provides the ' - 'rich binding definitions for Azure Functions for Python ' - 'apps.', + long_description=long_description, + long_description_content_type='text/markdown', author='Microsoft Corporation', author_email='azpysdkhelp@microsoft.com', classifiers=[ diff --git a/tests/__init__.py b/tests/__init__.py index b45b30f6..d138d18e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + """Bootstrap for '$ python setup.py test' command.""" import os.path @@ -10,9 +11,8 @@ def suite(): test_loader = unittest.TestLoader() - test_suite = test_loader.discover( + return test_loader.discover( os.path.dirname(__file__), pattern='test_*.py') - return test_suite if __name__ == '__main__': diff --git a/tests/test_code_quality.py b/tests/test_code_quality.py index c0341418..1b97863b 100644 --- a/tests/test_code_quality.py +++ b/tests/test_code_quality.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import pathlib import subprocess import sys diff --git a/tests/test_cosmosdb.py b/tests/test_cosmosdb.py index d5322def..9627308d 100644 --- a/tests/test_cosmosdb.py +++ b/tests/test_cosmosdb.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import unittest import azure.functions as func diff --git a/tests/test_durable_functions.py b/tests/test_durable_functions.py index 50229577..461439c1 100644 --- a/tests/test_durable_functions.py +++ b/tests/test_durable_functions.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import unittest import json diff --git a/tests/test_eventgrid.py b/tests/test_eventgrid.py index f9fce50e..f1a08bda 100644 --- a/tests/test_eventgrid.py +++ b/tests/test_eventgrid.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from datetime import datetime import unittest from typing import List diff --git a/tests/test_eventhub.py b/tests/test_eventhub.py index a203d578..a0c9b25e 100644 --- a/tests/test_eventhub.py +++ b/tests/test_eventhub.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from typing import List import unittest import json diff --git a/tests/test_http.py b/tests/test_http.py index a726c764..4f19c1b4 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import unittest import azure.functions as func diff --git a/tests/test_http_wsgi.py b/tests/test_http_wsgi.py index b1951e5e..3addf518 100644 --- a/tests/test_http_wsgi.py +++ b/tests/test_http_wsgi.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import unittest from io import StringIO, BytesIO diff --git a/tests/test_kafka.py b/tests/test_kafka.py index bc2bbbb7..efd7e9cb 100644 --- a/tests/test_kafka.py +++ b/tests/test_kafka.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from typing import List import unittest import json diff --git a/tests/test_meta.py b/tests/test_meta.py index 8a0fbf5c..32364060 100644 --- a/tests/test_meta.py +++ b/tests/test_meta.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from typing import Mapping, List import unittest import datetime diff --git a/tests/test_queue.py b/tests/test_queue.py index 52c54d01..ab83f923 100644 --- a/tests/test_queue.py +++ b/tests/test_queue.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + import json import unittest diff --git a/tests/test_servicebus.py b/tests/test_servicebus.py index d9b3e3e5..a4ab4d6a 100644 --- a/tests/test_servicebus.py +++ b/tests/test_servicebus.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from typing import Mapping import unittest from datetime import datetime, timezone