## 10 Porting to Python 3.9 

This section lists previously described changes and other bugfixes that may require changes to your code. 

## 10.1 Changes in the Python API 

• __import__() and importlib.util.resolve_name() now raise ImportError where it pre- viously raised ValueError . Callers catching the specific exception type and supporting both Python 3.9 and earlier versions will need to catch both using$_{except (ImportError, ValueError):}$ . 

• The venv activation scripts no longer special-case when __VENV_PROMPT__ is set to "" . 

• The select.epoll.unregister() method no longer ignores the EBADF error. (Contributed by Victor Stinner in bpo-39239.) 

• The compresslevel parameter of$_{bz2.BZ2File}$ became keyword-only, since the buffering parameter has been removed. (Contributed by Victor Stinner in bpo-39357.) 

• Simplified AST for subscription. Simple indices will be represented by their value, extended slices will be represented as tuples. Index(value) will return a value itself, ExtSlice(slices) will return Tuple(slices, Load()) . (Contributed by Serhiy Storchaka in bpo-34822.) 

• The$_{importlib}$module now ignores the$_{PYTHONCASEOK}$ environment variable when the$_{-E}$ or$_{-I}$com- mand line options are being used. 

• The encoding parameter has been added to the classes$_{ftplib.FTP}$and$_{ftplib.FTP_TLS}$as a keyword- only parameter, and the default encoding is changed from Latin-1 to UTF-8 to follow RFC 2640 . 

• asyncio.loop.shutdown_default_executor() has been added to AbstractEventLoop , meaning alternative event loops that inherit from it should have this method defined. (Contributed by Kyle Stanley in bpo-34037.) 

• The constant values of future flags in the __future__ module is updated in order to prevent collision with compiler flags. Previously PyCF_ALLOW_TOP_LEVEL_AWAIT was clashing with CO_FUTURE_DIVISION . (Contributed by Batuhan Taskaya in bpo-39562) 

• array('u') now uses $_{wchar_t}$as C type instead of $_{Py_UNICODE}$. This change doesn’t affect to its behavior because Py_UNICODE is alias of $_{wchar_t}$since Python 3.3. (Contributed by Inada Naoki in bpo-34538.) 

• The logging.getLogger() API now returns the root logger when passed the name 'root' , whereas previously it returned a non-root logger named 'root' . This could affect cases where user code explicitly wants a non-root logger named 'root' , or instantiates a logger using logging. getLogger(__name__) in some top-level module called 'root.py' . (Contributed by Vinay Sajip in bpo-37742.) 

• Division handling of$_{PurePath}$ now returns$_{NotImplemented}$instead of raising a$_{TypeError}$ when passed something other than an instance of$_{str}$ or$_{PurePath}$ . This allows creating compatible classes that don’t inherit from those mentioned types. (Contributed by Roger Aiudi in bpo-34775). 

• Starting with Python 3.9.5 the ipaddress module no longer accepts any leading zeros in IPv4 address strings. Leading zeros are ambiguous and interpreted as octal notation by some libraries. For example the legacy function$_{socket.inet_aton()}$ treats leading zeros as octal notatation. glibc implementation of modern$_{inet_pton()}$ does not accept any leading zeros. (Contributed by Christian Heimes in bpo-36384). 

• codecs.lookup() now normalizes the encoding name the same way as encodings. normalize_encoding() , except that$_{codecs.lookup()}$ also converts the name to lower case. For example,$_{"latex+latin1"}$ encoding name is now normalized to$_{"latex_latin1"}$ . (Contributed by Jordon Xu in bpo-37751.) 

