| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
the precedence of __conform__ vs __adapt__.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 |
+-------------------------------------------------------------+----------------+------------------------------+------------------------------+
|
| |
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
| |
their iro and sro.
Fixes #197.
|
| |
|
|
|
|
|
|
| |
env variable.
Fixes #192 and fixes #194.
Also fix the IRO for OrderedDict on CPython 2
|
| | |
|
| | |
|
| |
|
|
| |
Reviewers weren't sure how it could be raised.
|
| |
|
|
|
|
| |
the required attributes.
And fix the C handling of this case.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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%) |
+-------------------------------------------+------------+-------------------------------+
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
| |
__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.
|
| |
|
|
|
|
| |
None of the elegant solutions mentioned in the issue worked out, so I had to brute force it.
Fixes #8
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
| |
and as usual in Python.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Eliminate the trailing newlines and blank spaces (the code called them
"a stupid artifact").
Include the name of the defining interface (so the user can easily look up
any requirements on the attribute) and, for methods, the expected
signature (no more guessing about how many arguments are required!).
This is implemented by giving Attribute and Method useful reprs and strs.
Previously, they just had the defaults.
Fixes #170
|
| |
|
|
|
|
|
|
|
| |
on Pypy
On PyPy2, they are ignored (like on CPython), but on PyPy3 they can
actually be validated.
Fixes #118
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fixes #153
The items that went in each ``__all__`` are based on what is
documented:
$ rg --no-filename 'import' docs/ -trst | tr -s "[:blank:]" | sort | uniq | grep zope
>>> from pprint import pprint
>>> from zope.interface import *
>>> from zope.interface import Interface
>>> from zope.interface import Interface, Attribute, implementer
>>> from zope.interface import alsoProvides
>>> from zope.interface import classImplements
>>> from zope.interface import classImplementsOnly
>>> from zope.interface import directlyProvidedBy
>>> from zope.interface import directlyProvides
>>> from zope.interface import implementedBy
>>> from zope.interface import implementer
>>> from zope.interface import implementer_only
>>> from zope.interface import noLongerProvides
>>> from zope.interface import providedBy
>>> from zope.interface import provider
>>> from zope.interface.adapter import AdapterRegistry
>>> from zope.interface.declarations import Declaration
>>> from zope.interface.declarations import InstanceDeclarations
>>> from zope.interface.declarations import ProvidesClass
>>> from zope.interface.declarations import named
>>> from zope.interface.exceptions import BrokenImplementation
>>> from zope.interface.exceptions import Invalid
>>> from zope.interface.interface import Specification
>>> from zope.interface.interface import adapter_hooks
>>> from zope.interface.verify import verifyObject
>>> import gc
>>> import zope.interface
And also some personal judgement about what the public API is that I'm
more than happy to have reviewed.
|
| |
|
|
|
|
|
|
| |
Turns out they can be called in some very strange error cases. See #162 and #163 for details.
This should fix #162 (at least the provided test case, five.intid, passes now).
It also does enough work on #163 that (a) the test can be written and run in pure-python mode, which was needed to debug it and (b) five.intid runs in pure-python mode (well, with a bunch of other small hacks to Acquisition, ExtensionClass, DocumentTemplate and AccessControl), but I won't claim that it fully fixes #163. For one thing, there are no specific tests. For another, I see more such differences.
|
| |
|
|
| |
Fixes #157
|
| |
|
|
| |
another few percent.
|
| |
|
|
|
|
| |
example), so avoid allocating a WeakKeyDictionary until needed.
This saves another 2% or so.
|
| |
|
|
| |
In a test of 6000 modules that load 2245 InterfaceClass objects and produce 2233 ClassProvides instances, this saves about 1% total memory usage in Python 2.7.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Instead of storing 1 and 2 attributes, respectively, in __dict__. This lets us eliminate inst_attr and its use of an undocumented API.
It also helps reign in the size of these objects. Before, on CPython 8, a ClassProvides object that subclasses both SpecificationBase and ClassProvidesBase required 408 bytes: 48 for the object, 360 for the dict.
Now it requires 72 + 232 = 304.
With a bit of work on defining __slots__ in Python, that can be brought much lower still, I think.
zope.security tests pass with this installed.
|
| |
|
|
|
|
|
| |
Turns out that the C extensions build and work fine with PyPy, but don't use them by default. Let them
be forced, though.
Tests needed some refactoring to account for the various permutations.
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
| |
Fixes #91
Remove many (or most) now-redundant 'pragma: no cover'.
A few minor test changes to get full branch coverage.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Get as close to 100% coverage as possible.
Without conflicting with #86.
This is almost entirely trivial changes:
- Make dummy methods that should never be called either raise
NotImplementedError or call self.fail() in tests.
- Standardize the no-coverage pragma
- Add a few pragmas where coverage varies across
versions/implementations, mostly for the sake of tox (travis should
hit them all).
* Convert tox to run the coverage command, like travis. A follow up should have it produce coverage for all python versions/implementations.
Fixes #87
* Adjust coverage config for py2 only tests; fix typo; finish replacing self with cls
|
| |
|
|
|
|
|
|
|
|
| |
- The bare import of '_zope_c_optimizations' prevented them from being
used.
- After enabling them via absolute imports, they would fail due to
http://bugs.python.org/issue15657.
Fixes #60.
|
| |
|
|
| |
Fixes #42
|
| |
|
|
|
|
| |
We exclude interfaces declared with the 'class' statement, because their
methods typically have only a doctstring in the suite, which confuses
the branch coverage machinery.
|
| | |
|
| |
|
|
| |
loop body modified a weakref dict causing a ``RuntimeError`` error
|
| | |
|
| |
|
|
|
| |
'__code__', '__defaults__', '__func__', and '__self__' all work fine on
Python 2.6+.
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
See PEP 3155 for rationale. Thanks to Antoine Pitrou for the patch.
Fixes LP #900906.
|
| |
|
|
|
|
|
|
|
| |
Some sublcasses invoke '__hash__' before initializing '__module__' and
'__name__'. The workaround returns a fixed constant hash in such cases, and
issues a UserWarning.
Addresses LP #811792.
|
| | |
|