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
22 changes: 13 additions & 9 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ jobs:
strategy:
matrix:
python-version:
- "pypy-3.10"
- "pypy-3.11"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
extras:
- "[test,docs]"
- "[test,docs,zodb]"
# include:
# - python-version: "3.13"
# extras: "[test,docs,gevent,pyramid]"
Expand All @@ -46,10 +47,14 @@ jobs:
coverage combine || true
coverage report -i || true
- name: Lint
if: matrix.python-version == '3.12'
if: matrix.python-version == '3.14'
run: |
python -m pip install -U pylint
pylint src
- name: Test without ZODB
run: |
python -m pip uninstall -y ZODB zope.dublincore persistent zope.container BTrees
PURE_PYTHON=1 coverage run -a -m zope.testrunner --test-path=src --auto-color --auto-progress
- name: Submit to Coveralls
uses: coverallsapp/github-action@v2
with:
Expand All @@ -74,12 +79,11 @@ jobs:
python-version: [3.12]
image:
- manylinux_2_28_x86_64
- manylinux2014_aarch64
- manylinux2014_ppc64le
- manylinux2014_s390x
- manylinux2014_x86_64
- musllinux_1_1_x86_64
- musllinux_1_1_aarch64
- manylinux_2_28_aarch64
- manylinux_2_28_ppc64le
- manylinux_2_28_s390x
- musllinux_1_2_x86_64
- musllinux_1_2_aarch64
name: ${{ matrix.image }}

steps:
Expand Down
10 changes: 8 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
=========


2.4.1 (unreleased)
2.5.0 (unreleased)
==================

- Reduce the logging level for recursive invocations. We handle this
case correctly, it did not need to be a warning.

- Add support for Python 3.14.
- Add the new 'zodb' extra, which installs optional dependencies that
use the ZODB ecosystem: persistent, BTrees, zope.intid,
zope.container, etc. These dependencies are no longer installed by
default.
- No longer build binary wheels for the legacy 'manylinux2014'
standard, only 2_28. Similarly, switch from musllinux_1_1 to 1_2.

2.4.0 (2024-11-11)
==================
Expand Down
13 changes: 5 additions & 8 deletions make-manylinux
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,10 @@ if [ -d /project ] && [ -d /opt/python ]; then
OPATH="$PATH"
which auditwheel
echo @@@@@@@@@@@@@@@@@@@@@@
echo Will build /opt/python/cp{39,310,311}* /opt/python/pp{39,}*
echo Will build /opt/python/cp{310,311,312,313,314}*

for variant in `ls -d /opt/python/cp{314,313,310,311,312}*`; do

for variant in `ls -d /opt/python/cp{313,310,311,312}*`; do
if [ "$variant" = "/opt/python/cp313-cp313t" ]; then
echo "Skipping no-gil build. The GIL is required."
continue
fi
export PATH="$variant/bin:$OPATH"
echo "Building $variant $(python --version)"

Expand All @@ -64,7 +61,7 @@ if [ -d /project ] && [ -d /opt/python ]; then

# XXX: The name of the wheel doesn't match the name of the project
PATH="$OPATH" auditwheel repair $WHL
WHL=$(ls wheelhouse/nti.externalization*whl)
WHL=$(ls wheelhouse/*externalization*whl)
cp $WHL /project/wheelhouse
ls -l /project/wheelhouse

Expand All @@ -79,5 +76,5 @@ fi
# Mount the current directory as /project
# Can't use -i on Travis with arm64, "input device not a tty"
sname=$(basename "$0")
docker run --rm -e PIP_INDEX_URL -v "$(pwd)/:/project" "${DOCKER_IMAGE:-quay.io/pypa/manylinux2014_x86_64}" /project/"$sname"
docker run --rm -e PIP_INDEX_URL -v "$(pwd)/:/project" "${DOCKER_IMAGE:-quay.io/pypa/manylinux_2_28_x86_64}" /project/"$sname"
ls -l wheelhouse
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ requires = [
# failing in Python 2 (https://travis-ci.org/github/gevent/gevent/jobs/683782800);
# This was fixed in 3.0a5 (https://github.com/cython/cython/issues/3578)
# 3.0a6 fixes an issue cythonizing source on 32-bit platforms
"Cython >= 3.0.11",
"Cython >= 3.2.1",
]

[tool.check-manifest]
Expand Down
24 changes: 13 additions & 11 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
}

TESTS_REQUIRE = [
'nti.testing',
'nti.testing >= 4.4.0',
'zope.testrunner',
'manuel',
'pyperf',
'transaction >= 5.0',
]


Expand Down Expand Up @@ -152,20 +153,19 @@ def _c(m):
author_email='jason@nextthought.com',
description="NTI Externalization",
long_description=(_read('README.rst') + '\n\n' + _read('CHANGES.rst')),
license='Apache',
license='Apache-2.0',
keywords='externalization',
classifiers=[
'License :: OSI Approved :: Apache Software License',
'Intended Audience :: Developers',
'Natural Language :: English',
'Operating System :: OS Independent',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
],
Expand All @@ -179,30 +179,32 @@ def _c(m):
'nti.schema >= 1.17.0',

'PyYAML >= 5.1',
'ZODB >= 5.5.1',
'isodate',
'persistent >= 4.7.0',
'pytz',
'simplejson >= 3.19',
'transaction >= 2.2',
'transaction',
'zope.component >= 4.6.1',
'zope.configuration >= 4.4.0',
'zope.container >= 4.4.0',
'zope.dottedname >= 4.3.0',
'zope.dublincore >= 4.2.0',
'zope.event >= 4.4.0',
'zope.hookable >= 5.0.1',
'zope.interface >= 5.0.1', # getDirectTaggedValue
'zope.intid >= 4.3.0',
'zope.lifecycleevent >= 4.3.0',
'zope.location >= 4.2.0',
'zope.mimetype >= 2.5.0',
'zope.proxy >= 4.3.5',
'zope.schema >= 6.0.0',
'zope.security >= 5.1.1',
'BTrees >= 4.8.0', # Registers BTrees as Mapping automatically.
],
extras_require={
'zodb': [
'ZODB >= 5.5.1',
'persistent >= 4.7.0',
'zope.container >= 4.4.0',
'zope.dublincore >= 4.2.0',
'zope.intid >= 4.3.0',
'BTrees >= 4.8.0', # Registers BTrees as Mapping automatically.
],
'test': TESTS_REQUIRE,
'docs': [
'Sphinx',
Expand Down
18 changes: 14 additions & 4 deletions src/nti/externalization/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
System spanning utilities.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import sys
import logging

text_type = str

Expand All @@ -24,6 +21,19 @@
PURE_PYTHON = PYPY or os.getenv('PURE_PYTHON') or os.getenv("NTI_EXT_PURE_PYTHON")


try:
from zope.dublincore.interfaces import IDCTimes # pylint: disable=unused-import
except ModuleNotFoundError:
from zope.interface import Interface
class IDCTimes(Interface): # pylint: disable=inherit-non-class
"""Mock"""

try:
from ZODB.loglevels import TRACE
except ModuleNotFoundError:
TRACE = 5
logging.addLevelName(TRACE, "TRACE")

def to_unicode(s, encoding='utf-8', err='strict'):
"""
Decode a byte sequence and unicode result
Expand Down
10 changes: 4 additions & 6 deletions src/nti/externalization/autopackage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,19 @@
typically via a ZCML directive.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import logging

from ZODB.loglevels import TRACE
from zope import interface

from zope.dottedname import resolve as dottedname
from zope.mimetype.interfaces import IContentTypeAware

from nti.schema.interfaces import find_most_derived_interface
from nti.externalization.datastructures import ModuleScopedInterfaceObjectIO
from ._compat import TRACE
from .datastructures import ModuleScopedInterfaceObjectIO


logger = __import__('logging').getLogger(__name__)
logger = logging.getLogger(__name__)

# If we extend ExtensionClass.Base, __class_init__ is called automatically
# for each subclass. But we also start participating in acquisition, which
Expand Down
10 changes: 6 additions & 4 deletions src/nti/externalization/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
-->
<include package="." file="meta.zcml" />

<subscriber provides=".interfaces.IExternalStandardDictionaryDecorator"
for="zope.dublincore.interfaces.IDCExtended"
<subscriber
provides=".interfaces.IExternalStandardDictionaryDecorator"
for=".dublincore.IDCExtended"
factory=".dublincore.DCExtendedExternalMappingDecorator" />

<subscriber provides=".interfaces.IExternalStandardDictionaryDecorator"
for="zope.dublincore.interfaces.IDCDescriptiveProperties"
<subscriber
provides=".interfaces.IExternalStandardDictionaryDecorator"
for=".dublincore.IDCDescriptiveProperties"
factory=".dublincore.DCDescriptivePropertiesExternalMappingDecorator" />

<!-- The "*" matches things that implement some (any) interface -->
Expand Down
2 changes: 1 addition & 1 deletion src/nti/externalization/datastructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ class InterfaceObjectIO(AbstractDynamicObjectIO):
"""

_ext_iface_upper_bound = None
_iface = None


def __init__(self, context, iface_upper_bound=None, validate_after_update=True):
"""
Expand Down
11 changes: 9 additions & 2 deletions src/nti/externalization/dublincore.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@

from zope import component
from zope import interface
from zope.dublincore.interfaces import IDCDescriptiveProperties
from zope.dublincore.interfaces import IDCExtended
try:
from zope.dublincore.interfaces import IDCDescriptiveProperties
from zope.dublincore.interfaces import IDCExtended
except ModuleNotFoundError:
# pylint:disable=inherit-non-class
class IDCDescriptiveProperties(interface.Interface):
"""Mock"""
class IDCExtended(interface.Interface):
"""Mock"""

from nti.externalization.interfaces import IExternalStandardDictionaryDecorator
from nti.externalization.interfaces import StandardExternalFields
Expand Down
20 changes: 9 additions & 11 deletions src/nti/externalization/externalization/externalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,17 @@

# stdlib imports
import warnings
try:
from collections.abc import Set
except ImportError: # Python 2
# pylint:disable=deprecated-class
from collections import Set
from collections import Mapping
else: # pragma: no cover
from collections.abc import Mapping
from collections.abc import Set
from collections.abc import Mapping
from collections import defaultdict
from weakref import WeakKeyDictionary

import persistent

try:
from persistent.list import PersistentList
_PL = (PersistentList,)
except ModuleNotFoundError:
_PL = ()

from zope.component import queryAdapter
from zope.component import getUtility
Expand Down Expand Up @@ -73,11 +72,10 @@
#: by iterating it and mapping onto a list. This allows :class:`~z3c.batching.interfaces.IBatch`
#: to be directly externalized.
SEQUENCE_TYPES = (
persistent.list.PersistentList,
Set,
list,
tuple,
)
) + _PL

#: The types that we will treat as mappings for externalization purposes. These
#: all map onto a dict.
Expand Down
2 changes: 1 addition & 1 deletion src/nti/externalization/externalization/standard_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
from calendar import timegm as dt_tuple_to_unix


from zope.dublincore.interfaces import IDCTimes
from zope.security.management import system_user
from zope.security.interfaces import IPrincipal

from nti.externalization._compat import IDCTimes
from nti.externalization._base_interfaces import get_standard_external_fields
from nti.externalization._base_interfaces import get_standard_internal_fields
from nti.externalization._base_interfaces import get_default_externalization_policy
Expand Down
18 changes: 8 additions & 10 deletions src/nti/externalization/internalization/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@


# stdlib imports
try:
from collections.abc import MutableSequence
except ImportError: # Python 2
# pylint:disable=deprecated-class
from collections import MutableSequence
from collections import MutableMapping
else: # pragma: no cover
from collections.abc import MutableMapping
from collections.abc import MutableSequence
from collections.abc import MutableMapping
import inspect
import warnings


from persistent.interfaces import IPersistent
from zope import interface
try:
from persistent.interfaces import IPersistent
except ModuleNotFoundError:
class IPersistent(interface.Interface): # pylint: disable=inherit-non-class
"""Mock"""

from zope.event import notify as notify_event

from nti.externalization._base_interfaces import PRIMITIVES
Expand Down
14 changes: 11 additions & 3 deletions src/nti/externalization/oids.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,19 @@
import binascii
import collections


from ZODB.interfaces import IConnection
try:
from ZODB.interfaces import IConnection
except ModuleNotFoundError:
def IConnection(_):
raise TypeError
from zope import component

from zope.intid.interfaces import IIntIds
try:
from zope.intid.interfaces import IIntIds
except ModuleNotFoundError:
from zope.interface import Interface
class IIntIds(Interface): # pylint: disable=inherit-non-class
"""Mock"""

from nti.externalization._compat import bytes_

Expand Down
Loading
Loading