# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from os import getpid
from socket import gethostname
from time import time

# pylint: disable=wrong-import-position
from google.protobuf.timestamp_pb2 import Timestamp
from opencensus.proto.agent.common.v1 import common_pb2
from opencensus.proto.trace.v1 import trace_pb2

from opentelemetry.exporter.opencensus.version import (
    __version__ as opencensusexporter_exporter_version,
)
from opentelemetry.trace import SpanKind
from opentelemetry.util._importlib_metadata import version

OPENTELEMETRY_VERSION = version("opentelemetry-api")


def proto_timestamp_from_time_ns(time_ns):
    """Converts datetime to protobuf timestamp.

    Args:
        time_ns: Time in nanoseconds

    Returns:
        Returns protobuf timestamp.
    """
    ts = Timestamp()
    if time_ns is not None:
        # pylint: disable=no-member
        ts.FromNanoseconds(time_ns)
    return ts


# pylint: disable=no-member
def get_collector_span_kind(kind: SpanKind):
    if kind is SpanKind.SERVER:
        return trace_pb2.Span.SpanKind.SERVER
    if kind is SpanKind.CLIENT:
        return trace_pb2.Span.SpanKind.CLIENT
    return trace_pb2.Span.SpanKind.SPAN_KIND_UNSPECIFIED


def add_proto_attribute_value(pb_attributes, key, value):
    """Sets string, int, boolean or float value on protobuf
        span, link or annotation attributes.

    Args:
        pb_attributes: protobuf Span's attributes property.
        key: attribute key to set.
        value: attribute value
    """

    if isinstance(value, bool):
        pb_attributes.attribute_map[key].bool_value = value
    elif isinstance(value, int):
        pb_attributes.attribute_map[key].int_value = value
    elif isinstance(value, str):
        pb_attributes.attribute_map[key].string_value.value = value
    elif isinstance(value, float):
        pb_attributes.attribute_map[key].double_value = value
    else:
        pb_attributes.attribute_map[key].string_value.value = str(value)


# pylint: disable=no-member
def get_node(service_name, host_name):
    """Generates Node message from params and system information.

    Args:
       service_name: Name of Collector service.
       host_name: Host name.
    """
    return common_pb2.Node(
        identifier=common_pb2.ProcessIdentifier(
            host_name=gethostname() if host_name is None else host_name,
            pid=getpid(),
            start_timestamp=proto_timestamp_from_time_ns(int(time() * 1e9)),
        ),
        library_info=common_pb2.LibraryInfo(
            language=common_pb2.LibraryInfo.Language.Value("PYTHON"),
            exporter_version=opencensusexporter_exporter_version,
            core_library_version=OPENTELEMETRY_VERSION,
        ),
        service_info=common_pb2.ServiceInfo(name=service_name),
    )

exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/util.py
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from os import getpid
from socket import gethostname
from time import time

# pylint: disable=wrong-import-position
from google.protobuf.timestamp_pb2 import (  # pylint: disable=no-name-in-module
    Timestamp,
)
from opencensus.proto.agent.common.v1 import common_pb2
from opencensus.proto.trace.v1 import trace_pb2

from opentelemetry.exporter.opencensus.version import (
    __version__ as opencensusexporter_exporter_version,
)
from opentelemetry.trace import SpanKind
from opentelemetry.util._importlib_metadata import version

OPENTELEMETRY_VERSION = version("opentelemetry-api")


def proto_timestamp_from_time_ns(time_ns):
    """Converts datetime to protobuf timestamp.

    Args:
        time_ns: Time in nanoseconds

    Returns:
        Returns protobuf timestamp.
    """
    ts = Timestamp()
    if time_ns is not None:
        # pylint: disable=no-member
        ts.FromNanoseconds(time_ns)
    return ts


# pylint: disable=no-member
def get_collector_span_kind(kind: SpanKind):
    if kind is SpanKind.SERVER:
        return trace_pb2.Span.SpanKind.SERVER
    if kind is SpanKind.CLIENT:
        return trace_pb2.Span.SpanKind.CLIENT
    return trace_pb2.Span.SpanKind.SPAN_KIND_UNSPECIFIED


def add_proto_attribute_value(pb_attributes, key, value):
    """Sets string, int, boolean or float value on protobuf
        span, link or annotation attributes.

    Args:
        pb_attributes: protobuf Span's attributes property.
        key: attribute key to set.
        value: attribute value
    """

    if isinstance(value, bool):
        pb_attributes.attribute_map[key].bool_value = value
    elif isinstance(value, int):
        pb_attributes.attribute_map[key].int_value = value
    elif isinstance(value, str):
        pb_attributes.attribute_map[key].string_value.value = value
    elif isinstance(value, float):
        pb_attributes.attribute_map[key].double_value = value
    else:
        pb_attributes.attribute_map[key].string_value.value = str(value)


# pylint: disable=no-member
def get_node(service_name, host_name):
    """Generates Node message from params and system information.

    Args:
       service_name: Name of Collector service.
       host_name: Host name.
    """
    return common_pb2.Node(
        identifier=common_pb2.ProcessIdentifier(
            host_name=gethostname() if host_name is None else host_name,
            pid=getpid(),
            start_timestamp=proto_timestamp_from_time_ns(int(time() * 1e9)),
        ),
        library_info=common_pb2.LibraryInfo(
            language=common_pb2.LibraryInfo.Language.Value("PYTHON"),
            exporter_version=opencensusexporter_exporter_version,
            core_library_version=OPENTELEMETRY_VERSION,
        ),
        service_info=common_pb2.ServiceInfo(name=service_name),
    )

exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/util.py
diff --git a/docs/examples/fork-process-model/flask-gunicorn/requirements.txt b/docs/examples/fork-process-model/flask-gunicorn/requirements.txt
index ad166e35901..e1e8b00aa21 100644
--- a/docs/examples/fork-process-model/flask-gunicorn/requirements.txt
+++ b/docs/examples/fork-process-model/flask-gunicorn/requirements.txt
@@ -12,7 +12,7 @@ opentelemetry-instrumentation==0.41b0
 opentelemetry-instrumentation-flask==0.41b0
 opentelemetry-instrumentation-wsgi==0.41b0
 opentelemetry-sdk==1.20.0
-protobuf==3.19.5
+protobuf==3.20.3
 six==1.15.0
 thrift==0.13.0
 uWSGI==2.0.22
diff --git a/docs/examples/fork-process-model/flask-uwsgi/requirements.txt b/docs/examples/fork-process-model/flask-uwsgi/requirements.txt
index ad166e35901..e1e8b00aa21 100644
--- a/docs/examples/fork-process-model/flask-uwsgi/requirements.txt
+++ b/docs/examples/fork-process-model/flask-uwsgi/requirements.txt
@@ -12,7 +12,7 @@ opentelemetry-instrumentation==0.41b0
 opentelemetry-instrumentation-flask==0.41b0
 opentelemetry-instrumentation-wsgi==0.41b0
 opentelemetry-sdk==1.20.0
-protobuf==3.19.5
+protobuf==3.20.3
 six==1.15.0
 thrift==0.13.0
 uWSGI==2.0.22
diff --git a/exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/util.py b/exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/util.py
index 694e8dc6a10..77eed6ffd17 100644
--- a/exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/util.py
+++ b/exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/util.py
@@ -17,7 +17,9 @@
 from time import time
 
 # pylint: disable=wrong-import-position
-from google.protobuf.timestamp_pb2 import Timestamp
+from google.protobuf.timestamp_pb2 import (  # pylint: disable=no-name-in-module
+    Timestamp,
+)
 from opencensus.proto.agent.common.v1 import common_pb2
 from opencensus.proto.trace.v1 import trace_pb2
 
diff --git a/exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_trace_exporter.py b/exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_trace_exporter.py
index fa546cde7a2..75340da192c 100644
--- a/exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_trace_exporter.py
+++ b/exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_trace_exporter.py
@@ -16,7 +16,9 @@
 from unittest import mock
 
 import grpc
-from google.protobuf.timestamp_pb2 import Timestamp
+from google.protobuf.timestamp_pb2 import (  # pylint: disable=no-name-in-module
+    Timestamp,
+)
 from opencensus.proto.trace.v1 import trace_pb2
 
 import opentelemetry.exporter.opencensus.util as utils
diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt b/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt
new file mode 100644
index 00000000000..a692923fc42
--- /dev/null
+++ b/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt
@@ -0,0 +1,19 @@
+asgiref==3.7.2
+attrs==23.2.0
+Deprecated==1.2.14
+flaky==3.7.0
+importlib-metadata==6.11.0
+iniconfig==2.0.0
+packaging==23.2
+pluggy==1.4.0
+protobuf==3.20.3
+py==1.11.0
+py-cpuinfo==9.0.0
+pytest==7.1.3
+pytest-benchmark==4.0.0
+tomli==2.0.1
+typing_extensions==4.10.0
+wrapt==1.16.0
+zipp==3.17.0
+-e opentelemetry-proto
+-e exporter/opentelemetry-exporter-otlp-proto-common
diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements.txt b/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt
similarity index 100%
rename from exporter/opentelemetry-exporter-otlp-proto-common/test-requirements.txt
rename to exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt
diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt b/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt
index aa28c101cf4..c1ef1b74296 100644
--- a/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt
+++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt
@@ -8,7 +8,7 @@ importlib-metadata==6.11.0
 iniconfig==2.0.0
 packaging==23.2
 pluggy==1.4.0
-protobuf==3.19.6
+protobuf==3.20.3
 py==1.11.0
 py-cpuinfo==9.0.0
 pytest==7.1.3
diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py
index be0c7e1b0f3..da66f830c2f 100644
--- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py
+++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py
@@ -18,7 +18,9 @@
 from unittest import TestCase
 from unittest.mock import patch
 
-from google.protobuf.duration_pb2 import Duration
+from google.protobuf.duration_pb2 import (  # pylint: disable=no-name-in-module
+    Duration,
+)
 from google.rpc.error_details_pb2 import RetryInfo
 from grpc import ChannelCredentials, Compression, StatusCode, server
 
diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py
index 4dfed3e1541..c5e1ed76e70 100644
--- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py
+++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py
@@ -20,7 +20,9 @@
 from unittest import TestCase
 from unittest.mock import Mock, patch
 
-from google.protobuf.duration_pb2 import Duration
+from google.protobuf.duration_pb2 import (  # pylint: disable=no-name-in-module
+    Duration,
+)
 from google.rpc.error_details_pb2 import RetryInfo
 from grpc import Compression
 
diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py
index 95733b917bf..c52e94a00ea 100644
--- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py
+++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py
@@ -24,7 +24,9 @@
 from unittest import TestCase
 from unittest.mock import patch
 
-from google.protobuf.duration_pb2 import Duration
+from google.protobuf.duration_pb2 import (  # pylint: disable=no-name-in-module
+    Duration,
+)
 from google.rpc.error_details_pb2 import RetryInfo
 from grpc import ChannelCredentials, Compression, StatusCode, server
 
diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py
index bb17e35b7b7..3424d2c0898 100644
--- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py
+++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py
@@ -20,7 +20,9 @@
 from unittest import TestCase
 from unittest.mock import Mock, PropertyMock, patch
 
-from google.protobuf.duration_pb2 import Duration
+from google.protobuf.duration_pb2 import (  # pylint: disable=no-name-in-module
+    Duration,
+)
 from google.rpc.error_details_pb2 import RetryInfo
 from grpc import ChannelCredentials, Compression, StatusCode, server
 
diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt b/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt
index 0faf2626687..cad177da7b5 100644
--- a/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt
+++ b/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt
@@ -10,7 +10,7 @@ importlib-metadata==6.11.0
 iniconfig==2.0.0
 packaging==23.2
 pluggy==1.4.0
-protobuf==3.19.6
+protobuf==3.20.3
 py==1.11.0
 py-cpuinfo==9.0.0
 pytest==7.1.3
diff --git a/opentelemetry-proto/test-requirements.txt b/opentelemetry-proto/test-requirements-0.txt
similarity index 94%
rename from opentelemetry-proto/test-requirements.txt
rename to opentelemetry-proto/test-requirements-0.txt
index 4908ed5baaf..811544a0826 100644
--- a/opentelemetry-proto/test-requirements.txt
+++ b/opentelemetry-proto/test-requirements-0.txt
@@ -6,6 +6,7 @@ importlib-metadata==6.11.0
 iniconfig==2.0.0
 packaging==23.2
 pluggy==1.4.0
+protobuf==3.20.3
 py==1.11.0
 py-cpuinfo==9.0.0
 pytest==7.1.3
diff --git a/opentelemetry-proto/test-requirements-1.txt b/opentelemetry-proto/test-requirements-1.txt
new file mode 100644
index 00000000000..5b10e6867a7
--- /dev/null
+++ b/opentelemetry-proto/test-requirements-1.txt
@@ -0,0 +1,18 @@
+asgiref==3.7.2
+attrs==23.2.0
+Deprecated==1.2.14
+flaky==3.7.0
+importlib-metadata==6.11.0
+iniconfig==2.0.0
+packaging==23.2
+pluggy==1.4.0
+protobuf==4.25.3
+py==1.11.0
+py-cpuinfo==9.0.0
+pytest==7.1.3
+pytest-benchmark==4.0.0
+tomli==2.0.1
+typing_extensions==4.10.0
+wrapt==1.16.0
+zipp==3.17.0
+-e opentelemetry-proto
diff --git a/tox.ini b/tox.ini
index f537bd6216b..2e12556b4d1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,9 +8,12 @@ envlist =
     py3{8,9,10,11}-opentelemetry-api
     pypy3-opentelemetry-api
 
-    ; Test against both protobuf 3.x and 4.x
-    py3{8,9,10,11}-proto{3,4}-opentelemetry-protobuf
-    pypy3-proto{3,4}-opentelemetry-protobuf
+    ; The numbers at the end of the environment names
+    ; below mean these dependencies are being used:
+    ; 0: protobuf==3.20.3
+    ; 1: protobuf==4.25.3
+    py3{8,9,10,11}-opentelemetry-protobuf-{0,1}
+    pypy3-opentelemetry-protobuf-{0,1}
 
     py3{8,9,10,11}-opentelemetry-sdk
     pypy3-opentelemetry-sdk
@@ -31,18 +34,30 @@ envlist =
     py3{8,9,10,11}-opentelemetry-exporter-opencensus
     ; exporter-opencensus intentionally excluded from pypy3
 
-    py3{8,9,10,11}-proto{3,4}-opentelemetry-exporter-otlp-proto-common
-    pypy3-proto{3,4}-opentelemetry-exporter-otlp-proto-common
+    ; The numbers at the end of the environment names
+    ; below mean these dependencies are being used:
+    ; 0: protobuf==3.20.3
+    ; 1: protobuf==4.25.3
+    py3{8,9,10,11}-opentelemetry-exporter-otlp-proto-common-{0,1}
+    pypy3-opentelemetry-exporter-otlp-proto-common-{0,1}
 
     ; opentelemetry-exporter-otlp
     py3{8,9,10,11}-opentelemetry-exporter-otlp-combined
     ; intentionally excluded from pypy3
 
-    py3{8,9,10,11}-proto{3,4}-opentelemetry-exporter-otlp-proto-grpc
+    ; The numbers at the end of the environment names
+    ; below mean these dependencies are being used:
+    ; 0: protobuf==3.20.3
+    ; 1: protobuf==4.25.3
+    py3{8,9,10,11}-opentelemetry-exporter-otlp-proto-grpc-{0,1}
     ; intentionally excluded from pypy3
 
-    py3{8,9,10,11}-proto{3,4}-opentelemetry-exporter-otlp-proto-http
-    pypy3-opentelemetry-proto{3,4}-exporter-otlp-proto-http
+    ; The numbers at the end of the environment names
+    ; below mean these dependencies are being used:
+    ; 0: protobuf==3.20.3
+    ; 1: protobuf==4.25.3
+    py3{8,9,10,11}-opentelemetry-exporter-otlp-proto-http-{0,1}
+    pypy3-opentelemetry-exporter-otlp-proto-http-{0,1}
 
     py3{8,9,10,11}-opentelemetry-exporter-prometheus
     pypy3-opentelemetry-exporter-prometheus
@@ -109,7 +124,8 @@ commands_pre =
 ; cases but it saves a lot of boilerplate in this file.
   opentelemetry: pip install {toxinidir}/opentelemetry-api {toxinidir}/opentelemetry-semantic-conventions {toxinidir}/opentelemetry-sdk {toxinidir}/tests/opentelemetry-test-utils
 
-  protobuf: pip install -r {toxinidir}/opentelemetry-proto/test-requirements.txt
+  protobuf-0: pip install -r {toxinidir}/opentelemetry-proto/test-requirements-0.txt
+  protobuf-1: pip install -r {toxinidir}/opentelemetry-proto/test-requirements-1.txt
 
   getting-started: pip install -r {toxinidir}/docs/getting_started/tests/requirements.txt
   getting-started: pip install -e {env:CONTRIB_REPO}\#egg=opentelemetry-util-http&subdirectory=util/opentelemetry-util-http
@@ -120,15 +136,16 @@ commands_pre =
 
   exporter-opencensus: pip install -r {toxinidir}/exporter/opentelemetry-exporter-opencensus/test-requirements.txt
 
-  exporter-otlp-proto-common: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements.txt
+  exporter-otlp-proto-common-0: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt
+  exporter-otlp-proto-common-1: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-1.txt
 
   exporter-otlp-combined: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp/test-requirements.txt
 
-  proto3-opentelemetry-exporter-otlp-proto-grpc: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt
-  proto4-opentelemetry-exporter-otlp-proto-grpc: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt
+  opentelemetry-exporter-otlp-proto-grpc-0: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt
+  opentelemetry-exporter-otlp-proto-grpc-1: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt
 
-  proto3-opentelemetry-exporter-otlp-proto-http: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt
-  proto4-opentelemetry-exporter-otlp-proto-http: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt
+  opentelemetry-exporter-otlp-proto-http-0: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt
+  opentelemetry-exporter-otlp-proto-http-1: pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt
 
   opentracing-shim: pip install -r {toxinidir}/shim/opentelemetry-opentracing-shim/test-requirements.txt
 
@@ -204,27 +221,24 @@ deps =
   -r dev-requirements.txt
 
 commands_pre =
-  pip install -r {toxinidir}/opentelemetry-api/test-requirements.txt
-  pip install -r {toxinidir}/opentelemetry-sdk/test-requirements.txt
-  pip install -r {toxinidir}/opentelemetry-semantic-conventions/test-requirements.txt
-  pip install -r {toxinidir}/opentelemetry-proto/test-requirements.txt
-  pip install -r {toxinidir}/shim/opentelemetry-opentracing-shim/test-requirements.txt
-  pip install -r {toxinidir}/shim/opentelemetry-opencensus-shim/test-requirements.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-opencensus/test-requirements.txt
-  pip install -r {toxinidir}/tests/opentelemetry-test-utils/test-requirements.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-1.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-1.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-prometheus/test-requirements.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http/test-requirements.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-zipkin-json/test-requirements.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-otlp/test-requirements.txt
-  pip install -r {toxinidir}/exporter/opentelemetry-exporter-zipkin/test-requirements.txt
-  pip install -r {toxinidir}/propagator/opentelemetry-propagator-b3/test-requirements.txt
-  pip install -r {toxinidir}/propagator/opentelemetry-propagator-jaeger/test-requirements.txt
-  # Pin protobuf version due to lint failing on v3.20.0
-  # https://github.com/protocolbuffers/protobuf/issues/9730
-  python -m pip install protobuf==3.19.4
+  pip install -r {toxinidir}/opentelemetry-api/test-requirements.txt \
+  -r {toxinidir}/opentelemetry-sdk/test-requirements.txt \
+  -r {toxinidir}/opentelemetry-semantic-conventions/test-requirements.txt \
+  -r {toxinidir}/opentelemetry-proto/test-requirements-0.txt \
+  -r {toxinidir}/shim/opentelemetry-opentracing-shim/test-requirements.txt \
+  -r {toxinidir}/shim/opentelemetry-opencensus-shim/test-requirements.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-opencensus/test-requirements.txt \
+  -r {toxinidir}/tests/opentelemetry-test-utils/test-requirements.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-common/test-requirements-0.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-http/test-requirements-0.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-otlp-proto-grpc/test-requirements-0.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-prometheus/test-requirements.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-zipkin-proto-http/test-requirements.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-zipkin-json/test-requirements.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-otlp/test-requirements.txt \
+  -r {toxinidir}/exporter/opentelemetry-exporter-zipkin/test-requirements.txt \
+  -r {toxinidir}/propagator/opentelemetry-propagator-b3/test-requirements.txt \
+  -r {toxinidir}/propagator/opentelemetry-propagator-jaeger/test-requirements.txt
 
 commands =
   python scripts/eachdist.py lint --check-only

lint takes a long time
Fix that.
