Repository: SCons/scons

Issue:
Python 3.7 and multiple threads
SCons version: 3.0.1
Python version: 3.7
Python distribution: homebrew
SCons installed via pip
Platform: OS X 10.13.6
How to reproduce: run scons on any project

Description:
I recently got forcibly upgraded on my Mac to Python 3.7 via homebrew. After I went through and reinstalled all my packages, including SCons, I started seeing the following message when I run scons:

```
scons: warning: parallel builds are unsupported by this version of Python;
	ignoring -j or num_jobs option.
```

SCons seems to work fine with Python 3.7, it just emits this warning message. I did a little digging, and It seems that the `WITH_THREAD` config variable that SCons is using to test whether Python was configured with multiple threads is no longer supported, i.e., `sysconfig.get_config_var('WITH_THREAD')` used in Script/Main.py returns None even though multithreading *is* supported on the homebrew build.

I tried reverting to Python 3.6 through homebrew, but that doesn't seem to be supported, at least not directly based on what I could find via Google. I also tried using a build of Python 3.6 that I downloaded from python.org, but that build didn't seem to work very well. Scripts that worked fine with the homebrew build of Python 3.6 didn't seem to work correctly with the python.org build.

Based on what I'm reading on scons.org, it doesn't appear to me that SCons is supposed to directly support Python 3.7, yet; however, since I'm definitely running into fewer issues using Python 3.7 than I am with non-homebrew versions of Python 3.6, I'll continue using it. I'm just filing this issue as a heads-up for an issue that will probably arise when you begin testing on Python 3.7.

While I did not post this issue to the users list, I did look through all the archives back to the first of the year, and saw nothing obvious relating to Python 3.7. I would be nice if there were a search function for the archives. A google search pinned to site:scons.org didn't yield anything useful.


Discussion:
The users mailing list is pretty much for exactly what you put in this bug filing, and thus why we ask that people bring their issues there first.

Regardless, we're aware of the issue and likely have a simple fix which should make it into the next release. You can see a discussion of such in the IRC channel log. https://botbot.me/freenode/scons/2018-07-10/?msg=101945959&page=1
Thank you for the response. If it matters, I don't participate on email lists any more because I've had my address harvested by spammers too many times and ended up with, in one case, over 10,000 spam messages in the course of about two weeks. I swore off email lists not long after that. If that means I'm not welcome to participate here, then so be it.
Indeed that is not the case.  And of course the bug is valid. So please go ahead and reopen.  (that said I've thus far not had such a problem with mailing lists or google's spam filters is good enough I never see them)
Ah, I interpreted your first response to mean that there was already a ticket open and I just missed it when I searched. That's why I closed this one. It's now been reopened.

To be fair, the email issue happened a long time ago. It wasn't until much later that I realized I made the horrible mistake of using my work email address to subscribe to a few lists, so I couldn't just close the account or abandon it. Still, it really soured me on email lists.
@rickrankin  - indeed few work emails have spam protection as good as google.. Another trick is use + emails.. (so userid+tag@gmail.com is always routed to userid@gmail.com, but you can filter it via userid+tag).  Regardless, there's utility in scons' user mailing list, high signal to noise ratio and not a huge volume of email.

I'll try to get a pull request together by end of week for this. But for now, you could probably get away with 

` python_has_threads = True`

instead of:

` python_has_threads = sysconfig.get_config_var('WITH_THREAD') or is_pypy`
I had tried that, but there seems to be a little more to it. I haven't added any print statements to verify it, but it appears that SCons.Job.Jobs(...) is returning an object with num_jobs set to one, so the condition below `elif jobs.num_jobs == 1 ...` is still failing and I still see the message.

```python
    python_has_threads = True
    global num_jobs
    num_jobs = options.num_jobs
    jobs = SCons.Job.Jobs(num_jobs, taskmaster)
    if num_jobs > 1:
        msg = None
        if sys.platform == 'win32':
            msg = fetch_win32_parallel_msg()
        elif jobs.num_jobs == 1 or not python_has_threads:      # <--- failing here
            msg = "parallel builds are unsupported by this version of Python;\n" + \
                  "\tignoring -j or num_jobs option.\n"
```

At this point, `python_has_threads` has been hardcoded to True, so the only possibility is that `jobs.num_jobs == 1`. I haven't had time to try to see why `jobs.num_jobs` is being set to 1.
What's the command line you're using?
I'm just typing `scons`, but I have SCONSFLAGS set to "-Qu -j4". If I unset SCONSFLAGS and run `scons`, then I don't see the message. Of course, then I don't get into the if condition at all, since `options.num_jobs`, and therefore global `num_jobs` will just be 1.

Resolving patch:
diff --git a/runtest.py b/runtest.py
--- a/runtest.py
+++ b/runtest.py
@@ -787,7 +787,7 @@ def find_py(directory):
 tests_failing = 0
 
 
-def run_test(t, io_lock, async=True):
+def run_test(t, io_lock, run_async=True):
     global tests_completed, tests_passing, tests_failing
     header = ""
     command_args = ['-tt']
@@ -930,4 +930,4 @@ def run(self):
 # tab-width:4
 # indent-tabs-mode:nil
 # End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
\ No newline at end of file
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -1255,7 +1255,11 @@ def order(dependencies):
 
 
     is_pypy = platform.python_implementation() == 'PyPy'
-    python_has_threads = sysconfig.get_config_var('WITH_THREAD') or is_pypy
+    # As of 3.7, python removed support for threadless platforms.
+    # See https://www.python.org/dev/peps/pep-0011/
+    is_37_or_later = sys.version_info.major > 3 or \
+        sys.version_info.major == 3 and sys.version_info.minor >= 7
+    python_has_threads = sysconfig.get_config_var('WITH_THREAD') or is_pypy or is_37_or_later
     # to check if python configured with threads.
     global num_jobs
     num_jobs = options.num_jobs


Test patch: