Skip to content

Commit 99a04e7

Browse files
committed
Refactor utils
Fixes #1598 This refactors utils to make them private the most as possible
1 parent 4c7bbf7 commit 99a04e7

File tree

11 files changed

+131
-152
lines changed

11 files changed

+131
-152
lines changed

.github/workflows/test.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ env:
1010
# Otherwise, set variable to the commit of your branch on
1111
# opentelemetry-python-contrib which is compatible with these Core repo
1212
# changes.
13-
CONTRIB_REPO_SHA: 99d6a2d7987d0f2cdde04319627c86fc0a465351
13+
CONTRIB_REPO_SHA: eb8b85327908ea9da66224790df01a92975c3102
1414

1515
jobs:
1616
build:
@@ -56,7 +56,7 @@ jobs:
5656
run: pip install -U tox-factor
5757
- name: Cache tox environment
5858
# Preserves .tox directory between runs for faster installs
59-
uses: actions/cache@v2
59+
uses: actions/cache@v1
6060
with:
6161
path: .tox
6262
key: tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-core
@@ -109,7 +109,7 @@ jobs:
109109
run: pip install -U tox
110110
- name: Cache tox environment
111111
# Preserves .tox directory between runs for faster installs
112-
uses: actions/cache@v1
112+
uses: actions/cache@v2
113113
with:
114114
path: .tox
115115
key: tox-cache-${{ matrix.tox-environment }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-core
@@ -159,7 +159,7 @@ jobs:
159159
run: pip install -U tox-factor
160160
- name: Cache tox environment
161161
# Preserves .tox directory between runs for faster installs
162-
uses: actions/cache@v2
162+
uses: actions/cache@v1
163163
with:
164164
path: .tox
165165
key: tox-cache-${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-contrib
@@ -191,7 +191,7 @@ jobs:
191191
run: pip install -U tox
192192
- name: Cache tox environment
193193
# Preserves .tox directory between runs for faster installs
194-
uses: actions/cache@v2
194+
uses: actions/cache@v1
195195
with:
196196
path: .tox
197197
key: tox-cache-${{ matrix.tox-environment }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-contrib

opentelemetry-api/src/opentelemetry/trace/__init__.py

+32-29
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,14 @@
7474
"""
7575

7676

77-
import abc
78-
import enum
79-
import typing
77+
from abc import ABC, abstractmethod
8078
from contextlib import contextmanager
79+
from enum import Enum
8180
from logging import getLogger
81+
from typing import Iterator, Optional, Sequence, cast
8282

8383
from opentelemetry.context.context import Context
84+
from opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER
8485
from opentelemetry.trace.propagation import (
8586
get_current_span,
8687
set_span_in_context,
@@ -102,12 +103,12 @@
102103
)
103104
from opentelemetry.trace.status import Status
104105
from opentelemetry.util import types
105-
from opentelemetry.util.providers import _load_trace_provider
106+
from opentelemetry.util._providers import _load_provider
106107

107108
logger = getLogger(__name__)
108109

109110

110-
class LinkBase(abc.ABC):
111+
class LinkBase(ABC):
111112
def __init__(self, context: "SpanContext") -> None:
112113
self._context = context
113114

@@ -116,7 +117,7 @@ def context(self) -> "SpanContext":
116117
return self._context
117118

118119
@property
119-
@abc.abstractmethod
120+
@abstractmethod
120121
def attributes(self) -> types.Attributes:
121122
pass
122123

@@ -140,10 +141,10 @@ def attributes(self) -> types.Attributes:
140141
return self._attributes
141142

142143

143-
_Links = typing.Optional[typing.Sequence[Link]]
144+
_Links = Optional[Sequence[Link]]
144145

145146

146-
class SpanKind(enum.Enum):
147+
class SpanKind(Enum):
147148
"""Specifies additional details on how this span relates to its parent span.
148149
149150
Note that this enumeration is experimental and likely to change. See
@@ -172,8 +173,8 @@ class SpanKind(enum.Enum):
172173
CONSUMER = 4
173174

174175

175-
class TracerProvider(abc.ABC):
176-
@abc.abstractmethod
176+
class TracerProvider(ABC):
177+
@abstractmethod
177178
def get_tracer(
178179
self,
179180
instrumenting_module_name: str,
@@ -217,7 +218,7 @@ def get_tracer(
217218
return DefaultTracer()
218219

219220

220-
class Tracer(abc.ABC):
221+
class Tracer(ABC):
221222
"""Handles span creation and in-process context propagation.
222223
223224
This class provides methods for manipulating the context, creating spans,
@@ -228,15 +229,15 @@ class Tracer(abc.ABC):
228229
# This is the default behavior when creating spans.
229230
CURRENT_SPAN = DefaultSpan(INVALID_SPAN_CONTEXT)
230231

231-
@abc.abstractmethod
232+
@abstractmethod
232233
def start_span(
233234
self,
234235
name: str,
235-
context: typing.Optional[Context] = None,
236+
context: Optional[Context] = None,
236237
kind: SpanKind = SpanKind.INTERNAL,
237238
attributes: types.Attributes = None,
238239
links: _Links = None,
239-
start_time: typing.Optional[int] = None,
240+
start_time: Optional[int] = None,
240241
record_exception: bool = True,
241242
set_status_on_exception: bool = True,
242243
) -> "Span":
@@ -283,19 +284,19 @@ def start_span(
283284
"""
284285

285286
@contextmanager # type: ignore
286-
@abc.abstractmethod
287+
@abstractmethod
287288
def start_as_current_span(
288289
self,
289290
name: str,
290-
context: typing.Optional[Context] = None,
291+
context: Optional[Context] = None,
291292
kind: SpanKind = SpanKind.INTERNAL,
292293
attributes: types.Attributes = None,
293294
links: _Links = None,
294-
start_time: typing.Optional[int] = None,
295+
start_time: Optional[int] = None,
295296
record_exception: bool = True,
296297
set_status_on_exception: bool = True,
297298
end_on_exit: bool = True,
298-
) -> typing.Iterator["Span"]:
299+
) -> Iterator["Span"]:
299300
"""Context manager for creating a new span and set it
300301
as the current span in this tracer's context.
301302
@@ -350,10 +351,10 @@ def start_as_current_span(
350351
"""
351352

352353
@contextmanager # type: ignore
353-
@abc.abstractmethod
354+
@abstractmethod
354355
def use_span(
355356
self, span: "Span", end_on_exit: bool = False,
356-
) -> typing.Iterator[None]:
357+
) -> Iterator[None]:
357358
"""Context manager for setting the passed span as the
358359
current span in the context, as well as resetting the
359360
context back upon exiting the context manager.
@@ -381,11 +382,11 @@ class DefaultTracer(Tracer):
381382
def start_span(
382383
self,
383384
name: str,
384-
context: typing.Optional[Context] = None,
385+
context: Optional[Context] = None,
385386
kind: SpanKind = SpanKind.INTERNAL,
386387
attributes: types.Attributes = None,
387388
links: _Links = None,
388-
start_time: typing.Optional[int] = None,
389+
start_time: Optional[int] = None,
389390
record_exception: bool = True,
390391
set_status_on_exception: bool = True,
391392
) -> "Span":
@@ -396,22 +397,22 @@ def start_span(
396397
def start_as_current_span(
397398
self,
398399
name: str,
399-
context: typing.Optional[Context] = None,
400+
context: Optional[Context] = None,
400401
kind: SpanKind = SpanKind.INTERNAL,
401402
attributes: types.Attributes = None,
402403
links: _Links = None,
403-
start_time: typing.Optional[int] = None,
404+
start_time: Optional[int] = None,
404405
record_exception: bool = True,
405406
set_status_on_exception: bool = True,
406407
end_on_exit: bool = True,
407-
) -> typing.Iterator["Span"]:
408+
) -> Iterator["Span"]:
408409
# pylint: disable=unused-argument,no-self-use
409410
yield INVALID_SPAN
410411

411412
@contextmanager # type: ignore
412413
def use_span(
413414
self, span: "Span", end_on_exit: bool = False,
414-
) -> typing.Iterator[None]:
415+
) -> Iterator[None]:
415416
# pylint: disable=unused-argument,no-self-use
416417
yield
417418

@@ -422,7 +423,7 @@ def use_span(
422423
def get_tracer(
423424
instrumenting_module_name: str,
424425
instrumenting_library_version: str = "",
425-
tracer_provider: typing.Optional[TracerProvider] = None,
426+
tracer_provider: Optional[TracerProvider] = None,
426427
) -> "Tracer":
427428
"""Returns a `Tracer` for use by the given instrumentation library.
428429
@@ -458,8 +459,10 @@ def get_tracer_provider() -> TracerProvider:
458459
global _TRACER_PROVIDER # pylint: disable=global-statement
459460

460461
if _TRACER_PROVIDER is None:
461-
_TRACER_PROVIDER = _load_trace_provider("tracer_provider")
462-
462+
_TRACER_PROVIDER = cast( # type: ignore
463+
"TracerProvider",
464+
_load_provider(OTEL_PYTHON_TRACER_PROVIDER, "tracer_provider"),
465+
)
463466
return _TRACER_PROVIDER
464467

465468

opentelemetry-api/src/opentelemetry/trace/span.py

+46-7
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,55 @@
77

88
from opentelemetry.trace.status import Status
99
from opentelemetry.util import types
10-
from opentelemetry.util.tracestate import (
11-
_DELIMITER_PATTERN,
12-
_MEMBER_PATTERN,
13-
_TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS,
14-
_is_valid_pair,
10+
11+
# The key MUST begin with a lowercase letter or a digit,
12+
# and can only contain lowercase letters (a-z), digits (0-9),
13+
# underscores (_), dashes (-), asterisks (*), and forward slashes (/).
14+
# For multi-tenant vendor scenarios, an at sign (@) can be used to
15+
# prefix the vendor name. Vendors SHOULD set the tenant ID
16+
# at the beginning of the key.
17+
18+
# key = ( lcalpha ) 0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )
19+
# key = ( lcalpha / DIGIT ) 0*240( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) "@" lcalpha 0*13( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )
20+
# lcalpha = %x61-7A ; a-z
21+
22+
_KEY_FORMAT = (
23+
r"[a-z][_0-9a-z\-\*\/]{0,255}|"
24+
r"[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}"
25+
)
26+
_KEY_PATTERN = re.compile(_KEY_FORMAT)
27+
28+
# The value is an opaque string containing up to 256 printable
29+
# ASCII [RFC0020] characters (i.e., the range 0x20 to 0x7E)
30+
# except comma (,) and (=).
31+
# value = 0*255(chr) nblk-chr
32+
# nblk-chr = %x21-2B / %x2D-3C / %x3E-7E
33+
# chr = %x20 / nblk-chr
34+
35+
_VALUE_FORMAT = (
36+
r"[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]"
1537
)
38+
_VALUE_PATTERN = re.compile(_VALUE_FORMAT)
1639

40+
41+
_TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS = 32
42+
_delimiter_pattern = re.compile(r"[ \t]*,[ \t]*")
43+
_member_pattern = re.compile(
44+
"({})(=)({})[ \t]*".format(_KEY_FORMAT, _VALUE_FORMAT)
45+
)
1746
_logger = logging.getLogger(__name__)
1847

1948

49+
def _is_valid_pair(key: str, value: str) -> bool:
50+
51+
return (
52+
isinstance(key, str)
53+
and _KEY_PATTERN.fullmatch(key) is not None
54+
and isinstance(value, str)
55+
and _VALUE_PATTERN.fullmatch(value) is not None
56+
)
57+
58+
2059
class Span(abc.ABC):
2160
"""A span represents a single operation within a trace."""
2261

@@ -314,11 +353,11 @@ def from_header(cls, header_list: typing.List[str]) -> "TraceState":
314353
"""
315354
pairs = OrderedDict()
316355
for header in header_list:
317-
for member in re.split(_DELIMITER_PATTERN, header):
356+
for member in re.split(_delimiter_pattern, header):
318357
# empty members are valid, but no need to process further.
319358
if not member:
320359
continue
321-
match = _MEMBER_PATTERN.fullmatch(member)
360+
match = _member_pattern.fullmatch(member)
322361
if not match:
323362
_logger.warning(
324363
"Member doesn't match the w3c identifiers format %s",

opentelemetry-api/src/opentelemetry/util/providers.py renamed to opentelemetry-api/src/opentelemetry/util/_providers.py

-21
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,19 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import time
1615
from logging import getLogger
1716
from os import environ
1817
from typing import TYPE_CHECKING, Union, cast
1918

2019
from pkg_resources import iter_entry_points
2120

22-
from opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER
23-
2421
if TYPE_CHECKING:
2522
from opentelemetry.trace import TracerProvider
2623

2724
Provider = Union["TracerProvider"]
2825

2926
logger = getLogger(__name__)
3027

31-
# Since we want API users to be able to provide timestamps,
32-
# this needs to be in the API.
33-
34-
try:
35-
time_ns = time.time_ns
36-
# Python versions < 3.7
37-
except AttributeError:
38-
39-
def time_ns() -> int:
40-
return int(time.time() * 1e9)
41-
4228

4329
def _load_provider(
4430
provider_environment_variable: str, provider: str
@@ -60,10 +46,3 @@ def _load_provider(
6046
except Exception: # pylint: disable=broad-except
6147
logger.error("Failed to load configured provider %s", provider)
6248
raise
63-
64-
65-
def _load_trace_provider(provider: str) -> "TracerProvider":
66-
return cast( # type: ignore
67-
"TracerProvider",
68-
_load_provider(OTEL_PYTHON_TRACER_PROVIDER, provider),
69-
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from sys import version_info
16+
17+
if version_info.minor < 7:
18+
from time import time
19+
20+
def time_ns() -> int:
21+
# FIXME this approach can have precision problems as explained here:
22+
# https://github.com/open-telemetry/opentelemetry-python/issues/1594
23+
return int(time() * 1e9)
24+
25+
26+
else:
27+
from time import time_ns # pylint: disable=unused-import

0 commit comments

Comments
 (0)