What’s new in Python?

What’s new in Python?

New Syntax features

PEP 563: Postponed Evaluation of Annotations

The introduction of type hints in Python revealed a couple of application issues with the functionality of annotations added in PEP 3107 and refined further in PEP 526. These issues were:

  • Only those names already available in the current scope could be used by annotations, in other words they didn’t support forward references of any kind
  • There were adverse effects on startup time of Python programs due to annotating source code.

These two issues are resolved by postponing the evaluation of annotations.The compiler stores the annotation in a string form equivalent to the AST of the expression in question, instead of compiling code which executes expressions in annotations at their definition time. If needed, annotations can be resolved at runtime using typing.get_type_hints().

In the common case where this is not needed, the annotations are cheaper to store (since short strings are interned by the interpreter) and make startup time faster.

Usability-wise, annotations now support forward references, making the following syntax valid:

Since this change breaks compatibility, the new behavior needs to be enabled on a per-module basis in Python 3.7 using a __future__import:

It will become the default in Python 4.0.

Backwards incompatible syntax changes

async and await are now reserved keywords

async and await names are now reserved keywords. Code using these names as identifiers will now raise a SyntaxError. (Contributed by Jelle Zijlstra in bpo-30406.)

New library modules

1. contextvars

The new contextvars module and a set of new C APIs introduce support for context variables. Context variables are conceptually similar to thread-local variables. Unlike TLS, context variables support asynchronous code correctly.

The asyncio and decimal modules have been updated to use and support context variables out of the box. Particularly the active decimal context is now stored in a context variable, which allows decimal operations to work with the correct context in asynchronous code.

2. dataclasses

The new dataclass() decorator provides a way to declare data classes. A data class describes its attributes using class variable annotations. Its constructor and other magic methods, such as __repr__(), __eq__(), and __hash__() are generated automatically.

Example:

3. importlib.resources

The new importlib.resources module provides several new APIs and one new ABC for access to, opening, and reading resources inside packages. Resources are roughly similar to files inside packages, but they needn’t be actual files on the physical file system. Module loaders can provide a get_resource_reader() function which returns a importlib.abc.ResourceReader instance to support this new API. Built-in file path loaders and zip file loaders both support this.

Contributed by Barry Warsaw and Brett Cannon in bpo-32248.

New built-in features

PEP 553: Built-in breakpoint()

Python 3.7 includes the new built-in breakpoint() function as an easy and consistent way to enter the Python debugger.

Built-in breakpoint() calls sys.breakpointhook(). By default, the latter imports pdb and then calls pdb.set_trace(), but by binding sys.breakpointhook() to the function of your choosing, breakpoint() can enter any debugger. Additionally, the environment variable PYTHONBREAKPOINTcan be set to the callable of your debugger of choice. Set PYTHONBREAKPOINT=0 to completely disable built-in breakpoint().

Python data model improvements

1. PEP 562: Customization of Access to Module Attributes

Python 3.7 allows defining __getattr__() on modules and will call it whenever a module attribute is otherwise not found. Defining __dir__() on modules is now also allowed.

A typical example of where this may be useful is module attribute deprecation and lazy loading.

2. PEP 560: Core Support for typing module and Generic Types

Initially PEP 484 was designed in such way that it would not introduce any changes to the core CPython interpreter. Now type hints and the typing module are extensively used by the community, so this restriction is removed. The PEP introduces two special methods __class_getitem__() and __mro_entries__, these methods are now used by most classes and special constructs in typing. As a result, the speed of various operations with types increased up to 7 times, the generic types can be used without metaclass conflicts, and several long standing bugs in typing module are fixed.

3. “Dict keeps insertion order”

The insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec

Significant improvements in the standard library

1. asyncio

The asyncio module has received many new features, usability and performance improvements Notable changes include:

(Contributed by Yury Selivanov in bpo-32662.)

Several asyncio APIs have been deprecated.

2. PEP 564: New Time Functions With Nanosecond Resolution

The resolution of clocks in modern systems can exceed the limited precision of a floating point number returned by the time.time() function and its variants. To avoid loss of precision, PEP 564 adds six new “nanosecond” variants of the existing timer functions to the time module:

The new functions return the number of nanoseconds as an integer value.

Measurements show that on Linux and Windows the resolution of time.time_ns() is approximately 3 times better than that of time.time().

CPython implementation improvements

1. Avoiding the use of ASCII as a default text encoding
i. PEP 538: Legacy C Locale Coercion

An ongoing challenge within the Python 3 series has been determining a sensible default strategy for handling the “7-bit ASCII” text encoding assumption currently implied by the use of the default C or POSIX locale on non-Windows platforms.

PEP 538 updates the default interpreter command line interface to automatically coerce that locale to an available UTF-8 based locale as described in the documentation of the new PYTHONCOERCECLOCALE environment variable. Automatically setting LC_CTYPE this way means that both the core interpreter and locale-aware C extensions (such as readline) will assume the use of UTF-8 as the default text encoding, rather than ASCII.

The platform support definition in PEP 11 has also been updated to limit full text handling support to suitably configured non-ASCII based locales.

As part of this change, the default error handler for stdin and stdout is now surrogateescape (rather than strict) when using any of the defined coercion target locales (currently C.UTF-8, C.utf8, and UTF-8). The default error handler for stderr continues to be backslashreplace, regardless of locale.

Locale coercion is silent by default, but to assist in debugging potentially locale related integration problems, explicit warnings (emitted directly on stderr) can be requested by setting PYTHONCOERCECLOCALE=warn. This setting will also cause the Python runtime to emit a warning if the legacy C locale remains active when the core interpreter is initialized.

While PEP 538’s locale coercion has the benefit of also affecting extension modules (such as GNU readline), as well as child processes (including those running non-Python applications and older versions of Python), it has the downside of requiring that a suitable target locale be present on the running system. To better handle the case where no suitable target locale is available (as occurs on RHEL/CentOS 7, for example), Python 3.7 also implements PEP 540: Forced UTF-8 Runtime Mode.

ii. PEP 540: Forced UTF-8 Runtime Mode

The new -X utf8 command line option and PYTHONUTF8 environment variable can be used to enable the CPython UTF-8 mode.

When in UTF-8 mode, CPython ignores the locale settings, and uses the UTF-8 encoding by default. The error handlers for sys.stdin and sys.stdout streams are set to surrogateescape.

The forced UTF-8 mode can be used to change the text handling behavior in an embedded Python interpreter without changing the locale settings of an embedding application.

While PEP 540’s UTF-8 mode has the benefit of working regardless of which locales are available on the running system, it has the downside of having no effect on extension modules (such as GNU readline), child processes running non-Python applications, and child processes running older versions of Python. To reduce the risk of corrupting text data when communicating with such components, Python 3.7 also implements PEP 540: Forced UTF-8 Runtime Mode).

The UTF-8 mode is enabled by default when the locale is C or POSIX, and the PEP 538 locale coercion feature fails to change it to a UTF-8 based alternative (whether that failure is due to PYTHONCOERCECLOCALE=0 being set, LC_ALL being set, or the lack of a suitable target locale).

2. PEP 552: Hash-based .pyc Files

Python has traditionally checked the up-to-dateness of bytecode cache files (i.e., .pyc files) by comparing the source metadata (last-modified timestamp and size) with source metadata saved in the cache file header when it was generated. While effective, this invalidation method has its drawbacks. When filesystem timestamps are too coarse, Python can miss source updates, leading to user confusion. Additionally, having a timestamp in the cache file is problematic for build reproduciblit and content-based build systems.

PEP 552 extends the pyc format to allow the hash of the source file to be used for invalidation instead of the source timestamp. Such .pyc files are called “hash-based”. By default, Python still uses timestamp-based invalidation and does not generate hash-based .pyc files at runtime. Hash-based .pyc files may be generated with py_compile or compileall.

Hash-based .pyc files come in two variants: checked and unchecked. Python validates checked hash-based .pyc files against the corresponding source files at runtime but doesn’t do so for unchecked hash-based pycs. Unchecked hash-based .pyc files are a useful performance optimization for environments where a system external to Python (e.g., the build system) is responsible for keeping .pyc files up-to-date.

See Cached bytecode invalidation for more information.

3. The new Development Runtime Mode: -X dev

The new -X dev command line option or the new PYTHONDEVMODE environment variable can be used to enable CPython’s development mode. When in development mode, CPython performs additional runtime checks that are too expensive to be enabled by default. See -X dev documentation for the full description of the effects of this mode.

4. PEP 565: Show DeprecationWarning in __main__

The default handling of DeprecationWarning has been changed such that these warnings are once more shown by default, but only when the code triggering them is running directly in the __main__ module. As a result, developers of single file scripts and those using Python interactively should once again start seeing deprecation warnings for the APIs they use, but deprecation warnings triggered by imported application, library and framework modules will continue to be hidden by default. As a result of this change, the standard library now allows developers to choose between three different deprecation warning behaviours:

  • FutureWarning: always displayed by default, recommended for warnings intended to be seen by application end users (e.g. for deprecated application configuration settings).
  • DeprecationWarning: displayed by default only in __main__ and when running tests, recommended for warnings intended to be seen by other Python developers where a version upgrade may result in changed behaviour or an error.
  • PendingDeprecationWarning: displayed by default only when running tests, intended for cases where a future version upgrade will change the warning category to DeprecationWarning or FutureWarning..

Previously both DeprecationWarning and PendingDeprecationWarning were only visible when running tests, which meant that developers primarily writing single file scripts or using Python interactively could be surprised by breaking changes in the APIs they used.

C API improvements

1. PEP 539: New C API for Thread-Local Storage

While Python provides a C API for thread-local storage support; the existing Thread Local Storage (TLS) API has used int to represent TLS keys across all platforms. This has not generally been a problem for officially-support platforms, but that is neither POSIX-compliant, nor portable in any practical sense.

PEP 539 changes this by providing a new Thread Specific Storage (TSS) API API to CPython which supersedes use of the existing TLS API within the CPython interpreter, while deprecating the existing API. The TSS API uses a new type Py_tss_t instead of int to represent TSS keys–an opaque type the definition of which may depend on the underlying TLS implementation. Therefore, this will allow to build CPython on platforms where the native TLS key is defined in a way that cannot be safely cast to int.

Note that on platforms where the native TLS key is defined in a way that cannot be safely cast to int, all functions of the existing TLS API will be no-op and immediately return failure. This indicates clearly that the old API is not supported on platforms where it cannot be used reliably, and that no effort will be made to add such support.

Documentation improvements

PEP 545: Python Documentation Translations

PEP 545 describes the process of creating and maintaining Python documentation translations.

Three new translations have been added:

Other Language Changes

More than 255 arguments can now be passed to a function, and a function can now have more than 255 parameters. (Contributed by Serhiy Storchaka in bpo-12844 and bpo-18896.)

bytes.fromhex() and bytearray.fromhex() now ignore all ASCII whitespace, not only spaces. (Contributed by Robert Xiao in bpo-28927.)
str, bytes, and bytearray gained support for the new isascii() method, which can be used to test if a string or bytes contain only the ASCII characters. (Contributed by INADA Naoki in bpo-32677.)

ImportError now displays module name and module __file__ path when from ... import ... fails. (Contributed by Matthias Bussonnier in bpo-29546.)

Circular imports involving absolute imports with binding a submodule to a name are now supported. (Contributed by Serhiy Storchaka in 004.)

object.__format__(x, '') is now equivalent to str(x) rather than format(str(self), ''). (Contributed by Serhiy Storchaka in bpo-28974.)

In order to better support dynamic creation of stack traces, types.TracebackType can now be instantiated from Python code, and the tb_next attribute on tracebacks is now writable. (Contributed by Nathaniel J. Smith in bpo-30579.)

When using the -m switch, sys.path[0] is now eagerly expanded to the full starting directory path, rather than being left as the empty directory (which allows imports from the current working directory at the time when an import occurs) (Contributed by Nick Coghlan in bpo-33053.)

The new -X importtime option or the PYTHONPROFILEIMPORTTIME environment variable can be used to show the timing of each module import. (Contributed by Victor Stinner in bpo-31415..)

To get the detailed information about the new updates in Python, you can click on the the link.

So, Should I Upgrade?

Let’s start with the simple answer. If you want to try out any of the new features you have seen here, then you do need to be able to use Python 3.7. Using tools such as pyenv or Anaconda makes it easy to have several versions of Python installed side by side. There is no downside to installing Python 3.7 and trying it out.

Now, for the more complicated questions. Should you upgrade your production environment to Python 3.7? Should you make your own project dependent on Python 3.7 to take advantage of the new features?

With the obvious caveat that you should always do thorough testing before upgrading your production environment, there are very few things in Python 3.7 that will break earlier code (async and await becoming keywords is one example though). If you are already using a modern Python, upgrading to 3.7 should be quite smooth. If you want to be a little conservative, you might want to wait for the release of the first maintenance release—Python 3.7.1—tentatively expected some time in July 2018.

Arguing that you should make your project 3.7 only is harder. Many of the new features in Python 3.7 are either available as backports to Python 3.6 (data classes, importlib.resources) or conveniences (faster startup and method calls, easier debugging, and -X options). The latter, you can take advantage of by running Python 3.7 yourself while keeping your code compatible with Python 3.6 (or lower).
The big features that will lock your code to Python 3.7 are __getattr__() on modules,  forward references in type hints, and the nanosecond time functions. If you really need any of these, you should go ahead and bump your requirements. Otherwise, your project will probably be more useful to others if it can be run on Python 3.6 for a while longer.

See the Porting to Python 3.7 guide for details to be aware of when upgrading.

Recent market updates on Python

In an independent 3rd party survey, it has been found that the Python programming language is currently the most popular language for Data Scientists worldwide. This claim is substantiated by IEEE, which tracks programming languages by popularity. According to them, Python tops the list of the most popular programming languages in 2018. Not only this, Python is finding its application in diverse domains like web development, game development, big data, web testing, AI/data science and smart services etc.

Some of the big players like Quora, Facebook, YouTube, SlideShare, Dropbox, Pinterest, Reddit, and Netflix have most of their new code written in Python. It is an open secret in the developer world that Google has now adopted Python as its secondary coding language, and has committed to using it more in its new product offerings.

Top factors driving python ahead in 2018

Data science libraries

Data Science is the single biggest reason why everyone is migrating to Python. Data Science offers exciting work along with high pay. Now let us see deep-dive and know about the details the following three Data Science Libraries.

Pandas:

Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.

It is free software released under the three-clause BSD license. pandas assume general familiarity with NumPy.

NumPy:

NumPy is a library for the Python programming language, adding support for large, multi-dimensional arrays and matrices, along with a large collection of high-level mathematical functions to operate on these arrays.

Pandas is built on top of NumPy and is intended to integrate well within a scientific computing environment with many other 3rd party libraries.

Matplotlib:

Matplotlib is a Python 2D plotting library which produces publication quality figures in a variety of hard copy formats and interactive environments across platforms.

Matplotlib can be used in Python scripts, the Python and IPython shell, the jupyter notebook, web application servers, and four graphical user interface toolkits.

2.Web development frameworks

Django:

Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design.

Flask:

Flask is a Python web framework built with a small core and easy-to-extend philosophy. Flask is considered more Pythonic than Django because Flask web application code is in most cases more explicit.

Flask is easy to get started with as a beginner because there is little boilerplate code for getting a simple app up and running.

3. Machine learning

Machine learning and AI has been a hot topic for the IT industry. We see every IT firm just latching on this new opportunity. Algorithms have become sophisticated as the time has gone.

Google search engine is the most common example as it predicts our searches. This is a huge reason why everyone who is interested in machine learning or AI is learning Python as presently it is the major language which makes the task easy.

What’s new in C? (Prev Lesson)
(Next Lesson) WHY AGILE SCRUM IS IMPORTANT?