Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update repr() and str() of some common objects. #237

Merged
merged 1 commit into from Mar 29, 2021
Merged

Conversation

jamadden
Copy link
Member

Only InterfaceClass got a str, so it now has a distinction. Other objects only got updated reprs.

Note: This may potentially break some doctests.

In many cases, the repr() is now something that can be evaluated to produce an equal object. For example, what was previously printed as <implementedBy builtins.list> is now shown as classImplements(list, IMutableSequence, IIterable).

Fixes #236

Here's a before with ZOPE_INTERFACE_LOG_CHANGED_IRO=1 in BTrees:

Object <implementedBy builtins.list> has different legacy and C3 MROs:
  Legacy RO (len=11)                                                        C3 RO (len=11; inconsistent=no)
  ==================================================================================================================================================
    <implementedBy builtins.list>                                             <implementedBy builtins.list>
    <ABCInterfaceClass zope.interface.common.collections.IMutableSequence>    <ABCInterfaceClass zope.interface.common.collections.IMutableSequence>
    <ABCInterfaceClass zope.interface.common.collections.ISequence>           <ABCInterfaceClass zope.interface.common.collections.ISequence>
    <ABCInterfaceClass zope.interface.common.collections.IReversible>         <ABCInterfaceClass zope.interface.common.collections.IReversible>
    <ABCInterfaceClass zope.interface.common.collections.ICollection>         <ABCInterfaceClass zope.interface.common.collections.ICollection>
    <ABCInterfaceClass zope.interface.common.collections.ISized>              <ABCInterfaceClass zope.interface.common.collections.ISized>
                                                                            + <ABCInterfaceClass zope.interface.common.collections.IIterable>
    <ABCInterfaceClass zope.interface.common.collections.IContainer>          <ABCInterfaceClass zope.interface.common.collections.IContainer>
  - <ABCInterfaceClass zope.interface.common.collections.IIterable>
    <ABCInterfaceClass zope.interface.common.ABCInterface>                    <ABCInterfaceClass zope.interface.common.ABCInterface>
                                                                            + <implementedBy builtins.object>
    <InterfaceClass zope.interface.Interface>                                 <InterfaceClass zope.interface.Interface>
  - <implementedBy builtins.object>
Object <ABCInterfaceClass zope.interface.common.mapping.IFullMapping> has different legacy and C3 MROs:
  Legacy RO (len=18)                                                       C3 RO (len=18; inconsistent=no)
  ================================================================================================================================================
    <ABCInterfaceClass zope.interface.common.mapping.IFullMapping>           <ABCInterfaceClass zope.interface.common.mapping.IFullMapping>
    <ABCInterfaceClass zope.interface.common.collections.IMutableMapping>    <ABCInterfaceClass zope.interface.common.collections.IMutableMapping>
    <ABCInterfaceClass zope.interface.common.collections.IMapping>           <ABCInterfaceClass zope.interface.common.collections.IMapping>
    <ABCInterfaceClass zope.interface.common.collections.ICollection>        <ABCInterfaceClass zope.interface.common.collections.ICollection>
  - <ABCInterfaceClass zope.interface.common.collections.IIterable>
    <InterfaceClass zope.interface.common.mapping.IExtendedReadMapping>      <InterfaceClass zope.interface.common.mapping.IExtendedReadMapping>
    <InterfaceClass zope.interface.common.mapping.IIterableMapping>          <InterfaceClass zope.interface.common.mapping.IIterableMapping>
    <InterfaceClass zope.interface.common.mapping.IExtendedWriteMapping>     <InterfaceClass zope.interface.common.mapping.IExtendedWriteMapping>
    <InterfaceClass zope.interface.common.mapping.IClonableMapping>          <InterfaceClass zope.interface.common.mapping.IClonableMapping>
    <InterfaceClass zope.interface.common.mapping.IMapping>                  <InterfaceClass zope.interface.common.mapping.IMapping>
    <InterfaceClass zope.interface.common.mapping.IWriteMapping>             <InterfaceClass zope.interface.common.mapping.IWriteMapping>
    <InterfaceClass zope.interface.common.mapping.IEnumerableMapping>        <InterfaceClass zope.interface.common.mapping.IEnumerableMapping>
    <ABCInterfaceClass zope.interface.common.collections.ISized>             <ABCInterfaceClass zope.interface.common.collections.ISized>
                                                                           + <ABCInterfaceClass zope.interface.common.collections.IIterable>
    <InterfaceClass zope.interface.common.mapping.IReadMapping>              <InterfaceClass zope.interface.common.mapping.IReadMapping>
    <ABCInterfaceClass zope.interface.common.collections.IContainer>         <ABCInterfaceClass zope.interface.common.collections.IContainer>
    <ABCInterfaceClass zope.interface.common.ABCInterface>                   <ABCInterfaceClass zope.interface.common.ABCInterface>
    <InterfaceClass zope.interface.common.mapping.IItemMapping>              <InterfaceClass zope.interface.common.mapping.IItemMapping>
    <InterfaceClass zope.interface.Interface>                                <InterfaceClass zope.interface.Interface>
Object <InterfaceClass BTrees.Interfaces.ISet> has different legacy and C3 MROs:
  Legacy RO (len=7)                                  C3 RO (len=7; inconsistent=no)
  ====================================================================================================
    <InterfaceClass BTrees.Interfaces.ISet>            <InterfaceClass BTrees.Interfaces.ISet>
    <InterfaceClass BTrees.Interfaces.IKeySequence>    <InterfaceClass BTrees.Interfaces.IKeySequence>
  - <InterfaceClass BTrees.Interfaces.ISized>
    <InterfaceClass BTrees.Interfaces.ISetMutable>     <InterfaceClass BTrees.Interfaces.ISetMutable>
    <InterfaceClass BTrees.Interfaces.IKeyed>          <InterfaceClass BTrees.Interfaces.IKeyed>
    <InterfaceClass BTrees.Interfaces.ICollection>     <InterfaceClass BTrees.Interfaces.ICollection>
                                                     + <InterfaceClass BTrees.Interfaces.ISized>
    <InterfaceClass zope.interface.Interface>          <InterfaceClass zope.interface.Interface>

And here's after:

Object classImplements(list, IMutableSequence, IIterable) has different legacy and C3 MROs:
  Legacy RO (len=11)                                    C3 RO (len=11; inconsistent=no)
  ==========================================================================================================
    classImplements(list, IMutableSequence, IIterable)    classImplements(list, IMutableSequence, IIterable)
    zope.interface.common.collections.IMutableSequence    zope.interface.common.collections.IMutableSequence
    zope.interface.common.collections.ISequence           zope.interface.common.collections.ISequence
    zope.interface.common.collections.IReversible         zope.interface.common.collections.IReversible
    zope.interface.common.collections.ICollection         zope.interface.common.collections.ICollection
    zope.interface.common.collections.ISized              zope.interface.common.collections.ISized
                                                        + zope.interface.common.collections.IIterable
    zope.interface.common.collections.IContainer          zope.interface.common.collections.IContainer
  - zope.interface.common.collections.IIterable
    zope.interface.common.ABCInterface                    zope.interface.common.ABCInterface
                                                        + classImplements(object)
    zope.interface.Interface                              zope.interface.Interface
  - classImplements(object)
Object <ABCInterfaceClass zope.interface.common.mapping.IFullMapping> has different legacy and C3 MROs:
  Legacy RO (len=18)                                     C3 RO (len=18; inconsistent=no)
  ============================================================================================================
    zope.interface.common.mapping.IFullMapping             zope.interface.common.mapping.IFullMapping
    zope.interface.common.collections.IMutableMapping      zope.interface.common.collections.IMutableMapping
    zope.interface.common.collections.IMapping             zope.interface.common.collections.IMapping
    zope.interface.common.collections.ICollection          zope.interface.common.collections.ICollection
  - zope.interface.common.collections.IIterable
    zope.interface.common.mapping.IExtendedReadMapping     zope.interface.common.mapping.IExtendedReadMapping
    zope.interface.common.mapping.IIterableMapping         zope.interface.common.mapping.IIterableMapping
    zope.interface.common.mapping.IExtendedWriteMapping    zope.interface.common.mapping.IExtendedWriteMapping
    zope.interface.common.mapping.IClonableMapping         zope.interface.common.mapping.IClonableMapping
    zope.interface.common.mapping.IMapping                 zope.interface.common.mapping.IMapping
    zope.interface.common.mapping.IWriteMapping            zope.interface.common.mapping.IWriteMapping
    zope.interface.common.mapping.IEnumerableMapping       zope.interface.common.mapping.IEnumerableMapping
    zope.interface.common.collections.ISized               zope.interface.common.collections.ISized
                                                         + zope.interface.common.collections.IIterable
    zope.interface.common.mapping.IReadMapping             zope.interface.common.mapping.IReadMapping
    zope.interface.common.collections.IContainer           zope.interface.common.collections.IContainer
    zope.interface.common.ABCInterface                     zope.interface.common.ABCInterface
    zope.interface.common.mapping.IItemMapping             zope.interface.common.mapping.IItemMapping
    zope.interface.Interface                               zope.interface.Interface
Object <InterfaceClass BTrees.Interfaces.ISet> has different legacy and C3 MROs:
  Legacy RO (len=7)                 C3 RO (len=7; inconsistent=no)
  ==================================================================
    BTrees.Interfaces.ISet            BTrees.Interfaces.ISet
    BTrees.Interfaces.IKeySequence    BTrees.Interfaces.IKeySequence
  - BTrees.Interfaces.ISized
    BTrees.Interfaces.ISetMutable     BTrees.Interfaces.ISetMutable
    BTrees.Interfaces.IKeyed          BTrees.Interfaces.IKeyed
    BTrees.Interfaces.ICollection     BTrees.Interfaces.ICollection
                                    + BTrees.Interfaces.ISized
    zope.interface.Interface          zope.interface.Interface

Only InterfaceClass got a str, so it now has a distinction. Other objects only got updated reprs.

Note: This may potentially break some doctests.

In many cases, the ``repr()`` is now something that can be evaluated
to produce an equal object. For example, what was previously printed
as ``<implementedBy builtins.list>`` is now shown as
``classImplements(list, IMutableSequence, IIterable)``.

Fixes #236

Here's a before with ZOPE_INTERFACE_LOG_CHANGED_IRO=1 in BTrees:
```
Object <implementedBy builtins.list> has different legacy and C3 MROs:
  Legacy RO (len=11)                                                        C3 RO (len=11; inconsistent=no)
  ==================================================================================================================================================
    <implementedBy builtins.list>                                             <implementedBy builtins.list>
    <ABCInterfaceClass zope.interface.common.collections.IMutableSequence>    <ABCInterfaceClass zope.interface.common.collections.IMutableSequence>
    <ABCInterfaceClass zope.interface.common.collections.ISequence>           <ABCInterfaceClass zope.interface.common.collections.ISequence>
    <ABCInterfaceClass zope.interface.common.collections.IReversible>         <ABCInterfaceClass zope.interface.common.collections.IReversible>
    <ABCInterfaceClass zope.interface.common.collections.ICollection>         <ABCInterfaceClass zope.interface.common.collections.ICollection>
    <ABCInterfaceClass zope.interface.common.collections.ISized>              <ABCInterfaceClass zope.interface.common.collections.ISized>
                                                                            + <ABCInterfaceClass zope.interface.common.collections.IIterable>
    <ABCInterfaceClass zope.interface.common.collections.IContainer>          <ABCInterfaceClass zope.interface.common.collections.IContainer>
  - <ABCInterfaceClass zope.interface.common.collections.IIterable>
    <ABCInterfaceClass zope.interface.common.ABCInterface>                    <ABCInterfaceClass zope.interface.common.ABCInterface>
                                                                            + <implementedBy builtins.object>
    <InterfaceClass zope.interface.Interface>                                 <InterfaceClass zope.interface.Interface>
  - <implementedBy builtins.object>
Object <ABCInterfaceClass zope.interface.common.mapping.IFullMapping> has different legacy and C3 MROs:
  Legacy RO (len=18)                                                       C3 RO (len=18; inconsistent=no)
  ================================================================================================================================================
    <ABCInterfaceClass zope.interface.common.mapping.IFullMapping>           <ABCInterfaceClass zope.interface.common.mapping.IFullMapping>
    <ABCInterfaceClass zope.interface.common.collections.IMutableMapping>    <ABCInterfaceClass zope.interface.common.collections.IMutableMapping>
    <ABCInterfaceClass zope.interface.common.collections.IMapping>           <ABCInterfaceClass zope.interface.common.collections.IMapping>
    <ABCInterfaceClass zope.interface.common.collections.ICollection>        <ABCInterfaceClass zope.interface.common.collections.ICollection>
  - <ABCInterfaceClass zope.interface.common.collections.IIterable>
    <InterfaceClass zope.interface.common.mapping.IExtendedReadMapping>      <InterfaceClass zope.interface.common.mapping.IExtendedReadMapping>
    <InterfaceClass zope.interface.common.mapping.IIterableMapping>          <InterfaceClass zope.interface.common.mapping.IIterableMapping>
    <InterfaceClass zope.interface.common.mapping.IExtendedWriteMapping>     <InterfaceClass zope.interface.common.mapping.IExtendedWriteMapping>
    <InterfaceClass zope.interface.common.mapping.IClonableMapping>          <InterfaceClass zope.interface.common.mapping.IClonableMapping>
    <InterfaceClass zope.interface.common.mapping.IMapping>                  <InterfaceClass zope.interface.common.mapping.IMapping>
    <InterfaceClass zope.interface.common.mapping.IWriteMapping>             <InterfaceClass zope.interface.common.mapping.IWriteMapping>
    <InterfaceClass zope.interface.common.mapping.IEnumerableMapping>        <InterfaceClass zope.interface.common.mapping.IEnumerableMapping>
    <ABCInterfaceClass zope.interface.common.collections.ISized>             <ABCInterfaceClass zope.interface.common.collections.ISized>
                                                                           + <ABCInterfaceClass zope.interface.common.collections.IIterable>
    <InterfaceClass zope.interface.common.mapping.IReadMapping>              <InterfaceClass zope.interface.common.mapping.IReadMapping>
    <ABCInterfaceClass zope.interface.common.collections.IContainer>         <ABCInterfaceClass zope.interface.common.collections.IContainer>
    <ABCInterfaceClass zope.interface.common.ABCInterface>                   <ABCInterfaceClass zope.interface.common.ABCInterface>
    <InterfaceClass zope.interface.common.mapping.IItemMapping>              <InterfaceClass zope.interface.common.mapping.IItemMapping>
    <InterfaceClass zope.interface.Interface>                                <InterfaceClass zope.interface.Interface>
Object <InterfaceClass BTrees.Interfaces.ISet> has different legacy and C3 MROs:
  Legacy RO (len=7)                                  C3 RO (len=7; inconsistent=no)
  ====================================================================================================
    <InterfaceClass BTrees.Interfaces.ISet>            <InterfaceClass BTrees.Interfaces.ISet>
    <InterfaceClass BTrees.Interfaces.IKeySequence>    <InterfaceClass BTrees.Interfaces.IKeySequence>
  - <InterfaceClass BTrees.Interfaces.ISized>
    <InterfaceClass BTrees.Interfaces.ISetMutable>     <InterfaceClass BTrees.Interfaces.ISetMutable>
    <InterfaceClass BTrees.Interfaces.IKeyed>          <InterfaceClass BTrees.Interfaces.IKeyed>
    <InterfaceClass BTrees.Interfaces.ICollection>     <InterfaceClass BTrees.Interfaces.ICollection>
                                                     + <InterfaceClass BTrees.Interfaces.ISized>
    <InterfaceClass zope.interface.Interface>          <InterfaceClass zope.interface.Interface>
```

And here's after:

```
Object classImplements(list, IMutableSequence, IIterable) has different legacy and C3 MROs:
  Legacy RO (len=11)                                    C3 RO (len=11; inconsistent=no)
  ==========================================================================================================
    classImplements(list, IMutableSequence, IIterable)    classImplements(list, IMutableSequence, IIterable)
    zope.interface.common.collections.IMutableSequence    zope.interface.common.collections.IMutableSequence
    zope.interface.common.collections.ISequence           zope.interface.common.collections.ISequence
    zope.interface.common.collections.IReversible         zope.interface.common.collections.IReversible
    zope.interface.common.collections.ICollection         zope.interface.common.collections.ICollection
    zope.interface.common.collections.ISized              zope.interface.common.collections.ISized
                                                        + zope.interface.common.collections.IIterable
    zope.interface.common.collections.IContainer          zope.interface.common.collections.IContainer
  - zope.interface.common.collections.IIterable
    zope.interface.common.ABCInterface                    zope.interface.common.ABCInterface
                                                        + classImplements(object)
    zope.interface.Interface                              zope.interface.Interface
  - classImplements(object)
Object <ABCInterfaceClass zope.interface.common.mapping.IFullMapping> has different legacy and C3 MROs:
  Legacy RO (len=18)                                     C3 RO (len=18; inconsistent=no)
  ============================================================================================================
    zope.interface.common.mapping.IFullMapping             zope.interface.common.mapping.IFullMapping
    zope.interface.common.collections.IMutableMapping      zope.interface.common.collections.IMutableMapping
    zope.interface.common.collections.IMapping             zope.interface.common.collections.IMapping
    zope.interface.common.collections.ICollection          zope.interface.common.collections.ICollection
  - zope.interface.common.collections.IIterable
    zope.interface.common.mapping.IExtendedReadMapping     zope.interface.common.mapping.IExtendedReadMapping
    zope.interface.common.mapping.IIterableMapping         zope.interface.common.mapping.IIterableMapping
    zope.interface.common.mapping.IExtendedWriteMapping    zope.interface.common.mapping.IExtendedWriteMapping
    zope.interface.common.mapping.IClonableMapping         zope.interface.common.mapping.IClonableMapping
    zope.interface.common.mapping.IMapping                 zope.interface.common.mapping.IMapping
    zope.interface.common.mapping.IWriteMapping            zope.interface.common.mapping.IWriteMapping
    zope.interface.common.mapping.IEnumerableMapping       zope.interface.common.mapping.IEnumerableMapping
    zope.interface.common.collections.ISized               zope.interface.common.collections.ISized
                                                         + zope.interface.common.collections.IIterable
    zope.interface.common.mapping.IReadMapping             zope.interface.common.mapping.IReadMapping
    zope.interface.common.collections.IContainer           zope.interface.common.collections.IContainer
    zope.interface.common.ABCInterface                     zope.interface.common.ABCInterface
    zope.interface.common.mapping.IItemMapping             zope.interface.common.mapping.IItemMapping
    zope.interface.Interface                               zope.interface.Interface
Object <InterfaceClass BTrees.Interfaces.ISet> has different legacy and C3 MROs:
  Legacy RO (len=7)                 C3 RO (len=7; inconsistent=no)
  ==================================================================
    BTrees.Interfaces.ISet            BTrees.Interfaces.ISet
    BTrees.Interfaces.IKeySequence    BTrees.Interfaces.IKeySequence
  - BTrees.Interfaces.ISized
    BTrees.Interfaces.ISetMutable     BTrees.Interfaces.ISetMutable
    BTrees.Interfaces.IKeyed          BTrees.Interfaces.IKeyed
    BTrees.Interfaces.ICollection     BTrees.Interfaces.ICollection
                                    + BTrees.Interfaces.ISized
    zope.interface.Interface          zope.interface.Interface
```
@jensens
Copy link
Member

jensens commented Mar 25, 2021

Without trying it, this may break some of my beloved (attention sarcasm) doctests in Plone. But if so we just need to fix those. So +1 for the change.

@jamadden
Copy link
Member Author

Without trying it, this may break some of my beloved (attention sarcasm) doctests in Plone. But if so we just need to fix those.

I wrote that this "may potentially break some doctests." It's pretty certain that it will. In zopetoolkit, there are two packages that are broken:

  • test-ztk-zope.mimetype
  • test-ztk-zope.publisher

Both are due to the change from str(iface) printing <InterfaceClass module.IFace> to just module.IFace. zope.publisher could be "fixed" by changing skinnable.py to use %r instead of %s in the error message "Skin interface %s doesn't provide ISkinType". A similar change applies to event.rst in zope.mimetype; instead of print(…, interface) it can do print(…, repr(interface)). Or both could just adapt the tests (that would mean a dependency on the new version).

Other than that, I'm aware of two potential problems; I went in a particular direction with these changes and I'd like to specifically highlight them for comments.

Continuing with the issue of doctests, a subtle change is that, for example, the output of implementedBy() is not "stable"; by which I mean, it changes depending on what the object implements. For users and people debugging, I think this is good. For doctests, this could be bad, because if someone, somewhere, writes classImplements(ClassUnderTest, ISomething), doctests that aren't expecting that can break.

For example, given this:

>>> from zope.interface import *
>>> class I1(Interface):
...   pass
>>> @implementer(I1)
...    class Foo(object):
…         pass
>>> implementedBy(Foo)

Previously, you'd get <implementedBy __main__.Foo>. Now you'll get classImplements(Foo, I1). If you were to define an interface I2, and write classImplements(Foo, I2), previously you'd get...<implementedBy __main__.Foo>, but now you'll get classImplements(Foo, I1, I2). If that classImplements() is somewhere far away, it may not be obvious what the source of the issue is.

Proposed solution: take care writing doctests that print the output of implementedBy and providedBy. For example, write classImplements(Foo…) instead of listing the interfaces (unless you really want to test the exact interfaces). Hopefully this isn't too much of burden?

The second opinion this code has is that it tries to produce short output. Continuing the above example, you get classImplements(Foo, I1, I2) instead of fully qualified names like classImplements(Foo, __main__.I1, __main__.I2). If the code detects ambiguity, the second and subsequent occurrences with the same name are qualified: classImplements(Foo, ILocation, other.pkg.ILocation). Usually I'm a big fan of fully qualified names, but here I went for brevity, betting that most names are unambiguous and are easily recognizable by the developer (or if not, doing list(implementedBy(Foo).flattened()) will get fully qualified names. Does that look like the right tradeoff? Should we instead try to do something different like using short names in (to-be-implemented) __str__ methods, and qualified names in __repr__?

jamadden added a commit to zopefoundation/zope.mimetype that referenced this pull request Mar 25, 2021
Explicitly use the repr of interfaces so we can work with any version of zope.interface.

See zopefoundation/zope.interface#237 (comment)
jamadden added a commit to zopefoundation/zope.publisher that referenced this pull request Mar 25, 2021
Explicitly use the repr of interfaces so we can work with any version of zope.interface.

See zopefoundation/zope.interface#237 (comment)
@jamadden
Copy link
Member Author

jamadden commented Mar 25, 2021

As some data points, in my random collection of zope(3)/plone and other modules, I have 13,080 total modules and 2,653 total interfaces. There are 2,561 Implements objects created, and 2,280 Classprovides objects.

There are a relatively small number of moduleProvides (or indeed, directlyProvides(some_module,…)) calls, and, if you ignore BTrees, most of those result in unique objects (not shared); 25 out of 39 total are shared, but 21 of those are from BTrees. So keeping track of the module names for these cases shouldn't be a memory burden.

directlyProvides(sys.modules['zope.interface'], IInterfaceDeclaration)
directlyProvides(('BTrees.IOBTree', 'BTrees.LOBTree', 'BTrees.fsBTree'), IIntegerObjectBTreeModule)
directlyProvides(('BTrees.IIBTree', 'BTrees.LLBTree'), IIntegerIntegerBTreeModule)
directlyProvides(('BTrees.IFBTree', 'BTrees.LFBTree'), IIntegerFloatBTreeModule)
directlyProvides(('BTrees.IUBTree', 'BTrees.LQBTree'), IIntegerUnsignedBTreeModule)
directlyProvides(('BTrees.UOBTree', 'BTrees.QOBTree'), IUnsignedObjectBTreeModule)
directlyProvides(('BTrees.UUBTree', 'BTrees.QQBTree'), IUnsignedUnsignedBTreeModule)
directlyProvides(('BTrees.UFBTree', 'BTrees.QFBTree'), IUnsignedFloatBTreeModule)
directlyProvides(('BTrees.UIBTree', 'BTrees.QLBTree'), IUnsignedIntegerBTreeModule)
directlyProvides(sys.modules['BTrees.OOBTree'], IObjectObjectBTreeModule)
directlyProvides(('BTrees.OIBTree', 'BTrees.OLBTree'), IObjectIntegerBTreeModule)
directlyProvides(('BTrees.OUBTree', 'BTrees.OQBTree'), IObjectUnsignedBTreeModule)
directlyProvides(sys.modules['zope.proxy'], IProxyIntrospection)
directlyProvides(sys.modules['zope.security.management'], ISecurityManagement, IInteractionManagement)
directlyProvides(sys.modules['zope.component'], IComponentArchitecture, IComponentRegistrationConvenience)
directlyProvides(sys.modules['zope.lifecycleevent'], IZopeLifecycleEvent)
directlyProvides(sys.modules['zope.globalrequest'], IGlobalRequest)
directlyProvides(sys.modules['zope.formlib.form'], IFormAPI)
directlyProvides(sys.modules['plone.supermodel'], IXMLToSchema)
directlyProvides(sys.modules['plone.rfc822'], IMessageAPI)
directlyProvides(('relstorage.adapters.sqlite.drivers', 'relstorage.adapters.postgresql.drivers', 'relstorage.adapters.oracle.drivers', 'relstorage.adapters.mysql.drivers'), IDBDriverOptions)
directlyProvides(sys.modules['zope.traversing.api'], ITraversalAPI)
directlyProvides(sys.modules['grokcore.annotation'], IGrokcoreAnnotationAPI)
directlyProvides(sys.modules['grokcore.viewlet'], IGrokcoreViewletAPI)
directlyProvides(sys.modules['z3c.objpath.path'], IObjectPath)

Copy link
Member

@icemac icemac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea although it might take a bit getting used to see executable Python code as repr. But it is much clearer now.

@jamadden jamadden merged commit 4a686fc into master Mar 29, 2021
@jamadden jamadden deleted the issue236 branch March 29, 2021 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update __repr__ and __str__ for (at least) Provides and InterfaceClass?
3 participants