Repository: conan-io/conan
Pull request: fix: need return 3 None on detect_default_compiler() to avoid errors
Changelog: Fix: Make sure `detect_default_compiler()` always returns a 3-tuple.
Docs: Omit

Close: #15712

- [x] Refer to the issue that supports this Pull Request.
- [x] If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.
- [x] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).
- [x] I've followed the PEP8 style guides for Python code.


Problem statement:
[bug] Detecting profile crashes
### Environment details

* GhostBSD 24.01.1, FreeBSD jorisp-ghostbsd 14.0-STABLE FreeBSD 14.0-STABLE GENERIC amd64
* /usr/local/bin/clang++15 (15.0.7) /usr/local/bin/gcc12 (12.2.0)
* Conan version: 2.1.0
* Python version: 3.9.18

### Steps to reproduce

`conan profile detect`

### Logs

ERROR: Traceback (most recent call last):
  File "/home/jorisp/.local/lib/python3.9/site-packages/conan/cli/cli.py", line 281, in main
    cli.run(args)
  File "/home/jorisp/.local/lib/python3.9/site-packages/conan/cli/cli.py", line 191, in run
    command.run(self._conan_api, args[0][1:])
  File "/home/jorisp/.local/lib/python3.9/site-packages/conan/cli/command.py", line 158, in run
    sub.run(conan_api, parser, *args)
  File "/home/jorisp/.local/lib/python3.9/site-packages/conan/cli/command.py", line 172, in run
    info = self._method(conan_api, parent_parser, self._parser, *args)
  File "/home/jorisp/.local/lib/python3.9/site-packages/conan/cli/commands/profile.py", line 68, in profile_detect
    detected_profile = conan_api.profiles.detect()
  File "/home/jorisp/.local/lib/python3.9/site-packages/conan/api/subapi/profiles.py", line 142, in detect
    settings = detect_defaults_settings()
  File "/home/jorisp/.local/lib/python3.9/site-packages/conans/client/conf/detect.py", line 17, in detect_defaults_settings
    compiler, version, compiler_exe = detect_default_compiler()
TypeError: cannot unpack non-iterable NoneType object

ERROR: cannot unpack non-iterable NoneType object

Hints from issue discussion:
Thanks for reporting this @jputcu 

It seems there is a gap for FreeBSD if it cannot detect the clang compiler:
```python
   if platform.system() in ["Darwin", "FreeBSD"]:
        clang, clang_version, compiler_exe = _clang_compiler()  # prioritize clang
        if clang:
            return clang, clang_version, compiler_exe
        return
```

That last return is the offending one, lets fix it for next release.
In the meantime, you can avoid it by manually creating your ``default`` profile, please ask for help if you need with that.
Apparently on GhostBSD, I need to install the following:
`sudo pkg install os-generic-userland-devtools`

Then `conan profile detect` gives me:
~~~~
detect_api: Found clang 16.0
detect_api: clang>=8, using the major as version

Detected profile:
[settings]
arch=x86_64
build_type=Release
compiler=clang
compiler.cppstd=gnu17
compiler.libcxx=libc++
compiler.version=16
os=FreeBSD

WARN: This profile is a guess of your environment, please check it.
WARN: The output of this command is not guaranteed to be stable and can change in future Conan versions.
WARN: Use your own profile files for stability.
~~~~
Yes, if the compiler is installed, then `` clang, clang_version, compiler_exe = _clang_compiler()`` doesn't raise, because the compiler is detected.

Commit message: fix: need return 3 None on detect_default_compiler() to avoid errors on the call

Patch to review:
diff --git a/conan/internal/api/detect_api.py b/conan/internal/api/detect_api.py
index f7449347694..f97c1e95aff 100644
--- a/conan/internal/api/detect_api.py
+++ b/conan/internal/api/detect_api.py
@@ -397,12 +397,12 @@ def detect_default_compiler():
         clang, clang_version, compiler_exe = _clang_compiler()  # prioritize clang
         if clang:
             return clang, clang_version, compiler_exe
-        return
     else:
         gcc, gcc_version, compiler_exe = _gcc_compiler()
         if gcc:
             return gcc, gcc_version, compiler_exe
         return _clang_compiler()
+    return None, None, None
 
 
 def default_msvc_ide_version(version):


Code review comments:
diff_hunk: @@ -397,12 +397,12 @@ def detect_default_compiler():
         clang, clang_version, compiler_exe = _clang_compiler()  # prioritize clang
         if clang:
             return clang, clang_version, compiler_exe
-        return
path: conan/internal/api/detect_api.py
text: @user1:
I'd keep this `return None, None, None` to simplify the flow too

@user2:
Agree

@user3:
Agree, can  you please do this change?

I have been doing a quick check, testing this seems possible with a mock of ``_clang_compiler``, but probably not worth the complexity (too much mock for testing one ``if``), so I am good without tests for this PR

@author:
Done 😄