Skip to content

Commit

Permalink
Merge pull request #313 from zopefoundation/tseaver-312-osd_as_basetype
Browse files Browse the repository at this point in the history
fix: ensure OSD is sublcassable
  • Loading branch information
tseaver authored Aug 6, 2024
2 parents f688bb0 + 19774cd commit 011c562
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 27 deletions.
7 changes: 4 additions & 3 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
Changes
=========

7.1 (unreleased)
================
7.0.1 (unreleased)
==================

- Nothing changed yet.
- Fix subclassability of ``ObjectSpecificationDescriptor`` (broken in 7.0).
(`#312 <https://github.com/zopefoundation/zope.interface/issues/312>`_)


7.0 (2024-08-06)
Expand Down
9 changes: 1 addition & 8 deletions src/zope/interface/_zope_interface_coptimizations.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@
* #c.PyTypeObject.tp_weaklistoffset
*/
#define USE_EXPLICIT_WEAKREFLIST 0
#define LEAFTYPE_FLAGS \
Py_TPFLAGS_DEFAULT | \
Py_TPFLAGS_MANAGED_WEAKREF | \
Py_TPFLAGS_HAVE_GC
#define BASETYPE_FLAGS \
Py_TPFLAGS_DEFAULT | \
Py_TPFLAGS_BASETYPE | \
Expand All @@ -74,9 +70,6 @@
* #c.PyTypeObject.tp_weaklistoffset
*/
#define USE_EXPLICIT_WEAKREFLIST 1
#define LEAFTYPE_FLAGS \
Py_TPFLAGS_DEFAULT | \
Py_TPFLAGS_HAVE_GC
#define BASETYPE_FLAGS \
Py_TPFLAGS_DEFAULT | \
Py_TPFLAGS_BASETYPE | \
Expand Down Expand Up @@ -546,7 +539,7 @@ static PyType_Slot OSD_type_slots[] = {
static PyType_Spec OSD_type_spec = {
.name = OSD__name__,
.basicsize = 0,
.flags = LEAFTYPE_FLAGS,
.flags = BASETYPE_FLAGS,
.slots = OSD_type_slots
};

Expand Down
25 changes: 17 additions & 8 deletions src/zope/interface/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,16 @@


class OptimizationTestMixin:
"""
Helper for testing that C optimizations are used
when appropriate.
"""Mixin testing that C optimizations are used when appropriate.
"""

def _getTargetClass(self):
"""
Define this to return the implementation in use,
without the 'Py' or 'Fallback' suffix.
"""Return the implementation in use, without 'Py' or 'Fallback' suffix.
"""
raise NotImplementedError

def _getFallbackClass(self):
"""
Define this to return the fallback Python implementation.
"""Return the fallback Python implementation.
"""
# Is there an algorithmic way to do this? The C
# objects all come from the same module so I don't see how we can
Expand All @@ -33,6 +28,20 @@ def test_optimizations(self):
self.assertIs(used, fallback)


class SubclassableMixin:

def _getTargetClass(self):
"""Return the implementation in use without 'Py' or 'Fallback' suffix.
"""
raise NotImplementedError

def test_can_subclass(self):
klass = self._getTargetClass()

class Derived(klass): # no raise
pass


class MissingSomeAttrs:
"""
Helper for tests that raises a specific exception
Expand Down
12 changes: 9 additions & 3 deletions src/zope/interface/tests/test_declarations.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from zope.interface.tests import MissingSomeAttrs
from zope.interface.tests import OptimizationTestMixin
from zope.interface.tests import SubclassableMixin
from zope.interface.tests.test_interface import \
NameAndModuleComparisonTestsMixin

Expand Down Expand Up @@ -1803,8 +1804,11 @@ class Bar(Foo):
self.assertRaises(AttributeError, getattr, bar, '__provides__')


class ClassProvidesBaseTests(OptimizationTestMixin,
ClassProvidesBaseFallbackTests):
class ClassProvidesBaseTests(
OptimizationTestMixin,
ClassProvidesBaseFallbackTests,
SubclassableMixin,
):
# Repeat tests for C optimizations

def _getTargetClass(self):
Expand Down Expand Up @@ -2632,7 +2636,9 @@ def __provides__(self):

class ObjectSpecificationDescriptorTests(
ObjectSpecificationDescriptorFallbackTests,
OptimizationTestMixin):
OptimizationTestMixin,
SubclassableMixin,
):
# Repeat tests for C optimizations

def _getTargetClass(self):
Expand Down
17 changes: 12 additions & 5 deletions src/zope/interface/tests/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from zope.interface.tests import CleanUp
from zope.interface.tests import MissingSomeAttrs
from zope.interface.tests import OptimizationTestMixin
from zope.interface.tests import SubclassableMixin


_marker = object()
Expand Down Expand Up @@ -216,8 +217,11 @@ def _implementedBy(obj):
self.assertFalse(sb.implementedBy(object()))


class SpecificationBaseTests(GenericSpecificationBaseTests,
OptimizationTestMixin):
class SpecificationBaseTests(
GenericSpecificationBaseTests,
OptimizationTestMixin,
SubclassableMixin,
):
# Tests that use the C implementation

def _getTargetClass(self):
Expand Down Expand Up @@ -436,9 +440,12 @@ def test___call___w_no_conform_catches_only_AttributeError(self):
)


class InterfaceBaseTests(InterfaceBaseTestsMixin,
OptimizationTestMixin,
unittest.TestCase):
class InterfaceBaseTests(
InterfaceBaseTestsMixin,
OptimizationTestMixin,
SubclassableMixin,
unittest.TestCase,
):
# Tests that work with the C implementation
def _getTargetClass(self):
from zope.interface.interface import InterfaceBase
Expand Down

0 comments on commit 011c562

Please sign in to comment.