[Python-legal-sig] Portable code: __import__ demands different string types between 2 and 3

Alex Gaynor alex.gaynor at gmail.com
Mon Dec 15 07:36:37 CET 2014


Was sending this to legal-sig a mistake?

Alex

On Sun Dec 14 2014 at 9:18:37 PM Ben Finney <ben+python at benfinney.id.au>
wrote:

> Howdy all,
>
> What should I do, in a world where all text literals are Unicode by
> default, to make ‘__import__’ work in both Python 2 and 3?
>
> I'm slowly learning about making Python code that will run under both
> Python 2 (version 2.6 or above) and Python 3 (version 3.2 or above).
>
> This entails, I believe, the admonition to ensure text literals are
> Unicode by default::
>
>     from __future__ import unicode_literals
>
> and to specify bytes literals explicitly with ‘b'wibble'’ if needed.
>
>
> The ‘__import__’ built-in function, though, is tripping up.
>
> A contrived, trivial project layout::
>
>     $ mkdir fooproject/
>     $ cd fooproject/
>
>     $ mkdir foo/
>     $ printf "" > foo/__init__.py
>     $ mkdir foo/bar/
>     $ printf "" > foo/bar/__init__.py
>
> Here's a simple ‘fooproject/setup.py’::
>
>     from __future__ import unicode_literals
>
>     main_module_name = 'foo'
>     main_module = __import__(main_module_name, fromlist=['bar'])
>
> That fails under Python 2, but runs fine under Python 3::
>
>     $ python2 ./setup.py
>     Traceback (most recent call last):
>       File "./setup.py", line 4, in <module>
>         main_module = __import__(main_module_name, fromlist=['bar'])
>     TypeError: Item in ``from list'' not a string
>
>     $ python3 ./setup.py
>
> We've deliberately made unadorned strings Unicode by default. By “not a
> string”, I presume Python 2 means “not a ‘bytes’ object”.
>
>
> Okay, so we'll explicitly set that to a ‘bytes’ literal::
>
>     from __future__ import unicode_literals
>
>     main_module_name = 'foo'
>     main_module = __import__(main_module_name, fromlist=[b'bar'])
>
> Now Python 2 is satisfied, but Python 3 complains::
>
>     $ python2 ./setup.py
>
>     $ python3 ./setup.py
>     Traceback (most recent call last):
>       File "./setup.py", line 4, in <module>
>         main_module = __import__(main_module_name, fromlist=[b'bar'])
>       File "<frozen importlib._bootstrap>", line 2281, in
>         _handle_fromlist
>     TypeError: hasattr(): attribute name must be string
>
>
> How can I get that ‘__import__’ call, complete with its ‘fromlist’
> parameter, working correctly under both Python 2 and Python 3, keeping
> the ‘unicode_literals’ setting?
>
> --
>  \           “I do not believe in immortality of the individual, and I |
>   `\        consider ethics to be an exclusively human concern with no |
> _o__)  superhuman authority behind it.” —Albert Einstein, letter, 1953 |
> Ben Finney
>
> _______________________________________________
> Python-legal-sig mailing list
> Python-legal-sig at python.org
> https://mail.python.org/mailman/listinfo/python-legal-sig
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-legal-sig/attachments/20141215/774e0b5b/attachment.html>


More information about the Python-legal-sig mailing list