diff --git a/.github/workflows/pr-actions.yml b/.github/workflows/pr-actions.yml index 6477ba5c..a8bd8106 100644 --- a/.github/workflows/pr-actions.yml +++ b/.github/workflows/pr-actions.yml @@ -37,7 +37,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] os: ['ubuntu-latest'] name: PyTests OS ${{ matrix.os }} - Python ${{ matrix.python-version }} steps: diff --git a/brewtils/models.py b/brewtils/models.py index 635634e4..56fe2127 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import copy -from datetime import datetime +from datetime import datetime, timezone from enum import Enum +from zoneinfo import ZoneInfo -import pytz # noqa # not in requirements file import six # noqa # not in requirements file from brewtils.errors import ModelError, _deprecate @@ -468,7 +468,7 @@ def __init__(self, heartbeat=None, history=None): def set_status_heartbeat(self, status, max_history=None): - self.heartbeat = datetime.utcnow() + self.heartbeat = datetime.now(timezone.utc) self.history.append( StatusHistory(status=copy.deepcopy(status), heartbeat=self.heartbeat) ) @@ -1264,7 +1264,7 @@ def __repr__(self): class DateTrigger(BaseModel): schema = "DateTriggerSchema" - def __init__(self, run_date=None, timezone=None): + def __init__(self, run_date=None, timezone="UTC"): self.run_date = run_date self.timezone = timezone @@ -1280,9 +1280,10 @@ def scheduler_attributes(self): @property def scheduler_kwargs(self): - tz = pytz.timezone(self.timezone) - return {"timezone": tz, "run_date": tz.localize(self.run_date)} + tz = ZoneInfo(self.timezone.upper()) + + return {"timezone": tz, "run_date": self.run_date.replace(tzinfo=tz)} class IntervalTrigger(BaseModel): @@ -1297,7 +1298,7 @@ def __init__( seconds=None, start_date=None, end_date=None, - timezone=None, + timezone="UTC", jitter=None, reschedule_on_finish=None, ): @@ -1339,14 +1340,16 @@ def scheduler_attributes(self): @property def scheduler_kwargs(self): - tz = pytz.timezone(self.timezone) + tz = ZoneInfo(self.timezone.upper()) kwargs = {key: getattr(self, key) for key in self.scheduler_attributes} kwargs.update( { "timezone": tz, - "start_date": tz.localize(self.start_date) if self.start_date else None, - "end_date": tz.localize(self.end_date) if self.end_date else None, + "start_date": ( + self.start_date.replace(tzinfo=tz) if self.start_date else None + ), + "end_date": self.end_date.replace(tzinfo=tz) if self.end_date else None, } ) @@ -1368,7 +1371,7 @@ def __init__( second=None, start_date=None, end_date=None, - timezone=None, + timezone="UTC", jitter=None, ): self.year = year @@ -1415,14 +1418,16 @@ def scheduler_attributes(self): @property def scheduler_kwargs(self): - tz = pytz.timezone(self.timezone) + tz = ZoneInfo(self.timezone.upper()) kwargs = {key: getattr(self, key) for key in self.scheduler_attributes} kwargs.update( { "timezone": tz, - "start_date": tz.localize(self.start_date) if self.start_date else None, - "end_date": tz.localize(self.end_date) if self.end_date else None, + "start_date": ( + self.start_date.replace(tzinfo=tz) if self.start_date else None + ), + "end_date": self.end_date.replace(tzinfo=tz) if self.end_date else None, } ) diff --git a/brewtils/schema_parser.py b/brewtils/schema_parser.py index 86e7a22c..6853a700 100644 --- a/brewtils/schema_parser.py +++ b/brewtils/schema_parser.py @@ -370,9 +370,9 @@ def parse_job_ids(cls, job_id_json, from_string=False, **kwargs): schema = brewtils.schemas.JobExportInputSchema(**kwargs) if from_string: - return schema.loads(job_id_json).data + return schema.loads(job_id_json) else: - return schema.load(job_id_json).data + return schema.load(job_id_json) @classmethod def parse_garden(cls, garden, from_string=False, **kwargs): @@ -561,7 +561,7 @@ def parse( schema.context["models"] = cls._models - return schema.loads(data).data if from_string else schema.load(data).data + return schema.loads(data) if from_string else schema.load(data) # Serialization methods @classmethod @@ -1162,7 +1162,7 @@ def serialize( schema = getattr(brewtils.schemas, schema_name)(**kwargs) - return schema.dumps(model).data if to_string else schema.dump(model).data + return schema.dumps(model) if to_string else schema.dump(model) # Explicitly force to_string to False so only original call returns a string multiple = [ diff --git a/brewtils/schemas.py b/brewtils/schemas.py index fe3828f5..23d65e16 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -1,13 +1,9 @@ # -*- coding: utf-8 -*- -import calendar import datetime from functools import partial -import marshmallow -import simplejson -from marshmallow import Schema, fields, post_load, pre_load -from marshmallow.utils import UTC +from marshmallow import Schema, fields, post_load, pre_load, utils, EXCLUDE from marshmallow_polyfield import PolyField __all__ = [ @@ -95,57 +91,42 @@ def __init__(self, type_field="payload_type", allowed_types=None, **kwargs): class DateTime(fields.DateTime): - """Class that adds methods for (de)serializing DateTime fields as an epoch""" + """Class that adds methods for (de)serializing DateTime fields as an epoch + + This is required for going from Mongo Model objects to Marshmallow model Objects + """ def __init__(self, format="epoch", **kwargs): - self.DATEFORMAT_SERIALIZATION_FUNCS["epoch"] = self.to_epoch - self.DATEFORMAT_DESERIALIZATION_FUNCS["epoch"] = self.from_epoch + self.SERIALIZATION_FUNCS["epoch"] = self.to_epoch + self.DESERIALIZATION_FUNCS["epoch"] = self.from_epoch super(DateTime, self).__init__(format=format, **kwargs) @staticmethod - def to_epoch(dt, localtime=False): + def to_epoch(value): # If already in epoch form just return it - if isinstance(dt, int): - return dt + if isinstance(value, int) or isinstance(value, float): + return value - if localtime and dt.tzinfo is not None: - localized = dt - else: - if dt.tzinfo is None: - localized = UTC.localize(dt) - else: - localized = dt.astimezone(UTC) - return (calendar.timegm(localized.timetuple()) * 1000) + int( - localized.microsecond / 1000 - ) + if value.tzinfo is not None and value.tzinfo is not datetime.timezone.utc: + value = value.replace(tzinfo=datetime.timezone.utc) + + return utils.timestamp_ms(value) @staticmethod - def from_epoch(epoch): + def from_epoch(value): # If already in datetime form just return it - if isinstance(epoch, datetime.datetime): - return epoch - - # utcfromtimestamp will correctly parse milliseconds in Python 3, - # but in Python 2 we need to help it - seconds, millis = divmod(epoch, 1000) - return datetime.datetime.utcfromtimestamp(seconds).replace( - microsecond=millis * 1000 - ) + if isinstance(value, datetime.datetime): + if value.tzinfo is None: + return value.replace(tzinfo=datetime.timezone.utc) + return value + return utils.from_timestamp_ms(value).replace(tzinfo=datetime.timezone.utc) -class BaseSchema(Schema): - class Meta: - version_nums = marshmallow.__version__.split(".") - if int(version_nums[0]) <= 2 and int(version_nums[1]) < 17: # pragma: no cover - json_module = simplejson - else: - render_module = simplejson - def __init__(self, strict=True, **kwargs): - super(BaseSchema, self).__init__(strict=strict, **kwargs) +class BaseSchema(Schema): @post_load - def make_object(self, data): + def make_object(self, data, **_): try: model_class = self.context["models"][self.__class__.__name__] except KeyError: @@ -161,12 +142,15 @@ def get_attribute_names(cls): if isinstance(value, fields.FieldABC) ] + class Meta: + unknown = EXCLUDE + class ChoicesSchema(BaseSchema): type = fields.Str(allow_none=True) display = fields.Str(allow_none=True) value = fields.Raw(allow_none=True, many=True) - strict = fields.Bool(allow_none=True, default=False) + strict = fields.Bool(allow_none=True, dump_default=False) details = fields.Dict(allow_none=True) @@ -178,8 +162,8 @@ class ParameterSchema(BaseSchema): optional = fields.Bool(allow_none=True) default = fields.Raw(allow_none=True) description = fields.Str(allow_none=True) - choices = fields.Nested("ChoicesSchema", allow_none=True, many=False) - parameters = fields.Nested("self", many=True, allow_none=True) + choices = fields.Nested(lambda: ChoicesSchema, allow_none=True) + parameters = fields.List(fields.Nested(lambda: ParameterSchema), allow_none=True) nullable = fields.Bool(allow_none=True) maximum = fields.Int(allow_none=True) minimum = fields.Int(allow_none=True) @@ -192,7 +176,7 @@ class CommandSchema(BaseSchema): name = fields.Str(allow_none=True) display_name = fields.Str(allow_none=True) description = fields.Str(allow_none=True) - parameters = fields.Nested("ParameterSchema", many=True) + parameters = fields.List(fields.Nested(lambda: ParameterSchema()), allow_none=True) command_type = fields.Str(allow_none=True) output_type = fields.Str(allow_none=True) schema = fields.Dict(allow_none=True) @@ -211,7 +195,7 @@ class InstanceSchema(BaseSchema): name = fields.Str(allow_none=True) description = fields.Str(allow_none=True) status = fields.Str(allow_none=True) - status_info = fields.Nested("StatusInfoSchema", allow_none=True) + status_info = fields.Nested(lambda: StatusInfoSchema(), allow_none=True) queue_type = fields.Str(allow_none=True) queue_info = fields.Dict(allow_none=True) icon_name = fields.Str(allow_none=True) @@ -225,8 +209,8 @@ class SystemSchema(BaseSchema): version = fields.Str(allow_none=True) max_instances = fields.Integer(allow_none=True) icon_name = fields.Str(allow_none=True) - instances = fields.Nested("InstanceSchema", many=True, allow_none=True) - commands = fields.Nested("CommandSchema", many=True, allow_none=True) + instances = fields.List(fields.Nested(lambda: InstanceSchema()), allow_none=True) + commands = fields.List(fields.Nested(lambda: CommandSchema()), allow_none=True) display_name = fields.Str(allow_none=True) metadata = fields.Dict(allow_none=True) namespace = fields.Str(allow_none=True) @@ -257,7 +241,7 @@ class FileSchema(BaseSchema): owner = fields.Raw(allow_none=True) job = fields.Nested("JobSchema", allow_none=True) request = fields.Nested("RequestSchema", allow_none=True) - updated_at = DateTime(allow_none=True, format="epoch", example="1500065932000") + updated_at = DateTime(allow_none=True, format="epoch") file_name = fields.Str(allow_none=True) file_size = fields.Int(allow_none=False) chunks = fields.Dict(allow_none=True) @@ -319,19 +303,28 @@ class RequestTemplateSchema(BaseSchema): class RequestSchema(RequestTemplateSchema): id = fields.Str(allow_none=True) is_event = fields.Bool(allow_none=True) - parent = fields.Nested("self", exclude=("children",), allow_none=True) - children = fields.Nested( - "self", exclude=("parent", "children"), many=True, default=None, allow_none=True + parent = fields.Nested( + lambda: RequestSchema(exclude=("children",)), allow_none=True + ) + children = fields.List( + fields.Nested( + lambda: RequestSchema( + exclude=( + "parent", + "children", + ) + ) + ), + dump_default=None, + allow_none=True, ) output = fields.Str(allow_none=True) hidden = fields.Boolean(allow_none=True) status = fields.Str(allow_none=True) error_class = fields.Str(allow_none=True) - created_at = DateTime(allow_none=True, format="epoch", example="1500065932000") - updated_at = DateTime(allow_none=True, format="epoch", example="1500065932000") - status_updated_at = DateTime( - allow_none=True, format="epoch", example="1500065932000" - ) + created_at = DateTime(allow_none=True, format="epoch") + updated_at = DateTime(allow_none=True, format="epoch") + status_updated_at = DateTime(allow_none=True, format="epoch") has_parent = fields.Bool(allow_none=True) requester = fields.String(allow_none=True) source_garden = fields.String(allow_none=True) @@ -339,13 +332,13 @@ class RequestSchema(RequestTemplateSchema): class StatusHistorySchema(BaseSchema): - heartbeat = DateTime(allow_none=True, format="epoch", example="1500065932000") + heartbeat = DateTime(allow_none=True, format="epoch") status = fields.Str(allow_none=True) class StatusInfoSchema(BaseSchema): - heartbeat = DateTime(allow_none=True, format="epoch", example="1500065932000") - history = fields.Nested("StatusHistorySchema", many=True, allow_none=True) + heartbeat = DateTime(allow_none=True, format="epoch") + history = fields.List(fields.Nested(lambda: StatusHistorySchema()), allow_none=True) class PatchSchema(BaseSchema): @@ -354,7 +347,7 @@ class PatchSchema(BaseSchema): value = fields.Raw(allow_none=True) @pre_load(pass_many=True) - def unwrap_envelope(self, data, many): + def unwrap_envelope(self, data, many, **_): """Helper function for parsing the different patch formats. This exists because previously multiple patches serialized like:: @@ -397,7 +390,7 @@ class EventSchema(BaseSchema): namespace = fields.Str(allow_none=True) garden = fields.Str(allow_none=True) metadata = fields.Dict(allow_none=True) - timestamp = DateTime(allow_none=True, format="epoch", example="1500065932000") + timestamp = DateTime(allow_none=True, format="epoch") payload_type = fields.Str(allow_none=True) payload = ModelField(allow_none=True, type_field="payload_type") @@ -419,13 +412,13 @@ class QueueSchema(BaseSchema): class UserTokenSchema(BaseSchema): id = fields.Str(allow_none=True) uuid = fields.Str(allow_none=True) - issued_at = DateTime(allow_none=True, format="epoch", example="1500065932000") - expires_at = DateTime(allow_none=True, format="epoch", example="1500065932000") + issued_at = DateTime(allow_none=True, format="epoch") + expires_at = DateTime(allow_none=True, format="epoch") username = fields.Str(allow_none=True) class DateTriggerSchema(BaseSchema): - run_date = DateTime(allow_none=True, format="epoch", example="1500065932000") + run_date = DateTime(allow_none=True, format="epoch") timezone = fields.Str(allow_none=True) @@ -435,8 +428,8 @@ class IntervalTriggerSchema(BaseSchema): hours = fields.Int(allow_none=True) minutes = fields.Int(allow_none=True) seconds = fields.Int(allow_none=True) - start_date = DateTime(allow_none=True, format="epoch", example="1500065932000") - end_date = DateTime(allow_none=True, format="epoch", example="1500065932000") + start_date = DateTime(allow_none=True, format="epoch") + end_date = DateTime(allow_none=True, format="epoch") timezone = fields.Str(allow_none=True) jitter = fields.Int(allow_none=True) reschedule_on_finish = fields.Bool(allow_none=True) @@ -451,8 +444,8 @@ class CronTriggerSchema(BaseSchema): hour = fields.Str(allow_none=True) minute = fields.Str(allow_none=True) second = fields.Str(allow_none=True) - start_date = DateTime(allow_none=True, format="epoch", example="1500065932000") - end_date = DateTime(allow_none=True, format="epoch", example="1500065932000") + start_date = DateTime(allow_none=True, format="epoch") + end_date = DateTime(allow_none=True, format="epoch") timezone = fields.Str(allow_none=True) jitter = fields.Int(allow_none=True) @@ -470,7 +463,7 @@ class FileTriggerSchema(BaseSchema): class ConnectionSchema(BaseSchema): api = fields.Str(allow_none=True) status = fields.Str(allow_none=True) - status_info = fields.Nested("StatusInfoSchema", allow_none=True) + status_info = fields.Nested(lambda: StatusInfoSchema(), allow_none=True) config = fields.Dict(allow_none=True) @@ -478,20 +471,20 @@ class GardenSchema(BaseSchema): id = fields.Str(allow_none=True) name = fields.Str(allow_none=True) status = fields.Str(allow_none=True) - status_info = fields.Nested("StatusInfoSchema", allow_none=True) + status_info = fields.Nested(lambda: StatusInfoSchema(), allow_none=True) connection_type = fields.Str(allow_none=True) - receiving_connections = fields.Nested( - "ConnectionSchema", many=True, allow_none=True + receiving_connections = fields.List( + fields.Nested(lambda: ConnectionSchema()), allow_none=True ) - publishing_connections = fields.Nested( - "ConnectionSchema", many=True, allow_none=True + publishing_connections = fields.List( + fields.Nested(lambda: ConnectionSchema()), allow_none=True ) namespaces = fields.List(fields.Str(), allow_none=True) - systems = fields.Nested("SystemSchema", many=True, allow_none=True) + systems = fields.List(fields.Nested(lambda: SystemSchema()), allow_none=True) has_parent = fields.Bool(allow_none=True) parent = fields.Str(allow_none=True) - children = fields.Nested( - "self", exclude=("parent"), many=True, default=None, allow_none=True + children = fields.List( + fields.Nested(lambda: GardenSchema(exclude=("parent",))), allow_none=True ) metadata = fields.Dict(allow_none=True) default_user = fields.Str(allow_none=True) @@ -511,7 +504,7 @@ class JobSchema(BaseSchema): request_template = fields.Nested("RequestTemplateSchema", allow_none=True) misfire_grace_time = fields.Int(allow_none=True) coalesce = fields.Bool(allow_none=True) - next_run_time = DateTime(allow_none=True, format="epoch", example="1500065932000") + next_run_time = DateTime(allow_none=True, format="epoch") success_count = fields.Int(allow_none=True) error_count = fields.Int(allow_none=True) canceled_count = fields.Int(allow_none=True) @@ -624,7 +617,7 @@ class TopicSchema(BaseSchema): class ReplicationSchema(BaseSchema): id = fields.Str(allow_none=True) replication_id = fields.Str(allow_none=True) - expires_at = DateTime(allow_none=True, format="epoch", example="1500065932000") + expires_at = DateTime(allow_none=True, format="epoch") class UserSchema(BaseSchema): diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 321e393a..dbe12a2e 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import copy -from datetime import datetime +from datetime import datetime, timezone +from zoneinfo import ZoneInfo import pytest -import pytz from brewtils.models import ( AliasUserMap, @@ -49,8 +49,8 @@ def system_id(): @pytest.fixture def ts_dt(): - """Jan 1, 2016 as a naive datetime.""" - return datetime(2016, 1, 1) + """Jan 1, 2016 as a UTC timezone-aware datetime.""" + return datetime(2016, 1, 1, tzinfo=timezone.utc) @pytest.fixture @@ -62,7 +62,7 @@ def ts_epoch(): @pytest.fixture def ts_dt_utc(ts_epoch): """Jan 1, 2016 UTC as timezone-aware datetime.""" - return datetime.fromtimestamp(ts_epoch / 1000, tz=pytz.utc) + return datetime.fromtimestamp(ts_epoch / 1000, tz=timezone.utc) @pytest.fixture @@ -74,13 +74,7 @@ def ts_epoch_eastern(): @pytest.fixture def ts_dt_eastern(): """Jan 1, 2016 US/Eastern as timezone-aware datetime.""" - return datetime(2016, 1, 1, tzinfo=pytz.timezone("US/Eastern")) - - -@pytest.fixture -def ts_2_dt(ts_2_epoch): - """Feb 2, 2017 as a naive datetime.""" - return datetime(2017, 2, 2) + return datetime(2016, 1, 1, tzinfo=ZoneInfo("US/Eastern")) @pytest.fixture @@ -92,7 +86,7 @@ def ts_2_epoch(): @pytest.fixture def ts_2_dt_utc(ts_2_epoch): """Feb 2, 2017 UTC as timezone-aware datetime.""" - return datetime.fromtimestamp(ts_2_epoch / 1000, tz=pytz.utc) + return datetime.fromtimestamp(ts_2_epoch / 1000, tz=timezone.utc) @pytest.fixture @@ -859,11 +853,11 @@ def interval_trigger_dict(ts_epoch, ts_2_epoch): @pytest.fixture -def bg_interval_trigger(interval_trigger_dict, ts_dt, ts_2_dt): +def bg_interval_trigger(interval_trigger_dict, ts_dt, ts_2_dt_utc): """An interval trigger as a model.""" dict_copy = copy.deepcopy(interval_trigger_dict) dict_copy["start_date"] = ts_dt - dict_copy["end_date"] = ts_2_dt + dict_copy["end_date"] = ts_2_dt_utc return IntervalTrigger(**dict_copy) @@ -893,11 +887,11 @@ def cron_trigger_dict(ts_epoch, ts_2_epoch): @pytest.fixture -def bg_cron_trigger(cron_trigger_dict, ts_dt, ts_2_dt): +def bg_cron_trigger(cron_trigger_dict, ts_dt, ts_2_dt_utc): """A cron trigger as a model.""" dict_copy = copy.deepcopy(cron_trigger_dict) dict_copy["start_date"] = ts_dt - dict_copy["end_date"] = ts_2_dt + dict_copy["end_date"] = ts_2_dt_utc return CronTrigger(**dict_copy) diff --git a/setup.py b/setup.py index a70360a5..9fb6dc87 100644 --- a/setup.py +++ b/setup.py @@ -31,31 +31,26 @@ def find_version(): package_data={"": ["README.md"]}, install_requires=[ "appdirs<2", - "lark-parser<0.7", - "marshmallow<3", - "marshmallow-polyfield<4", + "lark-parser<1", + "marshmallow<4,>=3.3", + "marshmallow-polyfield<6", "packaging", - "pika<=1.2,>=1.0.1", - "pytz<2021", + "pika<=1.4,>=1.0.1", "requests<3", "simplejson<4", "six<2", "wrapt", "yapconf>=0.3.7", ], - extras_require={ - ':python_version=="2.7"': ["futures", "funcsigs", "pathlib"], - ':python_version<"3.4"': ["enum34"], - ':python_version<"3.5"': ["typing"], - }, classifiers=[ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Software Development :: Libraries :: Python Modules", ], ) diff --git a/test/models_test.py b/test/models_test.py index 8bfa5443..a0694778 100644 --- a/test/models_test.py +++ b/test/models_test.py @@ -1,8 +1,11 @@ # -*- coding: utf-8 -*- import warnings +from datetime import timezone +from zoneinfo import ZoneInfo import pytest -import pytz +from pytest_lazyfixture import lazy_fixture + from brewtils.errors import ModelError from brewtils.models import ( Choices, @@ -13,17 +16,16 @@ LoggingConfig, Parameter, PatchOperation, - User, Queue, Request, RequestFile, RequestTemplate, Role, - Subscriber, StatusInfo, + Subscriber, Topic, + User, ) -from pytest_lazyfixture import lazy_fixture @pytest.fixture @@ -506,7 +508,7 @@ def test_str(self, bg_event): def test_repr(self, bg_event, bg_request): assert ( repr(bg_event) == "" % bg_request ) @@ -567,7 +569,7 @@ def test_repr(self, role): class TestDateTrigger(object): def test_scheduler_kwargs(self, bg_date_trigger, ts_dt_utc): assert bg_date_trigger.scheduler_kwargs == { - "timezone": pytz.utc, + "timezone": ZoneInfo("UTC"), "run_date": ts_dt_utc, } @@ -595,7 +597,7 @@ def test_scheduler_kwargs_default(self): "seconds": None, "start_date": None, "end_date": None, - "timezone": pytz.utc, + "timezone": ZoneInfo("UTC"), "jitter": None, "reschedule_on_finish": None, } @@ -605,7 +607,11 @@ def test_scheduler_kwargs( ): expected = interval_trigger_dict expected.update( - {"timezone": pytz.utc, "start_date": ts_dt_utc, "end_date": ts_2_dt_utc} + { + "timezone": ZoneInfo("UTC"), + "start_date": ts_dt_utc, + "end_date": ts_2_dt_utc, + } ) assert bg_interval_trigger.scheduler_kwargs == expected @@ -623,7 +629,7 @@ def test_scheduler_kwargs_default(self): "second": None, "start_date": None, "end_date": None, - "timezone": pytz.utc, + "timezone": ZoneInfo("UTC"), "jitter": None, } @@ -632,7 +638,11 @@ def test_scheduler_kwargs( ): expected = cron_trigger_dict expected.update( - {"timezone": pytz.utc, "start_date": ts_dt_utc, "end_date": ts_2_dt_utc} + { + "timezone": ZoneInfo("UTC"), + "start_date": ts_dt_utc, + "end_date": ts_2_dt_utc, + } ) assert bg_cron_trigger.scheduler_kwargs == expected @@ -647,8 +657,8 @@ def test_scheduler_kwargs( ), ( lazy_fixture("bg_date_trigger"), - "", - "", + "", + "", ), ( lazy_fixture("bg_file_trigger"), diff --git a/test/schema_parser_test.py b/test/schema_parser_test.py index d49652ee..92c44190 100644 --- a/test/schema_parser_test.py +++ b/test/schema_parser_test.py @@ -60,12 +60,6 @@ def test_error(self, data, kwargs, error): with pytest.raises(error): SchemaParser.parse_system(data, **kwargs) - def test_non_strict_failure(self, system_dict): - system_dict["name"] = 1234 - value = SchemaParser.parse_system(system_dict, from_string=False, strict=False) - assert value.get("name") is None - assert value["version"] == system_dict["version"] - def test_no_modify(self, system_dict): system_copy = copy.deepcopy(system_dict) SchemaParser().parse_system(system_dict) diff --git a/test/schema_test.py b/test/schema_test.py index da25bd61..b95f0a6b 100644 --- a/test/schema_test.py +++ b/test/schema_test.py @@ -6,17 +6,15 @@ from pytest_lazyfixture import lazy_fixture from brewtils.models import System +from brewtils.schema_parser import SchemaParser from brewtils.schemas import ( BaseSchema, - DateTime, SystemSchema, _deserialize_model, _serialize_model, model_schema_map, ) -from brewtils.schema_parser import SchemaParser - class TestSchemas(object): def test_make_object(self): @@ -36,29 +34,6 @@ def test_get_attributes(self): class TestFields(object): - @pytest.mark.parametrize( - "dt,localtime,expected", - [ - (lazy_fixture("ts_dt"), False, lazy_fixture("ts_epoch")), - (lazy_fixture("ts_dt"), True, lazy_fixture("ts_epoch")), - (lazy_fixture("ts_dt_eastern"), False, lazy_fixture("ts_epoch_eastern")), - (lazy_fixture("ts_dt_eastern"), True, lazy_fixture("ts_epoch")), - (lazy_fixture("ts_epoch"), False, lazy_fixture("ts_epoch")), - (lazy_fixture("ts_epoch"), True, lazy_fixture("ts_epoch")), - ], - ) - def test_to_epoch(self, dt, localtime, expected): - assert DateTime.to_epoch(dt, localtime) == expected - - @pytest.mark.parametrize( - "epoch,expected", - [ - (lazy_fixture("ts_epoch"), lazy_fixture("ts_dt")), - (lazy_fixture("ts_dt"), lazy_fixture("ts_dt")), - ], - ) - def test_from_epoch(self, epoch, expected): - assert DateTime.from_epoch(epoch) == expected def test_modelfield_serialize_invalid_type(self): with pytest.raises(TypeError):