Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions tensorboard/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,6 @@ py_library(
srcs = ["default.py"],
srcs_version = "PY3",
deps = [
"//tensorboard:expect_pkg_resources_installed",
"//tensorboard/backend:experimental_plugin",
"//tensorboard/plugins/audio:audio_plugin",
"//tensorboard/plugins/core:core_plugin",
Expand Down Expand Up @@ -347,7 +346,6 @@ py_test(
deps = [
":default",
":test",
"//tensorboard:expect_pkg_resources_installed",
"//tensorboard/plugins:base_plugin",
],
)
Expand All @@ -367,7 +365,7 @@ py_test(
deps = [
":test",
":version",
"//tensorboard:expect_pkg_resources_installed",
"//tensorboard:expect_packaging_installed",
],
)

Expand Down Expand Up @@ -461,10 +459,10 @@ py_library(name = "expect_absl_logging_installed")
# `pip install absl-py`
py_library(name = "expect_absl_testing_absltest_installed")

# This is a dummy rule used as a pkg-resources dependency in open-source.
# We expect pkg-resources to already be installed on the system, e.g., via
# `pip install setuptools`.
py_library(name = "expect_pkg_resources_installed")
# This is a dummy rule used as a packaging dependency in open-source.
# We expect packaging to already be installed on the system, e.g. via
# `pip install packaging`.
py_library(name = "expect_packaging_installed")

# This is a dummy rule used as a pandas dependency in open-source.
# We expect pandas to already be installed on the system, e.g. via
Expand Down
2 changes: 1 addition & 1 deletion tensorboard/data/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ py_library(
":grpc_provider",
":ingester",
"//tensorboard:expect_grpc_installed",
"//tensorboard:expect_pkg_resources_installed",
"//tensorboard:expect_packaging_installed",
"//tensorboard/data/proto:protos_all_py_pb2",
"//tensorboard/util:tb_logging",
],
Expand Down
11 changes: 4 additions & 7 deletions tensorboard/data/server_ingester.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@
import time

import grpc
import pkg_resources
from packaging import version as packaging_version

from tensorboard.data import grpc_provider
from tensorboard.data import ingester
from tensorboard.data.proto import data_provider_pb2
from tensorboard.util import tb_logging


logger = tb_logging.get_logger()

# If this environment variable is non-empty, it will be used as the path to the
Expand Down Expand Up @@ -202,7 +201,7 @@ def _maybe_read_file(path):


def _make_stub(addr, channel_creds_type):
(creds, options) = channel_creds_type.channel_config()
creds, options = channel_creds_type.channel_config()
options.append(("grpc.max_receive_message_length", 1024 * 1024 * 256))
channel = grpc.secure_channel(addr, creds, options=options)
return grpc_provider.make_stub(channel)
Expand Down Expand Up @@ -231,9 +230,7 @@ def __init__(self, path, version):
"""
self._path = path
self._version = (
pkg_resources.parse_version(version)
if version is not None
else version
packaging_version.parse(version) if version is not None else version
)

@property
Expand All @@ -260,7 +257,7 @@ def at_least_version(self, required_version):
"""
if self._version is None:
return True
return self._version >= pkg_resources.parse_version(required_version)
return self._version >= packaging_version.parse(required_version)


def get_server_binary():
Expand Down
22 changes: 14 additions & 8 deletions tensorboard/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@
for less repetition.
"""


import logging

import pkg_resources
from importlib import metadata

from tensorboard.plugins.audio import audio_plugin
from tensorboard.plugins.core import core_plugin
Expand All @@ -46,7 +44,6 @@
from tensorboard.plugins.mesh import mesh_plugin
from tensorboard.plugins.wit_redirect import wit_redirect_plugin


logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -119,8 +116,17 @@ def get_dynamic_plugins():
[1]: https://packaging.python.org/specifications/entry-points/
"""
return [
entry_point.resolve()
for entry_point in pkg_resources.iter_entry_points(
"tensorboard_plugins"
)
entry_point.load()
for entry_point in _iter_entry_points("tensorboard_plugins")
]


def _iter_entry_points(group):
"""Returns entry points for a given group across Python versions."""
entry_points = metadata.entry_points()
# In newer Python versions, `metadata.entry_points()` returns an
# `EntryPoints` object with a `select()` method.
# Before "selectable" entry points existed, it would return a dictionary.
if hasattr(entry_points, "select"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding a comment clarifying why this check exists?

Maybe:

# In newer Python versions, `metadata.entry_points()` returns an `EntryPoints`
# object with a `select()` method.
# Before "selectable" entry points existed, it would return a dictionary.

return entry_points.select(group=group)
return entry_points.get(group, ())
40 changes: 9 additions & 31 deletions tensorboard/default_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,30 @@
# ==============================================================================
"""Unit tests for `tensorboard.default`."""


from unittest import mock

import pkg_resources

from tensorboard import default
from tensorboard.plugins import base_plugin
from tensorboard import test


class FakePlugin(base_plugin.TBPlugin):
"""FakePlugin for testing."""

plugin_name = "fake"


class FakeEntryPoint(pkg_resources.EntryPoint):
"""EntryPoint class that fake loads FakePlugin."""

@classmethod
def create(cls):
"""Creates an instance of FakeEntryPoint.

Returns:
instance of FakeEntryPoint
"""
return cls("foo", "bar")

def resolve(self):
"""Returns FakePlugin instead of resolving module.
class FakeEntryPoint:
def __init__(self, value):
self._value = value

Returns:
FakePlugin
"""
return FakePlugin
def load(self):
return self._value


class DefaultTest(test.TestCase):
@mock.patch.object(pkg_resources, "iter_entry_points")
@mock.patch.object(default, "_iter_entry_points")
def test_get_dynamic_plugin(self, mock_iter_entry_points):
mock_iter_entry_points.return_value = [FakeEntryPoint.create()]
fake_plugin = object()
mock_iter_entry_points.return_value = [FakeEntryPoint(fake_plugin)]

actual_plugins = default.get_dynamic_plugins()

mock_iter_entry_points.assert_called_with("tensorboard_plugins")
self.assertEqual(actual_plugins, [FakePlugin])
self.assertEqual(actual_plugins, [fake_plugin])


if __name__ == "__main__":
Expand Down
23 changes: 6 additions & 17 deletions tensorboard/version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.


import pkg_resources
from packaging import version as packaging_version

from tensorboard import test as tb_test
from tensorboard import version
Expand All @@ -22,22 +22,11 @@
class VersionTest(tb_test.TestCase):
def test_valid_pep440_version(self):
"""Ensure that our version is PEP 440-compliant."""
# pkg_resources.parse_version() doesn't have a public return type,
# so we get a handle to it by parsing known good and bad versions.
#
# Note: depending on the version of the module (which is bundled
# with setuptools), when called with a non-compliant version, it
# either returns a `LegacyVersion` (setuptools < 66) or raises an
# `InvalidVersion` exception (setuptools >= 66). Handle both cases.
compliant_version = pkg_resources.parse_version("1.0.0")
try:
legacy_version = pkg_resources.parse_version("arbitrary string")
except Exception:
legacy_version = None
self.assertNotEqual(type(compliant_version), type(legacy_version))

tensorboard_version = pkg_resources.parse_version(version.VERSION)
self.assertIsInstance(tensorboard_version, type(compliant_version))
with self.assertRaises(packaging_version.InvalidVersion):
packaging_version.parse("arbitrary string")

tensorboard_version = packaging_version.parse(version.VERSION)
self.assertIsInstance(tensorboard_version, packaging_version.Version)


if __name__ == "__main__":
Expand Down
Loading