What's the difference between `raise` and `raise from` in Python?

```
try:
    raise ValueError
except Exception as e:
    raise IndexError

```

which yields

```
Traceback (most recent call last):
  File "tmp.py", line 2, in <module>
    raise ValueError
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tmp.py", line 4, in <module>
    raise IndexError
IndexError

```

and

```
try:
    raise ValueError
except Exception as e:
    raise IndexError from e

```

which yields

```
Traceback (most recent call last):
  File "tmp.py", line 2, in <module>
    raise ValueError
ValueError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "tmp.py", line 4, in <module>
    raise IndexError from e
IndexError

```