Skip to content

Commit

Permalink
Remove deprecated libraries flagged by pytest
Browse files Browse the repository at this point in the history
Some of these were soft deprecated (like pkg_resource), some
others were soon to be removed (tar usage with no filter to be gone 3.14
) and some are now gone (imghdr gone in 3.13)
  • Loading branch information
Hook25 committed Jan 22, 2025
1 parent ce6bef5 commit 2cb4143
Show file tree
Hide file tree
Showing 17 changed files with 159 additions and 84 deletions.
12 changes: 10 additions & 2 deletions checkbox-ng/checkbox_ng/test_certification.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,27 @@
Test definitions for plainbox.impl.certification module
"""

import requests
from io import BytesIO
from unittest import TestCase

from pkg_resources import resource_string
from plainbox.impl.transport import InvalidSecureIDError
from plainbox.impl.transport import TransportError
from plainbox.vendor import mock
from plainbox.vendor.mock import MagicMock
from requests.exceptions import ConnectionError, InvalidSchema, HTTPError
import requests

from checkbox_ng.certification import SubmissionServiceTransport

try:
from importlib.resources import files

def resource_string(module, path):
return files(module).joinpath(path).read_bytes()

except (ModuleNotFoundError, ImportError):
from pkg_resources import resource_string


class SubmissionServiceTransportTests(TestCase):

Expand Down
4 changes: 2 additions & 2 deletions checkbox-ng/checkbox_ng/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"""
import json
import textwrap
from datetime import datetime
import datetime

from plainbox.impl.color import Colorizer

Expand Down Expand Up @@ -60,7 +60,7 @@ def generate_resume_candidate_description(candidate):
last_job_id = candidate.metadata.running_job_name or "Unknown"
last_job_timestamp = candidate.metadata.last_job_start_time or None
if last_job_timestamp:
dt = datetime.utcfromtimestamp(last_job_timestamp)
dt = datetime.datetime.fromtimestamp(last_job_timestamp, datetime.UTC)
last_job_start_time = dt.strftime("%Y-%m-%d %H:%M:%S")
else:
last_job_start_time = "Unknown"
Expand Down
9 changes: 4 additions & 5 deletions checkbox-ng/plainbox/impl/exporter/jinja2.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@

import json
import re
import datetime
from collections import OrderedDict
from datetime import datetime
from packaging import version

import jinja2
Expand All @@ -46,7 +46,6 @@

from plainbox import get_version_string
from plainbox import get_origin
from plainbox.abc import ISessionStateExporter
from plainbox.impl.exporter import SessionStateExporterBase
from plainbox.impl.result import OUTCOME_METADATA_MAP
from plainbox.impl.unit.exporter import ExporterError
Expand Down Expand Up @@ -104,9 +103,9 @@ def __init__(
self._unit = exporter_unit
self._system_id = system_id
# Generate a time-stamp if needed
self._timestamp = timestamp or datetime.utcnow().strftime(
"%Y-%m-%dT%H:%M:%S"
)
self._timestamp = timestamp or datetime.datetime.now(
datetime.UTC
).strftime("%Y-%m-%dT%H:%M:%S")
# Use current version unless told otherwise
self._client_version = client_version or get_version_string()
# Remember client name
Expand Down
11 changes: 9 additions & 2 deletions checkbox-ng/plainbox/impl/exporter/test_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@
Test definitions for plainbox.impl.exporter.html module
"""
from unittest import TestCase
import io
from unittest import TestCase

try:
from importlib.resources import files

def resource_string(module, path):
return files(module).joinpath(path).read_bytes()

from pkg_resources import resource_string
except (ModuleNotFoundError, ImportError):
from pkg_resources import resource_string

from plainbox.abc import IJobResult
from plainbox.impl.exporter.jinja2 import Jinja2SessionStateExporter
Expand Down
14 changes: 12 additions & 2 deletions checkbox-ng/plainbox/impl/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"""

import ast
import sys
import itertools
import logging

Expand Down Expand Up @@ -381,8 +382,6 @@ class ResourceNodeVisitor(ast.NodeVisitor):
ast.Compare, # comparisons
ast.List, # lists
ast.Name, # name access (top-level name references)
ast.Num, # numbers
ast.Str, # strings
ast.Tuple, # tuples
ast.UnaryOp, # unary operators
# Allow all comparison operators
Expand All @@ -392,6 +391,17 @@ class ResourceNodeVisitor(ast.NodeVisitor):
# Allowed expression context (ast.expr_context)
ast.Load, # allow all loads
)
if sys.version_info[0] == 3 and sys.version_info[1] < 8:
# legacy lemmas, replaced with ast.Constant
_allowed_node_cls_list += (
ast.Num, # numbers
ast.Str, # strings
)
try:
# new in python3.6, use legacy lemmas on 3.5
_allowed_node_cls_list += (ast.Constant,)
except AttributeError:
...

def __init__(self):
"""
Expand Down
18 changes: 14 additions & 4 deletions checkbox-ng/plainbox/impl/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,16 @@
import base64
import codecs
import gzip
import imghdr
import inspect
import io
import json
import logging
import re
from contextlib import suppress
from collections import namedtuple

from plainbox.abc import IJobResult
from plainbox.i18n import gettext as _
from plainbox.i18n import pgettext as C_
from plainbox.i18n import gettext as _, pgettext as C_
from plainbox.impl import pod
from plainbox.impl.decorators import raises

Expand Down Expand Up @@ -479,7 +478,18 @@ def img_type(self):
except AttributeError:
return ""
filename = io_log_filename.replace("record.gz", "stdout")
return imghdr.what(filename)

with suppress(ModuleNotFoundError):
import imghdr # removed since python3.13

return imghdr.what(filename)

import filetype

kind = filetype.guess(filename)
if kind and kind.mime.startswith("image"):
return kind.extension
return ""

@property
def io_log_as_base64(self):
Expand Down
18 changes: 2 additions & 16 deletions checkbox-ng/plainbox/impl/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,13 @@
"""

import collections
import contextlib
import datetime
import getpass
import gzip
import io
import logging
import os
import select
import string
import subprocess
import sys
import tempfile
import threading
import time


from plainbox.abc import IJobResult, IJobRunner
from plainbox.i18n import gettext as _
from plainbox.impl.result import IOLogRecord
from plainbox.impl.result import IOLogRecordWriter
from plainbox.impl.result import JobResultBuilder
from plainbox.vendor import extcmd
from plainbox.vendor import morris

Expand All @@ -76,7 +62,7 @@ def on_begin(self, args, kwargs):
Begins tracking time (relative time entries)
"""
self.last_msg = datetime.datetime.utcnow()
self.last_msg = datetime.datetime.now(datetime.UTC)

def on_line(self, stream_name, line):
"""
Expand All @@ -86,7 +72,7 @@ def on_line(self, stream_name, line):
Maintains a timestamp of the last message so that approximate delay
between each piece of output can be recorded as well.
"""
now = datetime.datetime.utcnow()
now = datetime.datetime.now(datetime.UTC)
delay = now - self.last_msg
self.last_msg = now
record = IOLogRecord(delay.total_seconds(), stream_name, line)
Expand Down
16 changes: 10 additions & 6 deletions checkbox-ng/plainbox/impl/secure/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
===============================================================================
This module contains plugin interface for plainbox. Plugins are based on
pkg_resources entry points feature. Any python package can advertise the
importlib metadata entry points feature. Any python package can advertise the
existence of entry points associated with a given namespace. Any other
package can query a given namespace and enumerate a sequence of entry points.
Expand All @@ -47,7 +47,10 @@
import os
import time

import pkg_resources
try:
from importlib import metadata
except ImportError:
import importlib_metadata as metadata

from plainbox.i18n import gettext as _

Expand Down Expand Up @@ -467,7 +470,7 @@ def get_total_time(self) -> float:

class PkgResourcesPlugInCollection(PlugInCollectionBase):
"""
Collection of plug-ins based on pkg_resources
Collection of plug-ins based on importlib metadata
Instantiate with :attr:`namespace`, call :meth:`load()` and then access any
of the loaded plug-ins using the API offered. All loaded objects are
Expand All @@ -487,7 +490,7 @@ def __init__(
Initialize a collection of plug-ins from the specified name-space.
:param namespace:
pkg_resources entry-point name-space of the plug-in collection
importlib metadata entry-point name-space of the plug-in collection
:param load:
if true, load all of the plug-ins now
:param wrapper:
Expand Down Expand Up @@ -532,11 +535,12 @@ def load(self):

def _get_entry_points(self):
"""
Get entry points from pkg_resources.
Get entry points from importlib metadata.
This is the method you want to mock if you are writing unit tests
"""
return pkg_resources.iter_entry_points(self._namespace)

return metadata.entry_points(group=self._namespace)


class FsPlugInCollection(PlugInCollectionBase):
Expand Down
8 changes: 7 additions & 1 deletion checkbox-ng/plainbox/impl/secure/qualifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@
import logging
import operator
import re
import sre_constants

try:
# deprecated from python3.11.
# See: https://github.com/python/cpython/pull/32177/files
sre_constants = re._constants
except AttributeError:
import sre_constants

from plainbox.abc import IUnitQualifier
from plainbox.i18n import gettext as _
Expand Down
34 changes: 18 additions & 16 deletions checkbox-ng/plainbox/impl/secure/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,18 @@
Test definitions for plainbox.impl.secure.plugins module
"""

from unittest import TestCase
import collections
import os
import collections
from unittest import TestCase, mock

from plainbox.impl.secure.plugins import FsPlugInCollection
from plainbox.impl.secure.plugins import IPlugIn, PlugIn
from plainbox.impl.secure.plugins import PkgResourcesPlugInCollection
from plainbox.impl.secure.plugins import PlugInCollectionBase
from plainbox.impl.secure.plugins import PlugInError
from plainbox.vendor import mock
from plainbox.impl.secure.plugins import (
FsPlugInCollection,
IPlugIn,
PlugIn,
PkgResourcesPlugInCollection,
PlugInCollectionBase,
PlugInError,
)


class PlugInTests(TestCase):
Expand Down Expand Up @@ -343,8 +345,8 @@ def test_default_wrapper(self):
# Ensure that the wrapper is :class:`PlugIn`
self.assertEqual(self.col._wrapper, PlugIn)

@mock.patch("pkg_resources.iter_entry_points")
def test_load(self, mock_iter):
@mock.patch("plainbox.impl.secure.plugins.metadata")
def test_load(self, mock_metadata):
# Create a mocked entry point
mock_ep1 = mock.Mock()
mock_ep1.name = "zzz"
Expand All @@ -354,18 +356,18 @@ def test_load(self, mock_iter):
mock_ep2.name = "aaa"
mock_ep2.load.return_value = "one"
# Make the collection load both mocked entry points
mock_iter.return_value = [mock_ep1, mock_ep2]
mock_metadata.entry_points.return_value = [mock_ep1, mock_ep2]
# Load plugins
self.col.load()
# Ensure that pkg_resources were interrogated
mock_iter.assert_called_with(self._NAMESPACE)
mock_metadata.entry_points.assert_called_with(group=self._NAMESPACE)
# Ensure that both entry points were loaded
mock_ep1.load.assert_called_with()
mock_ep2.load.assert_called_with()

@mock.patch("plainbox.impl.secure.plugins.logger")
@mock.patch("pkg_resources.iter_entry_points")
def test_load_failing(self, mock_iter, mock_logger):
@mock.patch("plainbox.impl.secure.plugins.metadata")
def test_load_failing(self, mock_metadata, mock_logger):
# Create a mocked entry point
mock_ep1 = mock.Mock()
mock_ep1.name = "zzz"
Expand All @@ -375,11 +377,11 @@ def test_load_failing(self, mock_iter, mock_logger):
mock_ep2.name = "aaa"
mock_ep2.load.side_effect = ImportError("boom")
# Make the collection load both mocked entry points
mock_iter.return_value = [mock_ep1, mock_ep2]
mock_metadata.entry_points.return_value = [mock_ep1, mock_ep2]
# Load plugins
self.col.load()
# Ensure that pkg_resources were interrogated
mock_iter.assert_called_with(self._NAMESPACE)
mock_metadata.entry_points.assert_called_with(group=self._NAMESPACE)
# Ensure that both entry points were loaded
mock_ep1.load.assert_called_with()
mock_ep2.load.assert_called_with()
Expand Down
2 changes: 1 addition & 1 deletion checkbox-ng/plainbox/impl/session/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ def create(cls, prefix="pbox-"):
WellKnownDirsHelper.populate_base()

isoformat = "%Y-%m-%dT%H.%M.%S"
timestamp = datetime.datetime.utcnow().strftime(isoformat)
timestamp = datetime.datetime.now(datetime.UTC).strftime(isoformat)
session_id = "{prefix}{timestamp}".format(
prefix=slugify(prefix), timestamp=timestamp
)
Expand Down
11 changes: 10 additions & 1 deletion checkbox-ng/plainbox/impl/symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,16 @@ class SymbolDefNs:
:class:`Symbol` and added to the namespace.
"""

PASSTHRU = frozenset(("__name__", "__qualname__", "__doc__", "__module__"))
PASSTHRU = frozenset(
(
"__name__",
"__qualname__",
"__doc__",
"__module__",
"__firstlineno__",
"__static_attributes__",
)
)

def __init__(self, allow_outer=None):
self.data = {}
Expand Down
Loading

0 comments on commit 2cb4143

Please sign in to comment.