summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Move itertools import to module scope.issue224Jason Madden2021-03-151-30/+73
| | | | Also tweak docs.
* Let subclasses of BaseAdapterRegistry customize the data structures.Jason Madden2021-03-033-25/+844
| | | | | | | | | | | | Add extensive tests for this. Fixes #224. Also adds test for, and fixes #227 Add BAR.rebuild() to fix the refcount issue, and to change datatypes. It works by using the new methods allRegistrations() and allSubscriptions() to re-create the data in new data structures. This makes fresh calls to subscribe() and register(). I went this way instead of trying to manually walk the data structures and create them because the logic in those methods is fully tested.
* Merge branch 'master' of github.com:zopefoundation/zope.interface into masterJan-Jaap Driessen2020-10-012-0/+31
|\
| * C optimizations: Spec_clear and Spec_traverse need to include Spec->_basesJason Madden2020-09-282-0/+31
| | | | | | | | | | | | Previously they did not, leading to a reference leak of a tuple. Fixes #216
* | Use queryDirectTaggedValue to find invariants removes the need to keep track ↵Jan-Jaap Driessen2020-10-011-21/+13
| | | | | | | | of invariants we have already seen.
* | Use an internal method for validating invariants, so we don't taint the ↵Jan-Jaap Driessen2020-09-281-5/+6
| | | | | | | | public interface/signature.
* | When an invariant is defined in an interface, it's found byJan-Jaap Driessen2020-09-252-2/+21
|/ | | | | `validateInvariants` in all interfaces inheriting from that interface. Make sure to call each invariant only once when validating invariants.
* Fix interface definitions of IAdapterRegistry.subscribe, subscribers and ↵Jason Madden2020-04-233-78/+114
| | | | | | | | subscriptions. They were defined to accept a name argument, but the actual implementation doesn't. Add tests for this. Fixes #208. Also in test_adapter.py modernize idioms from assertTrue(x in y) and assertTrue(x is y) to assertIn and assertIs.
* Merge pull request #203 from zopefoundation/issue199Jason Madden2020-04-083-147/+246
|\ | | | | Make @implementer and classImplements not add redundant interfaces
| * Fix implementerOnly when duplicating something inherited from the parent.issue199Jason Madden2020-04-072-79/+89
| | | | | | | | | | | | Seen in plone.app.testing as a problem in Products.GenericSetup. Added tests for that.
| * Special case the base Interface in @implementer/classImplements to skip the ↵Jason Madden2020-04-073-10/+43
| | | | | | | | redundancy detection for the sake of plone.app.caching.
| * Make @implementer and classImplements not re-declare redundant interfaces.Jason Madden2020-04-072-90/+146
| | | | | | | | classImplementsOnly and @implementer_only can still be used to do that.
* | Merge pull request #205 from zopefoundation/issue204Jason Madden2020-04-072-6/+39
|\ \ | | | | | | The ImmutableDeclaration also has immutable _v_attrs.
| * | The ImmutableDeclaration also has immutable _v_attrs.issue204Jason Madden2020-04-072-6/+39
| |/ | | | | | | Fixes #204
* | Minor cleanup of #202.issue3_minor_cleanupJason Madden2020-04-071-2/+11
|/ | | | See https://github.com/zopefoundation/zope.interface/pull/202#pullrequestreview-389126705
* Feedback from review: whitespace, doc clarification, and a unit test showing ↵Jason Madden2020-04-074-18/+58
| | | | the precedence of __conform__ vs __adapt__.
* Let interface 'subclasses' override __adapt__.issue3Jason Madden2020-04-068-58/+312
| | | | | | | | | | | | | | | | | | | | Cooperate with InterfaceClass to ensure there is no performance penalty for this. Fixes #3 +-------------------------------------------------------------+----------------+------------------------------+------------------------------+ | Benchmark | bench_master38 | bench_issue3 | bench_issue3_opt | +=============================================================+================+==============================+==============================+ | call interface (provides; deep) | 369 ns | 454 ns: 1.23x slower (+23%) | not significant | +-------------------------------------------------------------+----------------+------------------------------+------------------------------+ | call interface (provides; wide) | 373 ns | 457 ns: 1.22x slower (+22%) | 365 ns: 1.02x faster (-2%) | +-------------------------------------------------------------+----------------+------------------------------+------------------------------+ | call interface (no alternate, no conform, not provided) | 671 ns | 760 ns: 1.13x slower (+13%) | 636 ns: 1.06x faster (-5%) | +-------------------------------------------------------------+----------------+------------------------------+------------------------------+ | call interface (alternate, no conform, not provided) | 395 ns | 494 ns: 1.25x slower (+25%) | not significant | +-------------------------------------------------------------+----------------+------------------------------+------------------------------+ | call interface (no alternate, valid conform, not provided) | 250 ns | not significant | 227 ns: 1.10x faster (-9%) | +-------------------------------------------------------------+----------------+------------------------------+------------------------------+ | call interface (alternate, invalid conform, not provided) | 348 ns | 424 ns: 1.22x slower (+22%) | not significant | +-------------------------------------------------------------+----------------+------------------------------+------------------------------+
* Add documentation for taggedValue and invariant.Jason Madden2020-04-061-0/+51
|
* Add more cross refs to documentation and fix a couple sphinx warnings about ↵Jason Madden2020-04-061-42/+98
| | | | duplicates in the index.
* MS VS stuck on c89 strikes again.Jason Madden2020-04-021-1/+1
|
* Remove the bare except: statements.Jason Madden2020-04-027-193/+384
| | | | | | | | Only catch AttributeError instead of everything. Fixes #200 Note that this does break a doctest in five.intid (it's expecting a TypeError but it now gets Acquisition's RuntimeError).
* Ensure that objects that implement no interfaces still have Interface in ↵Jason Madden2020-03-303-12/+54
| | | | | | their iro and sro. Fixes #197.
* Make the RO for InterfaceClass consistent and fix handling of the STRICT_IRO ↵issue192-issue194Jason Madden2020-03-206-25/+78
| | | | | | | | env variable. Fixes #192 and fixes #194. Also fix the IRO for OrderedDict on CPython 2
* Another comment update, referencing #163Jason Madden2020-03-191-2/+7
|
* Update comments and add a test for more coverage.Jason Madden2020-03-193-52/+104
|
* Remove untested except in the metaclass __new__.faster-eq-hash-comparisonJason Madden2020-03-181-7/+5
| | | | Reviewers weren't sure how it could be raised.
* Add additional tests for assigning to Interface.__module__.Jason Madden2020-03-181-0/+7
|
* Add tests for comparing InterfaceClass/Implements objects to things without ↵Jason Madden2020-03-184-14/+142
| | | | | | the required attributes. And fix the C handling of this case.
* Several small tweaks to GC and deletion handling.Jason Madden2020-03-181-5/+11
| | | | Several places needed to, essentially, call super.
* Move to a metaclass for handling __module__.Jason Madden2020-03-181-62/+108
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This offers the absolute best performance at what seems like reasonable complexity. +-------------------------------------------------------------+----------------+-------------------------------+ | Benchmark | 38-master-full | 38-faster-meta | +=============================================================+================+===============================+ | read __module__ | 41.8 ns | 40.9 ns: 1.02x faster (-2%) | +-------------------------------------------------------------+----------------+-------------------------------+ | read __name__ | 41.8 ns | 39.9 ns: 1.05x faster (-5%) | +-------------------------------------------------------------+----------------+-------------------------------+ | read providedBy | 56.9 ns | 58.4 ns: 1.03x slower (+3%) | +-------------------------------------------------------------+----------------+-------------------------------+ | query adapter (no registrations) | 3.85 ms | 2.95 ms: 1.31x faster (-24%) | +-------------------------------------------------------------+----------------+-------------------------------+ | query adapter (all trivial registrations) | 4.62 ms | 3.63 ms: 1.27x faster (-21%) | +-------------------------------------------------------------+----------------+-------------------------------+ | query adapter (all trivial registrations, wide inheritance) | 51.8 us | 42.2 us: 1.23x faster (-19%) | +-------------------------------------------------------------+----------------+-------------------------------+ | query adapter (all trivial registrations, deep inheritance) | 52.0 us | 41.7 us: 1.25x faster (-20%) | +-------------------------------------------------------------+----------------+-------------------------------+ | sort interfaces | 234 us | 29.9 us: 7.84x faster (-87%) | +-------------------------------------------------------------+----------------+-------------------------------+ | sort mixed | 569 us | 340 us: 1.67x faster (-40%) | +-------------------------------------------------------------+----------------+-------------------------------+ | contains (empty dict) | 135 ns | 55.2 ns: 2.44x faster (-59%) | +-------------------------------------------------------------+----------------+-------------------------------+ | contains (populated dict: interfaces) | 137 ns | 56.1 ns: 2.45x faster (-59%) | +-------------------------------------------------------------+----------------+-------------------------------+ | contains (populated list: interfaces) | 39.7 us | 2.96 us: 13.42x faster (-93%) | +-------------------------------------------------------------+----------------+-------------------------------+ | contains (populated dict: implementedBy) | 137 ns | 55.2 ns: 2.48x faster (-60%) | +-------------------------------------------------------------+----------------+-------------------------------+ | contains (populated list: implementedBy) | 40.6 us | 24.1 us: 1.68x faster (-41%) | +-------------------------------------------------------------+----------------+-------------------------------+ Not significant (2): read __doc__; sort implementedBy
* Use a descriptor for __module__Jason Madden2020-03-184-48/+83
| | | | | | | | | | | | | | | | | | | | | | | | | | | This makes the rest of the attribute access fast again, but slows down __module__. +-------------------------------------------+------------+-------------------------------+ | Benchmark | 38-master3 | 38-faster-descr | +===========================================+============+===============================+ | read __module__ | 41.1 ns | 123 ns: 2.99x slower (+199%) | +-------------------------------------------+------------+-------------------------------+ | read __name__ | 41.3 ns | 39.9 ns: 1.04x faster (-3%) | +-------------------------------------------+------------+-------------------------------+ | read __doc__ | 41.8 ns | 42.4 ns: 1.01x slower (+1%) | +-------------------------------------------+------------+-------------------------------+ | query adapter (no registrations) | 3.85 ms | 2.95 ms: 1.30x faster (-23%) | +-------------------------------------------+------------+-------------------------------+ | query adapter (all trivial registrations) | 4.59 ms | 3.67 ms: 1.25x faster (-20%) | +-------------------------------------------+------------+-------------------------------+ | contains (empty dict) | 136 ns | 54.8 ns: 2.48x faster (-60%) | +-------------------------------------------+------------+-------------------------------+ | contains (populated dict) | 137 ns | 55.7 ns: 2.46x faster (-59%) | +-------------------------------------------+------------+-------------------------------+ | contains (populated list) | 40.2 us | 2.86 us: 14.03x faster (-93%) | +-------------------------------------------+------------+-------------------------------+ Not significant (1): read providedBy
* Avoid use of a metaclass by implementeng __getattribute__.Jason Madden2020-03-184-212/+221
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This is pretty, but it slows down all attribute access to interfaces. By up to 25%. I'm not sure that's acceptable for things like Interface.providedBy. +-------------------------------------------+------------+-------------------------------+ | Benchmark | 38-master3 | 38-faster3 | +===========================================+============+===============================+ | read __module__ | 41.1 ns | 44.3 ns: 1.08x slower (+8%) | +-------------------------------------------+------------+-------------------------------+ | read __name__ | 41.3 ns | 51.6 ns: 1.25x slower (+25%) | +-------------------------------------------+------------+-------------------------------+ | read __doc__ | 41.8 ns | 53.3 ns: 1.28x slower (+28%) | +-------------------------------------------+------------+-------------------------------+ | read providedBy | 56.7 ns | 71.6 ns: 1.26x slower (+26%) | +-------------------------------------------+------------+-------------------------------+ | query adapter (no registrations) | 3.85 ms | 2.95 ms: 1.31x faster (-23%) | +-------------------------------------------+------------+-------------------------------+ | query adapter (all trivial registrations) | 4.59 ms | 3.65 ms: 1.26x faster (-20%) | +-------------------------------------------+------------+-------------------------------+ | contains (empty dict) | 136 ns | 55.4 ns: 2.45x faster (-59%) | +-------------------------------------------+------------+-------------------------------+ | contains (populated dict) | 137 ns | 55.0 ns: 2.49x faster (-60%) | +-------------------------------------------+------------+-------------------------------+ | contains (populated list) | 40.2 us | 2.95 us: 13.62x faster (-93%) | +-------------------------------------------+------------+-------------------------------+
* Fix tests when zope.component is also importable.Jason Madden2020-03-182-1/+24
|
* Clean up linter errors in test_interface.py so new/real problems are more ↵Jason Madden2020-03-181-41/+52
| | | | obvious.
* Fix doctest by making sure the default type repr can be used.Jason Madden2020-03-181-2/+16
|
* Move Interface hashing and comparison to C; 2.5 to 15x speedup in micro ↵Jason Madden2020-03-184-74/+318
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | benchmarks Included benchmark numbers: Current master, Python 3.8: ..................... contains (empty dict): Mean +- std dev: 198 ns +- 5 ns ..................... contains (populated dict): Mean +- std dev: 197 ns +- 6 ns ..................... contains (populated list): Mean +- std dev: 53.1 us +- 1.2 us This code: ..................... contains (empty dict): Mean +- std dev: 77.9 ns +- 2.3 ns ..................... contains (populated dict): Mean +- std dev: 78.4 ns +- 3.1 ns ..................... contains (populated list): Mean +- std dev: 3.69 us +- 0.08 us So anywhere from 2.5 to 15x faster. Not sure how that will translate to larger benchmarks, but I'm hopeful. It turns out that messing with ``__module__`` is nasty, tricky business, especially when you do it from C. Everytime you define a new subclass, the descriptors that you set get overridden by the type machinery (PyType_Ready). I'm using a data descriptor and a meta class right now to avoid that but I'm not super happy with that and would like to find a better way. (At least, maybe the data part of the descriptor isn't necessary?) It may be needed to move more code into C, I don't want a slowdown accessing ``__module__`` either; copying around the standard PyGetSet or PyMember descriptors isn't enough because they don't work on the class object (so ``classImplements(InterfaceClass, IInterface)`` fails).
* Move the one-base optimization down a level, and enable using pre-calculated ↵Jason Madden2020-03-183-33/+84
| | | | | | | | __sro__ for caching. In my local 'load the world' test, this went from ~7800 full C3 merges to about ~1100. Also take steps to avoid triggering false positive warnings about changed ROs when it's *just* Interface that moved.
* Ensure Interface is the last item in the __sro__.Jason Madden2020-03-183-21/+131
| | | | | | None of the elegant solutions mentioned in the issue worked out, so I had to brute force it. Fixes #8
* Merge pull request #189 from zopefoundation/issue136-issue134Jason Madden2020-03-181-2/+2
|\ | | | | Documentation clarifications.
| * Documentation clarifications.issue136-issue134Jason Madden2020-03-171-2/+2
| | | | | | | | | | | | | | | | | | - docs/adapter.rst Subscriptions are returned from least to most specific, not the other way around; the docs were incorrect. Add additional examples, and use more verbose names in current examples, to clarify this. Fixes #136. - interfaces.py names() and namesAndDescriptions() just return a collection, not a sequence. Fixes #134.
* | More minor documentation fixups.issue190Jason Madden2020-03-181-12/+13
| | | | | | | | Mostly formatting. Some interfaces were being documented as clasess, which doesn't work.
* | Make Interface.getTaggedValue follow the __iro__.Jason Madden2020-03-183-28/+203
|/ | | | | | | | Previously it manually walked up __bases__, meaning the answers could be inconsistent. Fixes #190. Also fixes several minor issues in the documentation, mostly cross-reference related.
* Use C3 (mostly) to compute IRO.issue21Jason Madden2020-03-1515-54/+1001
| | | | | | | | | | | | | | | | | | | | | | | | Fixes #21 The 'mostly' is because interfaces are used in cases that C3 forbids; when there's a conflict, we fallback to the legacy algorithm. It turns out there are few conflicts (13K out of 149K total orderings in Plone). I hoped the fix for #8 might shake out automatically, but it didn't. Optimize the extremely common case of a __bases__ of length one. In the benchmark, 4/5 of the interfaces and related objects have a base of length one. Fix the bad IROs in the bundled ABC interfaces, and implement a way to get warnings or errors. In running plone/buildout.coredev and tracking the RO requests, the stats for equal, not equal, and inconsistent-so-fallback, I got {'ros': 148868, 'eq': 138461, 'ne': 10407, 'inconsistent': 12934} Add the interface module to the Attribute str. This was extremely helpful tracking down the Plone problem; IDate is defined in multiple modules.
* Add additional low-level tests for super() unwrapping.Jason Madden2020-03-101-1/+38
|
* Remove unused str variablesJason Madden2020-03-101-15/+8
| | | | | The DEFINE_STRING macro prevents the linter from seeing them as unused so I temporarily redefined it to find all such variables.
* Make provided/implementedBy and adapter registries respect super().issue11Jason Madden2020-03-095-45/+647
| | | | | | | | | | | | | | | | | | | | | | | | The query functions now start by looking at the next class in the MRO (interfaces directly provided by the underlying object are not found). Adapter registries automatically pick up providedBy change to start finding the correct implementations of adapters, but to make that really useful they needed to change to unpack super() arguments and pass __self__ to the factory. Fixes #11 Unfortunately, this makes PyPy unable to build the C extensions. Additional crash-safety for adapter lookup. Make the C functions get the cache only after resolving the ``required`` into a tuple, in case of side-effects like...clearing the cache. This could lead to the ``cache`` object being deallocated before we used it. Drop the ``tuplefy`` function in favor of a direct call to ``PySequence_Tuple``. It's what the ``tuple`` constructor would do anyway and saves a few steps. Make sure that getting ``providedBy(super())`` and ``implementedBy(super())`` have no side effects.
* Cleanups per review.issue138Jason Madden2020-02-175-41/+34
|
* Update documentation and clarify the relationship of the older mapping and ↵Jason Madden2020-02-177-49/+158
| | | | sequence interfaces.
* Do not test _WindowsConsoleIOJason Madden2020-02-171-1/+1
|
* Find more concrete classes that are registered.Jason Madden2020-02-175-15/+41
|