Packages the distutils stdlib module as a standalone package,
```
377K distutils.data
221K distutils.data.br
19K distutils.js
```
to reduce the minimal pyodide size.

Part of #1542 

This also,
 - adds documentation on what's supported or not in the stdlib
 - makes a few changes to `pyodide_build/buildall.py` to be able to add such stdlib packages as a dependency in other packages (which didn't work before). For instance, until there is a release with https://github.com/pypa/packaging/pull/396 micropip has a dependency on distutils.
Unvendor distutils. Packages the distutils stdlib module as a standalone package,
```
377K distutils.data
221K distutils.data.br
19K distutils.js
```
to reduce the minimal pyodide size.

Part of #1542 

This also,
 - adds documentation on what's supported or not in the stdlib
 - makes a few changes to `pyodide_build/buildall.py` to be able to add such stdlib packages as a dependency in other packages (which didn't work before). For instance, until there is a release with https://github.com/pypa/packaging/pull/396 micropip has a dependency on distutils.
import pytest


def test_threading_import(selenium):
    # Importing threading works
    selenium.run(
        """
        from threading import Thread
        """
    )

    selenium.run(
        """
        from threading import RLock

        with RLock():
            pass
        """
    )

    selenium.run(
        """
        from threading import Lock

        with Lock():
            pass
        """
    )

    selenium.run(
        """
        import threading
        threading.local(); pass
        """
    )

    # Starting a thread doesn't work
    msg = "can't start new thread"
    with pytest.raises(selenium.JavascriptException, match=msg):
        selenium.run(
            """
            from threading import Thread

            def set_state():
                return
            th = Thread(target=set_state)
            th.start()
            """
        )


def test_multiprocessing(selenium):
    selenium.run("import multiprocessing")

    res = selenium.run(
        """
        from multiprocessing import cpu_count
        cpu_count()
        """
    )
    assert isinstance(res, int)
    assert res > 0

    msg = "Resource temporarily unavailable"
    with pytest.raises(selenium.JavascriptException, match=msg):
        selenium.run(
            """
            from multiprocessing import Process

            def func():
                return
            process = Process(target=func)
            process.start()
            """
        )

import pytest


def test_threading_import(selenium):
    # Importing threading works
    selenium.run(
        """
        from threading import Thread
        """
    )

    selenium.run(
        """
        from threading import RLock

        with RLock():
            pass
        """
    )

    selenium.run(
        """
        from threading import Lock

        with Lock():
            pass
        """
    )

    selenium.run(
        """
        import threading
        threading.local(); pass
        """
    )

    # Starting a thread doesn't work
    msg = "can't start new thread"
    with pytest.raises(selenium.JavascriptException, match=msg):
        selenium.run(
            """
            from threading import Thread

            def set_state():
                return
            th = Thread(target=set_state)
            th.start()
            """
        )


def test_multiprocessing(selenium):
    selenium.run("import multiprocessing")

    res = selenium.run(
        """
        from multiprocessing import cpu_count
        cpu_count()
        """
    )
    assert isinstance(res, int)
    assert res > 0

    msg = "Resource temporarily unavailable"
    with pytest.raises(selenium.JavascriptException, match=msg):
        selenium.run(
            """
            from multiprocessing import Process

            def func():
                return
            process = Process(target=func)
            process.start()
            """
        )
