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__ for (at least) Provides and InterfaceClass? #236

Closed
jamadden opened this issue Mar 18, 2021 · 2 comments · Fixed by #237
Closed

Update __repr__ and __str__ for (at least) Provides and InterfaceClass? #236

jamadden opened this issue Mar 18, 2021 · 2 comments · Fixed by #237
Assignees

Comments

@jamadden
Copy link
Member

(Moved from #234 (comment))

Given spec = Provides(AClass, IFoo, IBar), the repr will be something like

<zope.interface.Provides for instances of <class 'some.module.AClass'> providing (<InterfaceClass some.module.interfaces.IFoo>, <InterfaceClass some.module.interfaces.IBar>)>

Informative, but not terse.

Basically none of these objects have a __str__ method.

__repr__ is meant to "look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment)."

In contrast __str__ computes "the 'informal' string representation of an object. This differs from __repr__() in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead. The return value must be a string object."

For Provides, it would be pretty easy to give a repr that actually can be evaluated (in many cases) outputting something like

Provides(AClass, IFoo, IBar)

Similarly, interfaces could have a __str__ that just outputs __module__.__name__.

That would transform reports from

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>

to

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

(With similar benefits when Provides is present.)

Since the changes in Provides in #234 mean that there might have to be doctest updates, and since adding a __str__ mostly shouldn't (but might!) cause doctest updates, this might be a good time (before 5.3) to make such a change.

What do you think?

@jamadden
Copy link
Member Author

Pending discussion of this, I'd like to go ahead and publish the trunk to PyPI as zope.interface 5.3.0a1; that will unblock zope.component to move forward (zopefoundation/zope.component#53 and zopefoundation/zope.component#55).

If we decide to go ahead with these changes, I can make the PR, and then we can release that as 5.3.0.

If we decide not to make these changes, I can release 5.3.0 with no changes from 5.3.0a1.

I'll wait at least an hour before taking any action.

@mgedmin
Copy link
Member

mgedmin commented Mar 24, 2021

I like it.

@jamadden jamadden self-assigned this Mar 24, 2021
jamadden added a commit that referenced this issue Mar 25, 2021
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
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants