diff --git a/CHANGES.txt b/CHANGES.txt index 0b319fb5..8b00cefd 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,13 @@ +1.0 (unreleased) +================ + +- Move 'substanced.locking.now' to 'substanced.util.now', and rework to avoid + warning spew for 'datetime.datetime.utcnow'. + +- Suppress other warning spew from upstreams in newer Python versions + ('chameleon' / AST, 'pkg_resources', etc.) + + 1.0b1 (2024-11-27) ================== @@ -26,7 +36,7 @@ - Override ``serialize`` for ``ReferenceIdSchemaNode``. See https://github.com/Pylons/substanced/pull/311 -- Get all tests running under ``py.test`` against head of Pyramid's +- Get all tests running under ``py.test`` against head of Pyramid's ``1.10`` branch. See https://github.com/Pylons/substanced/pull/309 - Add support for Python 3.6 and 3.7; drop support for Python 3.4. @@ -111,7 +121,7 @@ the change. - Removed Python 2.6 compatibility shim ``substanced._compat.total_ordering``. - + 1.0a1 (2015-04-17) ================== diff --git a/demos/blog/blog/views/retail.py b/demos/blog/blog/views/retail.py index e8d52522..f25093f8 100644 --- a/demos/blog/blog/views/retail.py +++ b/demos/blog/blog/views/retail.py @@ -7,7 +7,10 @@ from pyramid.decorator import reify from pyramid.httpexceptions import HTTPFound from pyramid.url import resource_url -from substanced.util import find_catalog +from substanced.util import ( + find_catalog, + now, +) from pyramid.view import ( view_config, view_defaults, @@ -122,11 +125,6 @@ def __init__(self, context, request): self.context = context self.request = request - def _nowtz(self): - now = datetime.datetime.utcnow() # naive - y, mo, d, h, mi, s = now.timetuple()[:6] - return datetime.datetime(y, mo, d, h, mi, s, tzinfo=pytz.utc) - def _get_feed_info(self): context = self.context request = self.request @@ -160,7 +158,7 @@ def _add_updated_strings(updated, info): blogentries.sort(key=lambda x: x[0].isoformat()) blogentries = [entry[1] for entry in reversed(blogentries)][:15] - updated = blogentries and blogentries[0]['pubdate'] or self._nowtz() + updated = blogentries and blogentries[0]['pubdate'] or now() _add_updated_strings(updated, feed) return feed, blogentries diff --git a/pytest.ini b/pytest.ini index 8e2c1f9a..e104f6c5 100644 --- a/pytest.ini +++ b/pytest.ini @@ -3,5 +3,9 @@ addopts = -l --strict norecursedirs = lib include .tox .git python_files = test_*.py tests.py filterwarnings = + ignore::DeprecationWarning:chameleon ignore::DeprecationWarning:pkg_resources + ignore:.*pkg_resources:DeprecationWarning + ignore:.*Attribute . is deprecated:DeprecationWarning + ignore::DeprecationWarning:webob ignore::DeprecationWarning:zodburi diff --git a/substanced/audit/tests/test_views.py b/substanced/audit/tests/test_views.py index fdaa864d..e780e4a5 100644 --- a/substanced/audit/tests/test_views.py +++ b/substanced/audit/tests/test_views.py @@ -1,4 +1,6 @@ +import datetime import unittest + from pyramid import testing class Test_AuditLogEventStreamView(unittest.TestCase): @@ -93,11 +95,10 @@ def test_auditstream_sse_with_last_event_id_and_oids(self): self.assertEqual(list(auditlog.oids), [3]) def test_auditing(self): - import pytz context = testing.DummyResource() request = testing.DummyRequest() request.user = testing.DummyResource() - request.user.timezone = pytz.timezone('UTC') + request.user.timezone = datetime.timezone.utc inst = self._makeOne(context, request) inst.get_auditlog = lambda c: DummyAuditLog() result = inst.auditing() diff --git a/substanced/content/test_it.py b/substanced/content/test_it.py index 2368712b..f11923ce 100644 --- a/substanced/content/test_it.py +++ b/substanced/content/test_it.py @@ -24,7 +24,6 @@ def test_add_with_meta(self): def test_create(self): registry = DummyRegistry() inst = self._makeOne(registry) - inst._utcnow = lambda *a: 1 content = testing.DummyResource() inst.content_types['dummy'] = lambda a: content inst.meta['dummy'] = {} @@ -34,7 +33,6 @@ def test_create(self): def test_create_with_oid(self): registry = DummyRegistry() inst = self._makeOne(registry) - inst._utcnow = lambda *a: 1 content = testing.DummyResource() inst.content_types['dummy'] = lambda a: content inst.meta['dummy'] = {} diff --git a/substanced/locking/__init__.py b/substanced/locking/__init__.py index ae57edba..73bd96da 100644 --- a/substanced/locking/__init__.py +++ b/substanced/locking/__init__.py @@ -7,7 +7,6 @@ import datetime import uuid -import pytz from zope.interface import implementer @@ -43,6 +42,7 @@ find_objectmap, find_service, get_oid, + now, ) from substanced.schema import Schema @@ -69,9 +69,6 @@ class UnlockError(LockingError): or ``None`` if there was no lock to unlock. """ -def now(): - return datetime.datetime.utcnow().replace(tzinfo=pytz.UTC) - class LockOwnerSchema(colander.SchemaNode): title = 'Owner' schema_type = colander.Int diff --git a/substanced/locking/tests/test_init.py b/substanced/locking/tests/test_init.py index 0834ba00..1247a324 100644 --- a/substanced/locking/tests/test_init.py +++ b/substanced/locking/tests/test_init.py @@ -20,16 +20,6 @@ def test_ctor(self): inst = self._makeOne('lock') self.assertEqual(inst.lock, 'lock') -class Test_now(unittest.TestCase): - def _callFUT(self): - from .. import now - return now() - - def test_it(self): - from pytz import UTC - result = self._callFUT() - self.assertEqual(result.tzinfo, UTC) - class TestLockOwnerSchema(unittest.TestCase): def _makeOne(self): from .. import LockOwnerSchema @@ -210,18 +200,18 @@ def test_ctor(self): self.assertEqual(inst.comment, 'comment') def test_refresh(self): - import datetime + from .. import now inst = self._makeOne() - now = datetime.datetime.utcnow() - inst.refresh(when=now) - self.assertEqual(inst.last_refresh, now) + NOW = now() + inst.refresh(when=NOW) + self.assertEqual(inst.last_refresh, NOW) def test_refresh_with_timeout(self): - import datetime + from .. import now inst = self._makeOne() - now = datetime.datetime.utcnow() - inst.refresh(timeout=30, when=now) - self.assertEqual(inst.last_refresh, now) + NOW = now() + inst.refresh(timeout=30, when=NOW) + self.assertEqual(inst.last_refresh, NOW) self.assertEqual(inst.timeout, 30) def test_expires_timeout_is_None(self): @@ -231,11 +221,12 @@ def test_expires_timeout_is_None(self): def test_expires_timeout_is_int(self): import datetime + from .. import now inst = self._makeOne() inst.timeout = 30 - now = datetime.datetime.utcnow() - inst.last_refresh = now - self.assertEqual(inst.expires(), now + datetime.timedelta(seconds=30)) + NOW = now() + inst.last_refresh = NOW + self.assertEqual(inst.expires(), NOW + datetime.timedelta(seconds=30)) def test_is_valid_expires_timeout_is_None(self): inst = self._makeOne() @@ -244,31 +235,34 @@ def test_is_valid_expires_timeout_is_None(self): def test_is_valid_expires_timeout_is_int(self): import datetime + from .. import now inst = self._makeOne() inst.timeout = 30 - now = datetime.datetime.utcnow() - future = now + datetime.timedelta(seconds=60) - inst.last_refresh = now - self.assertTrue(inst.is_valid(now)) - self.assertFalse(inst.is_valid(future)) + NOW = now() + FUTURE = NOW + datetime.timedelta(seconds=60) + inst.last_refresh = NOW + self.assertTrue(inst.is_valid(NOW)) + self.assertFalse(inst.is_valid(FUTURE)) def test_is_valid_expires_resource_id_exists(self): import datetime + from .. import now inst = self._makeOne() inst.timeout = 30 - now = datetime.datetime.utcnow() - inst.last_refresh = now + NOW = now() + inst.last_refresh = NOW inst.__objectmap__ = DummyObjectMap([1]) - self.assertTrue(inst.is_valid(now)) + self.assertTrue(inst.is_valid(NOW)) def test_is_valid_expires_resource_id_notexist(self): import datetime + from .. import now inst = self._makeOne() inst.timeout = 30 - now = datetime.datetime.utcnow() - inst.last_refresh = now + NOW = now() + inst.last_refresh = NOW inst.__objectmap__ = DummyObjectMap([]) - self.assertFalse(inst.is_valid(now)) + self.assertFalse(inst.is_valid(NOW)) def test_depth_wo_infinite(self): inst = self._makeOne(infinite=False) diff --git a/substanced/util/__init__.py b/substanced/util/__init__.py index f10db34f..0909644d 100644 --- a/substanced/util/__init__.py +++ b/substanced/util/__init__.py @@ -3,6 +3,7 @@ import cProfile as _profile except ImportError: # pragma: no cover (pypy) import profile as _profile +import datetime import itertools import json import math @@ -30,6 +31,9 @@ _marker = object() +def now(): + return datetime.datetime.now(datetime.timezone.utc) + class JsonDict(dict): def __str__(self): return json.dumps(self) diff --git a/substanced/util/test_it.py b/substanced/util/test_it.py index a67cadf3..6f73fd6a 100644 --- a/substanced/util/test_it.py +++ b/substanced/util/test_it.py @@ -4,6 +4,17 @@ from . import _marker +class Test_now(unittest.TestCase): + def _callFUT(self): + from . import now + return now() + + def test_it(self): + import datetime + + result = self._callFUT() + self.assertIs(result.tzinfo, datetime.timezone.utc) + class Test__postorder(unittest.TestCase): def setUp(self): testing.setUp() @@ -391,8 +402,8 @@ def _callFUT(self, d): def test_it(self): import calendar - import datetime - d = datetime.datetime.utcnow() + from . import now + d = now() result = self._callFUT(d) timetime = calendar.timegm(d.timetuple()) val = int(timetime) // 100