diff --git a/docs/conf.py b/docs/conf.py index c4fee51f31a..d719ebe9311 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,38 +12,39 @@ import os import sys -sys.path.insert(0, os.path.abspath('../opentelemetry-api/src/')) + +sys.path.insert(0, os.path.abspath("../opentelemetry-api/src/")) # -- Project information ----------------------------------------------------- -project = 'OpenTelemetry' -copyright = '2019, OpenTelemetry Authors' -author = 'OpenTelemetry Authors' +project = "OpenTelemetry" +copyright = "2019, OpenTelemetry Authors" +author = "OpenTelemetry Authors" # -- General configuration --------------------------------------------------- # Easy automatic cross-references for `code in backticks` -default_role = 'any' +default_role = "any" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ # API doc generation - 'sphinx.ext.autodoc', + "sphinx.ext.autodoc", # Support for google-style docstrings - 'sphinx.ext.napoleon', + "sphinx.ext.napoleon", # Infer types from hints instead of docstrings - 'sphinx_autodoc_typehints', + "sphinx_autodoc_typehints", # Add links to source from generated docs - 'sphinx.ext.viewcode', + "sphinx.ext.viewcode", # Link to other sphinx docs - 'sphinx.ext.intersphinx', + "sphinx.ext.intersphinx", ] -intersphinx_mapping = {'python': ('https://docs.python.org/3/', None)} +intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)} # http://www.sphinx-doc.org/en/master/config.html#confval-nitpicky # Sphinx will warn about all references where the target cannot be found. @@ -51,18 +52,18 @@ nitpick_ignore = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] autodoc_default_options = { - 'members': True, - 'undoc-members': True, - 'show-inheritance': True, - 'member-order': 'bysource' + "members": True, + "undoc-members": True, + "show-inheritance": True, + "member-order": "bysource", } # -- Options for HTML output ------------------------------------------------- @@ -70,7 +71,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/ext/opentelemetry-ext-wsgi/setup.py b/ext/opentelemetry-ext-wsgi/setup.py index f2496022614..0634f8c3bdb 100644 --- a/ext/opentelemetry-ext-wsgi/setup.py +++ b/ext/opentelemetry-ext-wsgi/setup.py @@ -16,12 +16,7 @@ BASE_DIR = os.path.dirname(__file__) VERSION_FILENAME = os.path.join( - BASE_DIR, - "src", - "opentelemetry", - "ext", - "wsgi", - "version.py", + BASE_DIR, "src", "opentelemetry", "ext", "wsgi", "version.py" ) PACKAGE_INFO = {} with open(VERSION_FILENAME) as f: diff --git a/ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py b/ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py index 29d57567a0e..974a6998a87 100644 --- a/ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py +++ b/ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py @@ -35,11 +35,7 @@ class OpenTelemetryMiddleware: wsgi: The WSGI application callable. """ - def __init__( - self, - wsgi, - propagators=None, - ): + def __init__(self, wsgi, propagators=None): self.wsgi = wsgi # TODO: implement context propagation @@ -54,9 +50,9 @@ def _add_request_attributes(span, environ): span.set_attribute("http.host", host) url = ( - environ.get("REQUEST_URI") or - environ.get("RAW_URI") or - wsgiref_util.request_uri(environ, include_query=False) + environ.get("REQUEST_URI") + or environ.get("RAW_URI") + or wsgiref_util.request_uri(environ, include_query=False) ) span.set_attribute("http.url", url) @@ -101,5 +97,5 @@ def __call__(self, environ, start_response): for yielded in iterable: yield yielded finally: - if hasattr(iterable, 'close'): + if hasattr(iterable, "close"): iterable.close() diff --git a/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py b/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py index 0e86a871f45..b423224ade0 100644 --- a/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py +++ b/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py @@ -48,6 +48,7 @@ def iter_wsgi(environ, start_response): assert isinstance(environ, dict) start_response("200 OK", [("Content-Type", "text/plain")]) return response + return iter_wsgi @@ -66,10 +67,9 @@ class TestWsgiApplication(unittest.TestCase): def setUp(self): tracer = trace_api.tracer() self.span_context_manager = mock.MagicMock() - self.span_context_manager.__enter__.return_value = \ - mock.create_autospec( - trace_api.Span, spec_set=True - ) + self.span_context_manager.__enter__.return_value = mock.create_autospec( + trace_api.Span, spec_set=True + ) self.patcher = mock.patch.object( tracer, "start_span", @@ -115,8 +115,7 @@ def validate_response(self, response, error=None): self.assertEqual(self.status, "200 OK") self.assertEqual( - self.response_headers, - [("Content-Type", "text/plain")] + self.response_headers, [("Content-Type", "text/plain")] ) if error: self.assertIs(self.exc_info[0], error) @@ -159,8 +158,7 @@ def setUp(self): def test_request_attributes(self): OpenTelemetryMiddleware._add_request_attributes( # noqa pylint: disable=protected-access - self.span, - self.environ, + self.span, self.environ ) expected = ( mock.call("component", "http"), @@ -173,7 +171,7 @@ def test_request_attributes(self): def test_response_attributes(self): OpenTelemetryMiddleware._add_response_attributes( # noqa pylint: disable=protected-access - self.span, "404 Not Found", + self.span, "404 Not Found" ) expected = ( mock.call("http.status_code", 404), @@ -184,12 +182,11 @@ def test_response_attributes(self): def test_response_attributes_invalid_status_code(self): OpenTelemetryMiddleware._add_response_attributes( # noqa pylint: disable=protected-access - self.span, "Invalid Status Code", + self.span, "Invalid Status Code" ) self.assertEqual(self.span.set_attribute.call_count, 1) self.span.set_attribute.assert_called_with( - "http.status_text", - "Status Code", + "http.status_text", "Status Code" ) diff --git a/opentelemetry-api/setup.py b/opentelemetry-api/setup.py index 3e2aa720558..d9e900465a0 100644 --- a/opentelemetry-api/setup.py +++ b/opentelemetry-api/setup.py @@ -41,15 +41,16 @@ description="OpenTelemetry Python API", include_package_data=True, long_description=open("README.rst").read(), - install_requires=[ - "typing; python_version<'3.5'", - ], + install_requires=["typing; python_version<'3.5'"], extras_require={}, license="Apache-2.0", package_dir={"": "src"}, - packages=setuptools.find_namespace_packages(where="src", - include="opentelemetry.*"), - url=("https://github.com/open-telemetry/opentelemetry-python" - "/tree/master/opentelemetry-api"), + packages=setuptools.find_namespace_packages( + where="src", include="opentelemetry.*" + ), + url=( + "https://github.com/open-telemetry/opentelemetry-python" + "/tree/master/opentelemetry-api" + ), zip_safe=False, ) diff --git a/opentelemetry-api/src/opentelemetry/context/__init__.py b/opentelemetry-api/src/opentelemetry/context/__init__.py index 1495f8828e3..f6650429684 100644 --- a/opentelemetry-api/src/opentelemetry/context/__init__.py +++ b/opentelemetry-api/src/opentelemetry/context/__init__.py @@ -142,7 +142,7 @@ async def main(): from .base_context import BaseRuntimeContext -__all__ = ['Context'] +__all__ = ["Context"] Context = ( # pylint: disable=invalid-name @@ -151,7 +151,9 @@ async def main(): try: from .async_context import AsyncRuntimeContext + Context = AsyncRuntimeContext() # pylint:disable=invalid-name except ImportError: from .thread_local_context import ThreadLocalRuntimeContext + Context = ThreadLocalRuntimeContext() # pylint:disable=invalid-name diff --git a/opentelemetry-api/src/opentelemetry/context/async_context.py b/opentelemetry-api/src/opentelemetry/context/async_context.py index 559d36234be..803e242257f 100644 --- a/opentelemetry-api/src/opentelemetry/context/async_context.py +++ b/opentelemetry-api/src/opentelemetry/context/async_context.py @@ -20,7 +20,7 @@ class AsyncRuntimeContext(base_context.BaseRuntimeContext): class Slot(base_context.BaseRuntimeContext.Slot): - def __init__(self, name: str, default: 'object'): + def __init__(self, name: str, default: "object"): # pylint: disable=super-init-not-called self.name = name self.contextvar = ContextVar(name) # type: ContextVar[object] @@ -31,7 +31,7 @@ def __init__(self, name: str, default: 'object'): def clear(self) -> None: self.contextvar.set(self.default()) - def get(self) -> 'object': + def get(self) -> "object": try: return self.contextvar.get() except LookupError: @@ -39,5 +39,5 @@ def get(self) -> 'object': self.set(value) return value - def set(self, value: 'object') -> None: + def set(self, value: "object") -> None: self.contextvar.set(value) diff --git a/opentelemetry-api/src/opentelemetry/context/base_context.py b/opentelemetry-api/src/opentelemetry/context/base_context.py index 5c1ffb4a8e4..f1e37aa91f4 100644 --- a/opentelemetry-api/src/opentelemetry/context/base_context.py +++ b/opentelemetry-api/src/opentelemetry/context/base_context.py @@ -16,7 +16,7 @@ import typing -def wrap_callable(target: 'object') -> typing.Callable[[], object]: +def wrap_callable(target: "object") -> typing.Callable[[], object]: if callable(target): return target return lambda: target @@ -24,16 +24,16 @@ def wrap_callable(target: 'object') -> typing.Callable[[], object]: class BaseRuntimeContext: class Slot: - def __init__(self, name: str, default: 'object'): + def __init__(self, name: str, default: "object"): raise NotImplementedError def clear(self) -> None: raise NotImplementedError - def get(self) -> 'object': + def get(self) -> "object": raise NotImplementedError - def set(self, value: 'object') -> None: + def set(self, value: "object") -> None: raise NotImplementedError _lock = threading.Lock() @@ -49,10 +49,8 @@ def clear(cls) -> None: @classmethod def register_slot( - cls, - name: str, - default: 'object' = None, - ) -> 'BaseRuntimeContext.Slot': + cls, name: str, default: "object" = None + ) -> "BaseRuntimeContext.Slot": """Register a context slot with an optional default value. :type name: str @@ -68,52 +66,50 @@ def register_slot( cls._slots[name] = cls.Slot(name, default) return cls._slots[name] - def apply(self, snapshot: typing.Dict[str, 'object']) -> None: + def apply(self, snapshot: typing.Dict[str, "object"]) -> None: """Set the current context from a given snapshot dictionary""" for name in snapshot: setattr(self, name, snapshot[name]) - def snapshot(self) -> typing.Dict[str, 'object']: + def snapshot(self) -> typing.Dict[str, "object"]: """Return a dictionary of current slots by reference.""" keys = self._slots.keys() return dict((n, self._slots[n].get()) for n in keys) def __repr__(self) -> str: - return '{}({})'.format(type(self).__name__, self.snapshot()) + return "{}({})".format(type(self).__name__, self.snapshot()) - def __getattr__(self, name: str) -> 'object': + def __getattr__(self, name: str) -> "object": if name not in self._slots: self.register_slot(name, None) slot = self._slots[name] return slot.get() - def __setattr__(self, name: str, value: 'object') -> None: + def __setattr__(self, name: str, value: "object") -> None: if name not in self._slots: self.register_slot(name, None) slot = self._slots[name] slot.set(value) - def __getitem__(self, name: str) -> 'object': + def __getitem__(self, name: str) -> "object": return self.__getattr__(name) - def __setitem__(self, name: str, value: 'object') -> None: + def __setitem__(self, name: str, value: "object") -> None: self.__setattr__(name, value) def with_current_context( - self, - func: typing.Callable[..., 'object'], - ) -> typing.Callable[..., 'object']: + self, func: typing.Callable[..., "object"] + ) -> typing.Callable[..., "object"]: """Capture the current context and apply it to the provided func. """ caller_context = self.snapshot() def call_with_current_context( - *args: 'object', - **kwargs: 'object' - ) -> 'object': + *args: "object", **kwargs: "object" + ) -> "object": try: backup_context = self.snapshot() self.apply(caller_context) diff --git a/opentelemetry-api/src/opentelemetry/context/propagation/binaryformat.py b/opentelemetry-api/src/opentelemetry/context/propagation/binaryformat.py index f05ef699721..7f1a65882f3 100644 --- a/opentelemetry-api/src/opentelemetry/context/propagation/binaryformat.py +++ b/opentelemetry-api/src/opentelemetry/context/propagation/binaryformat.py @@ -24,6 +24,7 @@ class BinaryFormat(abc.ABC): This class provides an interface that enables converting span contexts to and from a binary format. """ + @staticmethod @abc.abstractmethod def to_bytes(context: SpanContext) -> bytes: @@ -39,6 +40,7 @@ def to_bytes(context: SpanContext) -> bytes: A bytes representation of the SpanContext. """ + @staticmethod @abc.abstractmethod def from_bytes(byte_representation: bytes) -> typing.Optional[SpanContext]: diff --git a/opentelemetry-api/src/opentelemetry/context/propagation/httptextformat.py b/opentelemetry-api/src/opentelemetry/context/propagation/httptextformat.py index 860498fe35d..f3823a86d17 100644 --- a/opentelemetry-api/src/opentelemetry/context/propagation/httptextformat.py +++ b/opentelemetry-api/src/opentelemetry/context/propagation/httptextformat.py @@ -67,9 +67,11 @@ def example_route(): .. _Propagation API Specification: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-propagators.md """ + @abc.abstractmethod - def extract(self, get_from_carrier: Getter, - carrier: object) -> SpanContext: + def extract( + self, get_from_carrier: Getter, carrier: object + ) -> SpanContext: """Create a SpanContext from values in the carrier. The extract function should retrieve values from the carrier @@ -88,9 +90,11 @@ def extract(self, get_from_carrier: Getter, A SpanContext with configuration found in the carrier. """ + @abc.abstractmethod - def inject(self, context: SpanContext, set_in_carrier: Setter, - carrier: object) -> None: + def inject( + self, context: SpanContext, set_in_carrier: Setter, carrier: object + ) -> None: """Inject values from a SpanContext into a carrier. inject enables the propagation of values into HTTP clients or diff --git a/opentelemetry-api/src/opentelemetry/context/thread_local_context.py b/opentelemetry-api/src/opentelemetry/context/thread_local_context.py index 8313fb57e89..b60914f846c 100644 --- a/opentelemetry-api/src/opentelemetry/context/thread_local_context.py +++ b/opentelemetry-api/src/opentelemetry/context/thread_local_context.py @@ -22,7 +22,7 @@ class ThreadLocalRuntimeContext(base_context.BaseRuntimeContext): class Slot(base_context.BaseRuntimeContext.Slot): _thread_local = threading.local() - def __init__(self, name: str, default: 'object'): + def __init__(self, name: str, default: "object"): # pylint: disable=super-init-not-called self.name = name self.default = base_context.wrap_callable( @@ -32,7 +32,7 @@ def __init__(self, name: str, default: 'object'): def clear(self) -> None: setattr(self._thread_local, self.name, self.default()) - def get(self) -> 'object': + def get(self) -> "object": try: got = getattr(self._thread_local, self.name) # type: object return got @@ -41,5 +41,5 @@ def get(self) -> 'object': self.set(value) return value - def set(self, value: 'object') -> None: + def set(self, value: "object") -> None: setattr(self._thread_local, self.name, value) diff --git a/opentelemetry-api/src/opentelemetry/loader.py b/opentelemetry-api/src/opentelemetry/loader.py index 78b7cc4f321..b23dafe2f0c 100644 --- a/opentelemetry-api/src/opentelemetry/loader.py +++ b/opentelemetry-api/src/opentelemetry/loader.py @@ -69,7 +69,7 @@ def my_factory_for_t(api_type: typing.Type[T]) -> typing.Optional[T]: import os import sys -_T = TypeVar('_T') +_T = TypeVar("_T") # "Untrusted" because this is usually user-provided and we don't trust the user # to really return a _T: by using object, mypy forces us to check/cast @@ -87,7 +87,8 @@ def my_factory_for_t(api_type: typing.Type[T]) -> typing.Optional[T]: def _try_load_impl_from_modname( - implementation_modname: str, api_type: Type[_T]) -> Optional[_T]: + implementation_modname: str, api_type: Type[_T] +) -> Optional[_T]: try: implementation_mod = importlib.import_module(implementation_modname) except (ImportError, SyntaxError): @@ -98,15 +99,15 @@ def _try_load_impl_from_modname( def _try_load_impl_from_mod( - implementation_mod: object, api_type: Type[_T]) -> Optional[_T]: + implementation_mod: object, api_type: Type[_T] +) -> Optional[_T]: try: # Note: We use such a long name to avoid calling a function that is not # intended for this API. implementation_fn = getattr( - implementation_mod, - 'get_opentelemetry_implementation' + implementation_mod, "get_opentelemetry_implementation" ) # type: _UntrustedImplFactory[_T] except AttributeError: # TODO Log/warn @@ -116,9 +117,8 @@ def _try_load_impl_from_mod( def _try_load_impl_from_callback( - implementation_fn: _UntrustedImplFactory[_T], - api_type: Type[_T] - ) -> Optional[_T]: + implementation_fn: _UntrustedImplFactory[_T], api_type: Type[_T] +) -> Optional[_T]: result = implementation_fn(api_type) if result is None: return None @@ -133,8 +133,8 @@ def _try_load_impl_from_callback( def _try_load_configured_impl( - api_type: Type[_T], factory: Optional[_UntrustedImplFactory[_T]] - ) -> Optional[_T]: + api_type: Type[_T], factory: Optional[_UntrustedImplFactory[_T]] +) -> Optional[_T]: """Attempts to find any specially configured implementation. If none is configured, or a load error occurs, returns `None` """ @@ -142,11 +142,13 @@ def _try_load_configured_impl( if sys.flags.ignore_environment: return None implementation_modname = os.getenv( - 'OPENTELEMETRY_PYTHON_IMPLEMENTATION_' + api_type.__name__.upper()) + "OPENTELEMETRY_PYTHON_IMPLEMENTATION_" + api_type.__name__.upper() + ) if implementation_modname: return _try_load_impl_from_modname(implementation_modname, api_type) implementation_modname = os.getenv( - 'OPENTELEMETRY_PYTHON_IMPLEMENTATION_DEFAULT') + "OPENTELEMETRY_PYTHON_IMPLEMENTATION_DEFAULT" + ) if implementation_modname: return _try_load_impl_from_modname(implementation_modname, api_type) if factory is not None: @@ -157,8 +159,9 @@ def _try_load_configured_impl( # Public to other opentelemetry-api modules -def _load_impl(api_type: Type[_T], - factory: Optional[Callable[[Type[_T]], Optional[_T]]]) -> _T: +def _load_impl( + api_type: Type[_T], factory: Optional[Callable[[Type[_T]], Optional[_T]]] +) -> _T: """Tries to load a configured implementation, if unsuccessful, returns a fast no-op implemenation that is always available. """ @@ -170,7 +173,8 @@ def _load_impl(api_type: Type[_T], def set_preferred_default_implementation( - implementation_factory: _UntrustedImplFactory[_T]) -> None: + implementation_factory: _UntrustedImplFactory[_T] +) -> None: """Sets a factory function that may be called for any implementation object. See the :ref:`module docs ` for more details.""" global _DEFAULT_FACTORY # pylint:disable=global-statement diff --git a/opentelemetry-api/src/opentelemetry/resources/__init__.py b/opentelemetry-api/src/opentelemetry/resources/__init__.py index 0d1e34dddbb..d6a6eb64a29 100644 --- a/opentelemetry-api/src/opentelemetry/resources/__init__.py +++ b/opentelemetry-api/src/opentelemetry/resources/__init__.py @@ -18,6 +18,7 @@ class Resource(abc.ABC): """The interface that resources must implement.""" + @staticmethod @abc.abstractmethod def create(labels: typing.Dict[str, str]) -> "Resource": @@ -30,6 +31,7 @@ def create(labels: typing.Dict[str, str]) -> "Resource": The resource with the labels in question """ + @property @abc.abstractmethod def labels(self) -> typing.Dict[str, str]: @@ -39,6 +41,7 @@ def labels(self) -> typing.Dict[str, str]: A dictionary with the labels of the resource """ + @abc.abstractmethod def merge(self, other: typing.Optional["Resource"]) -> "Resource": """Return a resource with the union of labels for both resources. diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 0ff3039bcd6..b947e77f667 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -68,7 +68,7 @@ from opentelemetry import types # TODO: quarantine -ParentSpan = typing.Optional[typing.Union['Span', 'SpanContext']] +ParentSpan = typing.Optional[typing.Union["Span", "SpanContext"]] class Span: @@ -93,7 +93,7 @@ def end(self) -> None: implementations are free to ignore or raise on further calls. """ - def get_context(self) -> 'SpanContext': + def get_context(self) -> "SpanContext": """Gets the span's SpanContext. Get an immutable, serializable identifier for this span that can be @@ -103,29 +103,28 @@ def get_context(self) -> 'SpanContext': A :class:`.SpanContext` with a copy of this span's immutable state. """ - def set_attribute(self: 'Span', - key: str, - value: types.AttributeValue, - ) -> None: + def set_attribute( + self: "Span", key: str, value: types.AttributeValue + ) -> None: """Sets an Attribute. Sets a single Attribute with the key and value passed as arguments. """ - def add_event(self: 'Span', - name: str, - attributes: types.Attributes = None, - ) -> None: + def add_event( + self: "Span", name: str, attributes: types.Attributes = None + ) -> None: """Adds an Event. Adds a single Event with the name and, optionally, attributes passed as arguments. """ - def add_link(self: 'Span', - link_target_context: 'SpanContext', - attributes: types.Attributes = None, - ) -> None: + def add_link( + self: "Span", + link_target_context: "SpanContext", + attributes: types.Attributes = None, + ) -> None: """Adds a Link to another span. Adds a single Link from this Span to another Span identified by the @@ -144,11 +143,12 @@ class TraceOptions(int): .. _W3C Trace Context - Traceparent: https://www.w3.org/TR/trace-context/#trace-flags """ + DEFAULT = 0x00 RECORDED = 0x01 @classmethod - def get_default(cls) -> 'TraceOptions': + def get_default(cls) -> "TraceOptions": return cls(cls.DEFAULT) @@ -167,7 +167,7 @@ class TraceState(typing.Dict[str, str]): """ @classmethod - def get_default(cls) -> 'TraceState': + def get_default(cls) -> "TraceState": return cls() @@ -175,11 +175,11 @@ def get_default(cls) -> 'TraceState': def format_trace_id(trace_id: int) -> str: - return '0x{:032x}'.format(trace_id) + return "0x{:032x}".format(trace_id) def format_span_id(span_id: int) -> str: - return '0x{:016x}'.format(span_id) + return "0x{:016x}".format(span_id) class SpanContext: @@ -195,12 +195,13 @@ class SpanContext: state: Tracing-system-specific info to propagate. """ - def __init__(self, - trace_id: int, - span_id: int, - trace_options: 'TraceOptions' = None, - trace_state: 'TraceState' = None - ) -> None: + def __init__( + self, + trace_id: int, + span_id: int, + trace_options: "TraceOptions" = None, + trace_state: "TraceState" = None, + ) -> None: if trace_options is None: trace_options = DEFAULT_TRACE_OPTIONS if trace_state is None: @@ -211,12 +212,11 @@ def __init__(self, self.trace_state = trace_state def __repr__(self) -> str: - return ("{}(trace_id={}, span_id={})" - .format( - type(self).__name__, - format_trace_id(self.trace_id), - format_span_id(self.span_id) - )) + return "{}(trace_id={}, span_id={})".format( + type(self).__name__, + format_trace_id(self.trace_id), + format_span_id(self.span_id), + ) def is_valid(self) -> bool: """Get whether this `SpanContext` is valid. @@ -227,8 +227,10 @@ def is_valid(self) -> bool: Returns: True if the `SpanContext` is valid, false otherwise. """ - return (self.trace_id != INVALID_TRACE_ID and - self.span_id != INVALID_SPAN_ID) + return ( + self.trace_id != INVALID_TRACE_ID + and self.span_id != INVALID_SPAN_ID + ) class DefaultSpan(Span): @@ -236,17 +238,22 @@ class DefaultSpan(Span): All operations are no-op except context propagation. """ - def __init__(self, context: 'SpanContext') -> None: + + def __init__(self, context: "SpanContext") -> None: self._context = context - def get_context(self) -> 'SpanContext': + def get_context(self) -> "SpanContext": return self._context INVALID_SPAN_ID = 0x0000000000000000 INVALID_TRACE_ID = 0x00000000000000000000000000000000 -INVALID_SPAN_CONTEXT = SpanContext(INVALID_TRACE_ID, INVALID_SPAN_ID, - DEFAULT_TRACE_OPTIONS, DEFAULT_TRACE_STATE) +INVALID_SPAN_CONTEXT = SpanContext( + INVALID_TRACE_ID, + INVALID_SPAN_ID, + DEFAULT_TRACE_OPTIONS, + DEFAULT_TRACE_STATE, +) INVALID_SPAN = DefaultSpan(INVALID_SPAN_CONTEXT) @@ -261,7 +268,7 @@ class Tracer: # This is the default behavior when creating spans. CURRENT_SPAN = Span() - def get_current_span(self) -> 'Span': + def get_current_span(self) -> "Span": """Gets the currently active span from the context. If there is no current span, return a placeholder span with an invalid @@ -275,10 +282,9 @@ def get_current_span(self) -> 'Span': return INVALID_SPAN @contextmanager # type: ignore - def start_span(self, - name: str, - parent: ParentSpan = CURRENT_SPAN - ) -> typing.Iterator['Span']: + def start_span( + self, name: str, parent: ParentSpan = CURRENT_SPAN + ) -> typing.Iterator["Span"]: """Context manager for span creation. Create a new span. Start the span and set it as the current span in @@ -324,10 +330,9 @@ def start_span(self, # pylint: disable=unused-argument,no-self-use yield INVALID_SPAN - def create_span(self, - name: str, - parent: ParentSpan = CURRENT_SPAN - ) -> 'Span': + def create_span( + self, name: str, parent: ParentSpan = CURRENT_SPAN + ) -> "Span": """Creates a span. Creating the span does not start it, and should not affect the tracer's @@ -362,7 +367,7 @@ def create_span(self, return INVALID_SPAN @contextmanager # type: ignore - def use_span(self, span: 'Span') -> typing.Iterator[None]: + def use_span(self, span: "Span") -> typing.Iterator[None]: """Context manager for controlling a span's lifetime. Start the given span and set it as the current span in this tracer's @@ -405,7 +410,7 @@ def tracer() -> Tracer: def set_preferred_tracer_implementation( - factory: ImplementationFactory + factory: ImplementationFactory ) -> None: """Set the factory to be used to create the tracer. diff --git a/opentelemetry-api/tests/test_loader.py b/opentelemetry-api/tests/test_loader.py index 68809468f5d..9123154b41d 100644 --- a/opentelemetry-api/tests/test_loader.py +++ b/opentelemetry-api/tests/test_loader.py @@ -36,8 +36,8 @@ def get_opentelemetry_implementation(type_): # pylint:disable=redefined-outer-name,protected-access,unidiomatic-typecheck -class TestLoader(unittest.TestCase): +class TestLoader(unittest.TestCase): def setUp(self): reload(loader) reload(trace) @@ -52,7 +52,8 @@ def test_get_default(self): def test_preferred_impl(self): trace.set_preferred_tracer_implementation( - get_opentelemetry_implementation) + get_opentelemetry_implementation + ) tracer = trace.tracer() self.assertIs(tracer, DUMMY_TRACER) @@ -68,15 +69,17 @@ def test_preferred_impl_with_tracer(self): def test_preferred_impl_with_default(self): self.do_test_preferred_impl( - loader.set_preferred_default_implementation) + loader.set_preferred_default_implementation + ) def test_try_set_again(self): self.assertTrue(trace.tracer()) # Try setting after the tracer has already been created: with self.assertRaises(RuntimeError) as einfo: trace.set_preferred_tracer_implementation( - get_opentelemetry_implementation) - self.assertIn('already loaded', str(einfo.exception)) + get_opentelemetry_implementation + ) + self.assertIn("already loaded", str(einfo.exception)) def do_test_get_envvar(self, envvar_suffix): global DUMMY_TRACER # pylint:disable=global-statement @@ -84,7 +87,7 @@ def do_test_get_envvar(self, envvar_suffix): # Test is not runnable with this! self.assertFalse(sys.flags.ignore_environment) - envname = 'OPENTELEMETRY_PYTHON_IMPLEMENTATION_' + envvar_suffix + envname = "OPENTELEMETRY_PYTHON_IMPLEMENTATION_" + envvar_suffix os.environ[envname] = __name__ try: tracer = trace.tracer() @@ -95,7 +98,7 @@ def do_test_get_envvar(self, envvar_suffix): self.assertIs(type(tracer), DummyTracer) def test_get_envvar_tracer(self): - return self.do_test_get_envvar('TRACER') + return self.do_test_get_envvar("TRACER") def test_get_envvar_default(self): - return self.do_test_get_envvar('DEFAULT') + return self.do_test_get_envvar("DEFAULT") diff --git a/opentelemetry-api/tests/trace/test_defaultspan.py b/opentelemetry-api/tests/trace/test_defaultspan.py index b3155d32615..a20b55cc4e6 100644 --- a/opentelemetry-api/tests/trace/test_defaultspan.py +++ b/opentelemetry-api/tests/trace/test_defaultspan.py @@ -19,9 +19,9 @@ class TestDefaultSpan(unittest.TestCase): def test_ctor(self): - context = trace.SpanContext(1, 1, - trace.DEFAULT_TRACE_OPTIONS, - trace.DEFAULT_TRACE_STATE) + context = trace.SpanContext( + 1, 1, trace.DEFAULT_TRACE_OPTIONS, trace.DEFAULT_TRACE_STATE + ) span = trace.DefaultSpan(context) self.assertEqual(context, span.get_context()) diff --git a/opentelemetry-sdk/setup.py b/opentelemetry-sdk/setup.py index 790dc92893d..fabf97cb391 100644 --- a/opentelemetry-sdk/setup.py +++ b/opentelemetry-sdk/setup.py @@ -17,8 +17,9 @@ import setuptools BASE_DIR = os.path.dirname(__file__) -VERSION_FILENAME = os.path.join(BASE_DIR, "src", "opentelemetry", "sdk", - "version.py") +VERSION_FILENAME = os.path.join( + BASE_DIR, "src", "opentelemetry", "sdk", "version.py" +) PACKAGE_INFO = {} with open(VERSION_FILENAME) as f: exec(f.read(), PACKAGE_INFO) @@ -42,15 +43,16 @@ description="OpenTelemetry Python SDK", include_package_data=True, long_description=open("README.rst").read(), - install_requires=[ - "opentelemetry-api==0.1.dev0" - ], + install_requires=["opentelemetry-api==0.1.dev0"], extras_require={}, license="Apache-2.0", package_dir={"": "src"}, - packages=setuptools.find_namespace_packages(where="src", - include="opentelemetry.sdk.*"), - url=("https://github.com/open-telemetry/opentelemetry-python" - "/tree/master/opentelemetry-sdk"), + packages=setuptools.find_namespace_packages( + where="src", include="opentelemetry.sdk.*" + ), + url=( + "https://github.com/open-telemetry/opentelemetry-python" + "/tree/master/opentelemetry-sdk" + ), zip_safe=False, ) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/__init__.py index 7d6a6e83f41..94c5ff2d8ee 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/__init__.py @@ -15,7 +15,4 @@ from . import trace from . import util -__all__ = [ - "trace", - "util", -] +__all__ = ["trace", "util"] diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/context/propagation/b3_format.py b/opentelemetry-sdk/src/opentelemetry/sdk/context/propagation/b3_format.py index eaeeb577d2b..3223e39eb13 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/context/propagation/b3_format.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/context/propagation/b3_format.py @@ -39,7 +39,8 @@ def extract(cls, get_from_carrier, carrier): flags = None single_header = _extract_first_element( - get_from_carrier(carrier, cls.SINGLE_HEADER_KEY)) + get_from_carrier(carrier, cls.SINGLE_HEADER_KEY) + ) if single_header: # The b3 spec calls for the sampling state to be # "deferred", which is unspecified. This concept does not @@ -58,14 +59,30 @@ def extract(cls, get_from_carrier, carrier): else: return trace.INVALID_SPAN_CONTEXT else: - trace_id = _extract_first_element( - get_from_carrier(carrier, cls.TRACE_ID_KEY)) or trace_id - span_id = _extract_first_element( - get_from_carrier(carrier, cls.SPAN_ID_KEY)) or span_id - sampled = _extract_first_element( - get_from_carrier(carrier, cls.SAMPLED_KEY)) or sampled - flags = _extract_first_element( - get_from_carrier(carrier, cls.FLAGS_KEY)) or flags + trace_id = ( + _extract_first_element( + get_from_carrier(carrier, cls.TRACE_ID_KEY) + ) + or trace_id + ) + span_id = ( + _extract_first_element( + get_from_carrier(carrier, cls.SPAN_ID_KEY) + ) + or span_id + ) + sampled = ( + _extract_first_element( + get_from_carrier(carrier, cls.SAMPLED_KEY) + ) + or sampled + ) + flags = ( + _extract_first_element( + get_from_carrier(carrier, cls.FLAGS_KEY) + ) + or flags + ) options = 0 # The b3 spec provides no defined behavior for both sample and @@ -86,10 +103,12 @@ def extract(cls, get_from_carrier, carrier): @classmethod def inject(cls, context, set_in_carrier, carrier): sampled = (trace.TraceOptions.RECORDED & context.trace_options) != 0 - set_in_carrier(carrier, cls.TRACE_ID_KEY, - format_trace_id(context.trace_id)) - set_in_carrier(carrier, cls.SPAN_ID_KEY, - format_span_id(context.span_id)) + set_in_carrier( + carrier, cls.TRACE_ID_KEY, format_trace_id(context.trace_id) + ) + set_in_carrier( + carrier, cls.SPAN_ID_KEY, format_span_id(context.span_id) + ) set_in_carrier(carrier, cls.SAMPLED_KEY, "1" if sampled else "0") diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 03cf34c1784..531da12db1c 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -42,18 +42,16 @@ class BoundedList(Sequence): """An append only list with a fixed max size.""" + def __init__(self, maxlen): self.dropped = 0 self._dq = deque(maxlen=maxlen) self._lock = threading.Lock() def __repr__(self): - return ("{}({}, maxlen={})" - .format( - type(self).__name__, - list(self._dq), - self._dq.maxlen - )) + return "{}({}, maxlen={})".format( + type(self).__name__, list(self._dq), self._dq.maxlen + ) def __getitem__(self, index): return self._dq[index] @@ -91,6 +89,7 @@ def from_seq(cls, maxlen, seq): class BoundedDict(MutableMapping): """A dict with a fixed max capacity.""" + def __init__(self, maxlen): if not isinstance(maxlen, int): raise ValueError @@ -102,12 +101,9 @@ def __init__(self, maxlen): self._lock = threading.Lock() def __repr__(self): - return ("{}({}, maxlen={})" - .format( - type(self).__name__, - dict(self._dict), - self.maxlen - )) + return "{}({}, maxlen={})".format( + type(self).__name__, dict(self._dict), self.maxlen + ) def __getitem__(self, key): return self._dict[key] @@ -146,9 +142,9 @@ def from_map(cls, maxlen, mapping): return bounded_dict -Event = namedtuple('Event', ('name', 'attributes')) +Event = namedtuple("Event", ("name", "attributes")) -Link = namedtuple('Link', ('context', 'attributes')) +Link = namedtuple("Link", ("context", "attributes")) class Span(trace_api.Span): @@ -174,17 +170,18 @@ class Span(trace_api.Span): empty_events = BoundedList(MAX_NUM_EVENTS) empty_links = BoundedList(MAX_NUM_LINKS) - def __init__(self: 'Span', - name: str, - context: 'trace_api.SpanContext', - parent: trace_api.ParentSpan = None, - sampler=None, # TODO - trace_config=None, # TODO - resource=None, # TODO - attributes: types.Attributes = None, # TODO - events: typing.Sequence[Event] = None, # TODO - links: typing.Sequence[Link] = None, # TODO - ) -> None: + def __init__( + self: "Span", + name: str, + context: "trace_api.SpanContext", + parent: trace_api.ParentSpan = None, + sampler=None, # TODO + trace_config=None, # TODO + resource=None, # TODO + attributes: types.Attributes = None, # TODO + events: typing.Sequence[Event] = None, # TODO + links: typing.Sequence[Link] = None, # TODO + ) -> None: self.name = name self.context = context @@ -200,7 +197,8 @@ def __init__(self: 'Span', self.attributes = Span.empty_attributes else: self.attributes = BoundedDict.from_map( - MAX_NUM_ATTRIBUTES, attributes) + MAX_NUM_ATTRIBUTES, attributes + ) if events is None: self.events = Span.empty_events @@ -216,37 +214,32 @@ def __init__(self: 'Span', self.start_time = None def __repr__(self): - return ('{}(name="{}")' - .format( - type(self).__name__, - self.name - )) + return '{}(name="{}")'.format(type(self).__name__, self.name) def get_context(self): return self.context - def set_attribute(self: 'Span', - key: str, - value: types.AttributeValue, - ) -> None: + def set_attribute( + self: "Span", key: str, value: types.AttributeValue + ) -> None: if self.attributes is Span.empty_attributes: self.attributes = BoundedDict(MAX_NUM_ATTRIBUTES) self.attributes[key] = value - def add_event(self: 'Span', - name: str, - attributes: types.Attributes = None, - ) -> None: + def add_event( + self: "Span", name: str, attributes: types.Attributes = None + ) -> None: if self.events is Span.empty_events: self.events = BoundedList(MAX_NUM_EVENTS) if attributes is None: attributes = Span.empty_attributes self.events.append(Event(name, attributes)) - def add_link(self: 'Span', - link_target_context: 'trace_api.SpanContext', - attributes: types.Attributes = None, - ) -> None: + def add_link( + self: "Span", + link_target_context: "trace_api.SpanContext", + attributes: types.Attributes = None, + ) -> None: if self.links is Span.empty_links: self.links = BoundedList(MAX_NUM_LINKS) if attributes is None: @@ -287,12 +280,10 @@ class Tracer(trace_api.Tracer): name: The name of the tracer. """ - def __init__(self, - name: str = '' - ) -> None: - slot_name = 'current_span' + def __init__(self, name: str = "") -> None: + slot_name = "current_span" if name: - slot_name = '{}.current_span'.format(name) + slot_name = "{}.current_span".format(name) self._current_span_slot = Context.register_slot(slot_name) def get_current_span(self): @@ -300,19 +291,20 @@ def get_current_span(self): return self._current_span_slot.get() @contextmanager - def start_span(self, - name: str, - parent: trace_api.ParentSpan = trace_api.Tracer.CURRENT_SPAN - ) -> typing.Iterator['Span']: + def start_span( + self, + name: str, + parent: trace_api.ParentSpan = trace_api.Tracer.CURRENT_SPAN, + ) -> typing.Iterator["Span"]: """See `opentelemetry.trace.Tracer.start_span`.""" with self.use_span(self.create_span(name, parent)) as span: yield span - def create_span(self, - name: str, - parent: trace_api.ParentSpan = - trace_api.Tracer.CURRENT_SPAN - ) -> 'Span': + def create_span( + self, + name: str, + parent: trace_api.ParentSpan = trace_api.Tracer.CURRENT_SPAN, + ) -> "Span": """See `opentelemetry.trace.Tracer.create_span`.""" span_id = generate_span_id() if parent is Tracer.CURRENT_SPAN: @@ -330,11 +322,12 @@ def create_span(self, parent_context.trace_id, span_id, parent_context.trace_options, - parent_context.trace_state) + parent_context.trace_state, + ) return Span(name=name, context=context, parent=parent) @contextmanager - def use_span(self, span: 'Span') -> typing.Iterator['Span']: + def use_span(self, span: "Span") -> typing.Iterator["Span"]: """See `opentelemetry.trace.Tracer.use_span`.""" span.start() span_snapshot = self._current_span_slot.get() diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/util.py b/opentelemetry-sdk/src/opentelemetry/sdk/util.py index 9886206fb79..0efe009b628 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/util.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/util.py @@ -18,5 +18,6 @@ time_ns = time.time_ns # pylint: disable=invalid-name # Python versions < 3.7 except AttributeError: + def time_ns(): return int(time.time() * 1e9) diff --git a/opentelemetry-sdk/tests/context/propagation/test_b3_format.py b/opentelemetry-sdk/tests/context/propagation/test_b3_format.py index a24dd01c668..42ff3410f06 100644 --- a/opentelemetry-sdk/tests/context/propagation/test_b3_format.py +++ b/opentelemetry-sdk/tests/context/propagation/test_b3_format.py @@ -29,9 +29,11 @@ class TestB3Format(unittest.TestCase): @classmethod def setUpClass(cls): cls.serialized_trace_id = b3_format.format_trace_id( - trace.generate_trace_id()) + trace.generate_trace_id() + ) cls.serialized_span_id = b3_format.format_span_id( - trace.generate_span_id()) + trace.generate_span_id() + ) def test_extract_multi_header(self): """Test the extraction of B3 headers.""" @@ -43,25 +45,30 @@ def test_extract_multi_header(self): span_context = FORMAT.extract(get_as_list, carrier) new_carrier = {} FORMAT.inject(span_context, dict.__setitem__, new_carrier) - self.assertEqual(new_carrier[FORMAT.TRACE_ID_KEY], - self.serialized_trace_id) - self.assertEqual(new_carrier[FORMAT.SPAN_ID_KEY], - self.serialized_span_id) + self.assertEqual( + new_carrier[FORMAT.TRACE_ID_KEY], self.serialized_trace_id + ) + self.assertEqual( + new_carrier[FORMAT.SPAN_ID_KEY], self.serialized_span_id + ) self.assertEqual(new_carrier[FORMAT.SAMPLED_KEY], "1") def test_extract_single_header(self): """Test the extraction from a single b3 header.""" carrier = { - FORMAT.SINGLE_HEADER_KEY: - "{}-{}".format(self.serialized_trace_id, self.serialized_span_id) + FORMAT.SINGLE_HEADER_KEY: "{}-{}".format( + self.serialized_trace_id, self.serialized_span_id + ) } span_context = FORMAT.extract(get_as_list, carrier) new_carrier = {} FORMAT.inject(span_context, dict.__setitem__, new_carrier) - self.assertEqual(new_carrier[FORMAT.TRACE_ID_KEY], - self.serialized_trace_id) - self.assertEqual(new_carrier[FORMAT.SPAN_ID_KEY], - self.serialized_span_id) + self.assertEqual( + new_carrier[FORMAT.TRACE_ID_KEY], self.serialized_trace_id + ) + self.assertEqual( + new_carrier[FORMAT.SPAN_ID_KEY], self.serialized_span_id + ) self.assertEqual(new_carrier[FORMAT.SAMPLED_KEY], "1") def test_extract_header_precedence(self): @@ -70,20 +77,19 @@ def test_extract_header_precedence(self): """ single_header_trace_id = self.serialized_trace_id[:-3] + "123" carrier = { - FORMAT.SINGLE_HEADER_KEY: - "{}-{}".format(single_header_trace_id, self.serialized_span_id), - FORMAT.TRACE_ID_KEY: - self.serialized_trace_id, - FORMAT.SPAN_ID_KEY: - self.serialized_span_id, - FORMAT.SAMPLED_KEY: - "1", + FORMAT.SINGLE_HEADER_KEY: "{}-{}".format( + single_header_trace_id, self.serialized_span_id + ), + FORMAT.TRACE_ID_KEY: self.serialized_trace_id, + FORMAT.SPAN_ID_KEY: self.serialized_span_id, + FORMAT.SAMPLED_KEY: "1", } span_context = FORMAT.extract(get_as_list, carrier) new_carrier = {} FORMAT.inject(span_context, dict.__setitem__, new_carrier) - self.assertEqual(new_carrier[FORMAT.TRACE_ID_KEY], - single_header_trace_id) + self.assertEqual( + new_carrier[FORMAT.TRACE_ID_KEY], single_header_trace_id + ) def test_enabled_sampling(self): """Test b3 sample key variants that turn on sampling.""" @@ -146,8 +152,9 @@ def test_64bit_trace_id(self): span_context = FORMAT.extract(get_as_list, carrier) new_carrier = {} FORMAT.inject(span_context, dict.__setitem__, new_carrier) - self.assertEqual(new_carrier[FORMAT.TRACE_ID_KEY], - "0" * 16 + trace_id_64_bit) + self.assertEqual( + new_carrier[FORMAT.TRACE_ID_KEY], "0" * 16 + trace_id_64_bit + ) def test_invalid_single_header(self): """If an invalid single header is passed, return an @@ -162,7 +169,7 @@ def test_missing_trace_id(self): """If a trace id is missing, populate an invalid trace id.""" carrier = { FORMAT.SPAN_ID_KEY: self.serialized_span_id, - FORMAT.FLAGS_KEY: "1" + FORMAT.FLAGS_KEY: "1", } span_context = FORMAT.extract(get_as_list, carrier) self.assertEqual(span_context.trace_id, api_trace.INVALID_TRACE_ID) @@ -171,7 +178,7 @@ def test_missing_span_id(self): """If a trace id is missing, populate an invalid trace id.""" carrier = { FORMAT.TRACE_ID_KEY: self.serialized_trace_id, - FORMAT.FLAGS_KEY: "1" + FORMAT.FLAGS_KEY: "1", } span_context = FORMAT.extract(get_as_list, carrier) self.assertEqual(span_context.span_id, api_trace.INVALID_SPAN_ID) diff --git a/opentelemetry-sdk/tests/resources/test_init.py b/opentelemetry-sdk/tests/resources/test_init.py index 6ce69fff890..47e986bd35d 100644 --- a/opentelemetry-sdk/tests/resources/test_init.py +++ b/opentelemetry-sdk/tests/resources/test_init.py @@ -9,10 +9,8 @@ def test_resource_merge(self): right = resources.Resource({"host": "service-host"}) self.assertEqual( left.merge(right), - resources.Resource({ - "service": "ui", - "host": "service-host" - })) + resources.Resource({"service": "ui", "host": "service-host"}), + ) def test_resource_merge_empty_string(self): """Verify Resource.merge behavior with the empty string. @@ -22,13 +20,10 @@ def test_resource_merge_empty_string(self): """ left = resources.Resource({"service": "ui", "host": ""}) - right = resources.Resource({ - "host": "service-host", - "service": "not-ui" - }) + right = resources.Resource( + {"host": "service-host", "service": "not-ui"} + ) self.assertEqual( left.merge(right), - resources.Resource({ - "service": "ui", - "host": "service-host" - })) + resources.Resource({"service": "ui", "host": "service-host"}), + ) diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index cd13d0fb70e..be8ae2b0271 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -20,26 +20,24 @@ class TestTracer(unittest.TestCase): - def test_extends_api(self): tracer = trace.Tracer() self.assertIsInstance(tracer, trace_api.Tracer) class TestSpanCreation(unittest.TestCase): - def test_start_span_implicit(self): - tracer = trace.Tracer('test_start_span_implicit') + tracer = trace.Tracer("test_start_span_implicit") self.assertIsNone(tracer.get_current_span()) - with tracer.start_span('root') as root: + with tracer.start_span("root") as root: self.assertIs(tracer.get_current_span(), root) self.assertIsNotNone(root.start_time) self.assertIsNone(root.end_time) - with tracer.start_span('child') as child: + with tracer.start_span("child") as child: self.assertIs(tracer.get_current_span(), child) self.assertIs(child.parent, root) @@ -51,12 +49,15 @@ def test_start_span_implicit(self): root_context = root.get_context() child_context = child.get_context() self.assertEqual(root_context.trace_id, child_context.trace_id) - self.assertNotEqual(root_context.span_id, - child_context.span_id) - self.assertEqual(root_context.trace_state, - child_context.trace_state) - self.assertEqual(root_context.trace_options, - child_context.trace_options) + self.assertNotEqual( + root_context.span_id, child_context.span_id + ) + self.assertEqual( + root_context.trace_state, child_context.trace_state + ) + self.assertEqual( + root_context.trace_options, child_context.trace_options + ) # After exiting the child's scope the parent should become the # current span again. @@ -67,23 +68,23 @@ def test_start_span_implicit(self): self.assertIsNotNone(root.end_time) def test_start_span_explicit(self): - tracer = trace.Tracer('test_start_span_explicit') + tracer = trace.Tracer("test_start_span_explicit") other_parent = trace_api.SpanContext( - trace_id=0x000000000000000000000000deadbeef, - span_id=0x00000000deadbef0 + trace_id=0x000000000000000000000000DEADBEEF, + span_id=0x00000000DEADBEF0, ) self.assertIsNone(tracer.get_current_span()) # Test with the implicit root span - with tracer.start_span('root') as root: + with tracer.start_span("root") as root: self.assertIs(tracer.get_current_span(), root) self.assertIsNotNone(root.start_time) self.assertIsNone(root.end_time) - with tracer.start_span('stepchild', other_parent) as child: + with tracer.start_span("stepchild", other_parent) as child: # The child should become the current span as usual, but its # parent should be the one passed in, not the # previously-current span. @@ -98,12 +99,15 @@ def test_start_span_explicit(self): # parent, not the previously-current span. child_context = child.get_context() self.assertEqual(other_parent.trace_id, child_context.trace_id) - self.assertNotEqual(other_parent.span_id, - child_context.span_id) - self.assertEqual(other_parent.trace_state, - child_context.trace_state) - self.assertEqual(other_parent.trace_options, - child_context.trace_options) + self.assertNotEqual( + other_parent.span_id, child_context.span_id + ) + self.assertEqual( + other_parent.trace_state, child_context.trace_state + ) + self.assertEqual( + other_parent.trace_options, child_context.trace_options + ) # After exiting the child's scope the last span on the stack should # become current, not the child's parent. @@ -112,75 +116,82 @@ def test_start_span_explicit(self): self.assertIsNotNone(child.end_time) def test_span_members(self): - tracer = trace.Tracer('test_span_members') + tracer = trace.Tracer("test_span_members") other_context1 = trace_api.SpanContext( trace_id=trace.generate_trace_id(), - span_id=trace.generate_span_id() + span_id=trace.generate_span_id(), ) other_context2 = trace_api.SpanContext( trace_id=trace.generate_trace_id(), - span_id=trace.generate_span_id() + span_id=trace.generate_span_id(), ) self.assertIsNone(tracer.get_current_span()) - with tracer.start_span('root') as root: - root.set_attribute('component', 'http') - root.set_attribute('http.method', 'GET') - root.set_attribute('http.url', - 'https://example.com:779/path/12/?q=d#123') - root.set_attribute('http.status_code', 200) - root.set_attribute('http.status_text', 'OK') - root.set_attribute('misc.pi', 3.14) + with tracer.start_span("root") as root: + root.set_attribute("component", "http") + root.set_attribute("http.method", "GET") + root.set_attribute( + "http.url", "https://example.com:779/path/12/?q=d#123" + ) + root.set_attribute("http.status_code", 200) + root.set_attribute("http.status_text", "OK") + root.set_attribute("misc.pi", 3.14) # Setting an attribute with the same key as an existing attribute # SHOULD overwrite the existing attribute's value. - root.set_attribute('attr-key', 'attr-value1') - root.set_attribute('attr-key', 'attr-value2') + root.set_attribute("attr-key", "attr-value1") + root.set_attribute("attr-key", "attr-value2") - root.add_event('event0') - root.add_event('event1', {'name': 'birthday'}) + root.add_event("event0") + root.add_event("event1", {"name": "birthday"}) root.add_link(other_context1) - root.add_link(other_context2, {'name': 'neighbor'}) + root.add_link(other_context2, {"name": "neighbor"}) # The public API does not expose getters. # Checks by accessing the span members directly self.assertEqual(len(root.attributes), 7) - self.assertEqual(root.attributes['component'], 'http') - self.assertEqual(root.attributes['http.method'], 'GET') - self.assertEqual(root.attributes['http.url'], - 'https://example.com:779/path/12/?q=d#123') - self.assertEqual(root.attributes['http.status_code'], 200) - self.assertEqual(root.attributes['http.status_text'], 'OK') - self.assertEqual(root.attributes['misc.pi'], 3.14) - self.assertEqual(root.attributes['attr-key'], 'attr-value2') + self.assertEqual(root.attributes["component"], "http") + self.assertEqual(root.attributes["http.method"], "GET") + self.assertEqual( + root.attributes["http.url"], + "https://example.com:779/path/12/?q=d#123", + ) + self.assertEqual(root.attributes["http.status_code"], 200) + self.assertEqual(root.attributes["http.status_text"], "OK") + self.assertEqual(root.attributes["misc.pi"], 3.14) + self.assertEqual(root.attributes["attr-key"], "attr-value2") self.assertEqual(len(root.events), 2) - self.assertEqual(root.events[0], - trace.Event(name='event0', - attributes={})) - self.assertEqual(root.events[1], - trace.Event(name='event1', - attributes={'name': 'birthday'})) + self.assertEqual( + root.events[0], trace.Event(name="event0", attributes={}) + ) + self.assertEqual( + root.events[1], + trace.Event(name="event1", attributes={"name": "birthday"}), + ) self.assertEqual(len(root.links), 2) - self.assertEqual(root.links[0].context.trace_id, - other_context1.trace_id) - self.assertEqual(root.links[0].context.span_id, - other_context1.span_id) + self.assertEqual( + root.links[0].context.trace_id, other_context1.trace_id + ) + self.assertEqual( + root.links[0].context.span_id, other_context1.span_id + ) self.assertEqual(root.links[0].attributes, {}) - self.assertEqual(root.links[1].context.trace_id, - other_context2.trace_id) - self.assertEqual(root.links[1].context.span_id, - other_context2.span_id) - self.assertEqual(root.links[1].attributes, {'name': 'neighbor'}) + self.assertEqual( + root.links[1].context.trace_id, other_context2.trace_id + ) + self.assertEqual( + root.links[1].context.span_id, other_context2.span_id + ) + self.assertEqual(root.links[1].attributes, {"name": "neighbor"}) class TestSpan(unittest.TestCase): - def test_basic_span(self): - span = trace.Span('name', mock.Mock(spec=trace_api.SpanContext)) - self.assertEqual(span.name, 'name') + span = trace.Span("name", mock.Mock(spec=trace_api.SpanContext)) + self.assertEqual(span.name, "name")