> For the complete documentation index, see [llms.txt](https://ricardomol.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ricardomol.gitbook.io/notes/backend/python/targeting-python-2-+-3.md).

# Targeting Python 2 + 3

To develop **programs which can be run in both Python 2+ and 3+**.

You have 2 choices:

1. Distribute 2 modules, one for Python 2 and the other for Python 3.
2. Modify your current code and make it compatible with both Python 2 and 3.

**Tricks which you can employ to make a script compatible with both of them:**

## **Future imports**

&#x20;`__future__` imports **allow you to import Python 3 functionality in Python 2**.

Examples:

**Context managers** were new in Python 2.6+. For using them in Python 2.5 you can use:

```python
from __future__ import with_statement
```

**`print` was changed to a function in Python 3**. If you want to use it in Python 2 you can import it from `__future__`:

```python
print
# Output:

from __future__ import print_function
print(print)
# Output: <built-in function print>
```

## **Dealing with module renaming**

Most of us import packages like this :

```python
import foo
# or
from foo import bar
```

But you can also do this:

```python
import foo as foo
```

I know its function is the same as the above listed code but it is vital for making your script compatible with Python 2 and 3. Now examine the code below :

```python
try:
    import urllib.request as urllib_request  # for Python 3
except ImportError:
    import urllib2 as urllib_request  # for Python 2
```

We are wrapping our importing code in a `try/except`clause. We are doing it because **in Python 2 there is no `urllib.request` module so this would result in an `ImportError`**. The functionality of `urllib.request` is provided by the `urllib2` module in Python 2. So, when using Python 2, we try to import `urllib.request` and if we get an `ImportError` then we tell Python to import `urllib2` instead.

**The `as` keyword is mapping the imported module to `urllib_request`**&#x73;o that all of the classes and methods within `urllib2` are available to us via the alias `urllib_request`.

## **Obsolete Python 2 builtins**

There are 12 Python 2 builtins which have been removed from Python 3. **Make sure that you don’t use them in Python 2 in order to make your code compatible with Python 3**.

To enforce that you abandon these 12 builtins in Python 2:

```python
from future.builtins.disabled import *
```

Now whenever you try to use the modules which are abandoned in Python 3, it raises a `NameError`like this:

```python
from future.builtins.disabled import *

apply()
# Output: NameError: obsolete Python 2 builtin apply is disabled
```

## **External standard-library backports**

There are a few packages which provide Python 3 functionality in Python 2:

* enum `pip install enum34`
* singledispatch `pip install singledispatch`
* pathlib `pip install pathlib`

## Further reading

[Comprehensive guide](https://docs.python.org/3/howto/pyporting.html) to make your code compatible with both Python 2 and 3.
