[Python-ideas] Dunder method to make object str-like

Brett Cannon brett at python.org
Thu Apr 7 17:50:53 EDT 2016


On Thu, 7 Apr 2016 at 12:36 Random832 <random832 at fastmail.com> wrote:

> On Thu, Apr 7, 2016, at 15:17, Brett Cannon wrote:
> > How do you make Python 3.3 code work with this when the ABC will simply
> > not
> > be available to you unless you're running Python 3.4.3, 3.5.2, or 3.6.0
> > (under the assumption that the ABC is put in pathlib and backported
> > thanks
> > to its provisional status)? The ternary operator one-liner is
> > backwards-compatible while the ABC is only forward-compatible.
>
> If it's not available to you, then it's not available to anyone to
> register either, so you obviously act as if no objects are StringLike if
> you get an ImportError when trying to use it. Isn't this just the
> standard dance for using *any* function that's new to a new version of
> Python?
>

Yes, but the lack of a magic method is not as severe as a lack of an ABC
you will be using in an isinstance() check.


>
> try:
>     from pathlib import StringLike # if it's in pathlib why is it called
>     StringLike?
>

I called it StringLike because I was replying to Chris' proposal of a
generic string-like protocol (which wouldn't live in pathlib).


>     def is_StringLike(x): return isinstance(x, StringLike)
> except ImportError:
>     def is_StringLike(x): return False
>

That would cut out all third-party libraries no matter what their Python
version support was.

My point is that if I wanted this to work in Python 3.3.x, Python 3.4.2, or
Python 3.5.1 then the ABC solution is out as the ABC won't exist. The magic
method, though, would still work with the one-liner all the way back to
Python 2.5 when conditional expressions were added to the language.

For instance, let's say I'm the author of a library that uses file paths
that wants to support Python 3.3 and newer. How do I add support for using
pathlib.Path and Ethan's path library? With the magic method solution I can
use:

  def ospath(path):
      return path.__ospath__() if hasattr(path, '__ospath__') else path

If I really wanted to I could just embed that wherever I want to work with
paths.

Now how about the ABC?

  # In pathlib.
  class StringPath(abc.ABC):
      @abstractmethod
      def __str__(self): ...

  StringPath.register(pathlib.PurePath, str)  # Maybe not cover str?

  # In my library trying to support Python 3.3 and newer, pathlib and
Ethan's path library.
  try:
      from importlib import StringPath
  except ImportError:
      StringPath = None

  def ospath(path):
      if StringPath is None:
          if isinstance(path, StringPath):
              return str(path)
      # What am I supposed to do here?

Now you could set `StringPath = object`, but that starts to negate the
point of not subclassing strings as you're now accepting anything that
defines __str__() in that case unless you're on a version of Python "new"
enough to have pathlib w/ the ABC defined. And if you go some other route,
what would you want to do if StringPath wasn't available?

So the ABC vs magic method discussion comes down to whether we think
third-party libraries will use whatever approach is decided upon and
whether they care about how good the support is for Python 3.3.x, 3.4.2,
and 3.5.1.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160407/0bee819f/attachment.html>


More information about the Python-ideas mailing list