Add support for Homebrew-installed software (#232)

* Add support for Homebrew-installed software

* mock os.pathsep when running macOS tests on non-macOS systems

* respond to review comments

* respond to review comments
diff --git a/src/platformdirs/api.py b/src/platformdirs/api.py
index 1315799..aa9ce7b 100644
--- a/src/platformdirs/api.py
+++ b/src/platformdirs/api.py
@@ -58,8 +58,8 @@
         """
         self.multipath = multipath
         """
-        An optional parameter only applicable to Unix/Linux which indicates that the entire list of data dirs should be
-        returned. By default, the first item would only be returned.
+        An optional parameter which indicates that the entire list of data dirs should be returned.
+        By default, the first item would only be returned.
         """
         self.opinion = opinion  #: A flag to indicating to use opinionated values.
         self.ensure_exists = ensure_exists
diff --git a/src/platformdirs/macos.py b/src/platformdirs/macos.py
index 7800fe1..c01ce16 100644
--- a/src/platformdirs/macos.py
+++ b/src/platformdirs/macos.py
@@ -2,6 +2,7 @@
 from __future__ import annotations
 
 import os.path
+import sys
 
 from .api import PlatformDirsABC
 
@@ -22,8 +23,20 @@
 
     @property
     def site_data_dir(self) -> str:
-        """:return: data directory shared by users, e.g. ``/Library/Application Support/$appname/$version``"""
-        return self._append_app_name_and_version("/Library/Application Support")
+        """
+        :return: data directory shared by users, e.g. ``/Library/Application Support/$appname/$version``.
+          If we're using a Python binary managed by `Homebrew <https://brew.sh>`_, the directory
+          will be under the Homebrew prefix, e.g. ``/opt/homebrew/share/$appname/$version``.
+          If `multipath <platformdirs.api.PlatformDirsABC.multipath>` is enabled and we're in Homebrew,
+          the response is a multi-path string separated by ":", e.g.
+          ``/opt/homebrew/share/$appname/$version:/Library/Application Support/$appname/$version``
+        """
+        is_homebrew = sys.prefix.startswith("/opt/homebrew")
+        path_list = [self._append_app_name_and_version("/opt/homebrew/share")] if is_homebrew else []
+        path_list.append(self._append_app_name_and_version("/Library/Application Support"))
+        if self.multipath:
+            return os.pathsep.join(path_list)
+        return path_list[0]
 
     @property
     def user_config_dir(self) -> str:
@@ -42,8 +55,20 @@
 
     @property
     def site_cache_dir(self) -> str:
-        """:return: cache directory shared by users, e.g. ``/Library/Caches/$appname/$version``"""
-        return self._append_app_name_and_version("/Library/Caches")
+        """
+        :return: cache directory shared by users, e.g. ``/Library/Caches/$appname/$version``.
+          If we're using a Python binary managed by `Homebrew <https://brew.sh>`_, the directory
+          will be under the Homebrew prefix, e.g. ``/opt/homebrew/var/cache/$appname/$version``.
+          If `multipath <platformdirs.api.PlatformDirsABC.multipath>` is enabled and we're in Homebrew,
+          the response is a multi-path string separated by ":", e.g.
+          ``/opt/homebrew/var/cache/$appname/$version:/Library/Caches/$appname/$version``
+        """
+        is_homebrew = sys.prefix.startswith("/opt/homebrew")
+        path_list = [self._append_app_name_and_version("/opt/homebrew/var/cache")] if is_homebrew else []
+        path_list.append(self._append_app_name_and_version("/Library/Caches"))
+        if self.multipath:
+            return os.pathsep.join(path_list)
+        return path_list[0]
 
     @property
     def user_state_dir(self) -> str:
diff --git a/tests/test_macos.py b/tests/test_macos.py
index decbec5..551ec0f 100644
--- a/tests/test_macos.py
+++ b/tests/test_macos.py
@@ -1,13 +1,27 @@
 from __future__ import annotations
 
 import os
+import sys
 from pathlib import Path
-from typing import Any
+from typing import TYPE_CHECKING, Any
 
 import pytest
 
 from platformdirs.macos import MacOS
 
+if TYPE_CHECKING:
+    from pytest_mock import MockerFixture
+
+
+@pytest.fixture(autouse=True)
+def _fix_os_pathsep(mocker: MockerFixture) -> None:
+    """
+    If we're not actually running on macOS, set `os.pathsep` to what it should be on macOS.
+    """
+    if sys.platform != "darwin":  # pragma: darwin no cover
+        mocker.patch("os.pathsep", ":")
+        mocker.patch("os.path.pathsep", ":")
+
 
 @pytest.mark.parametrize(
     "params",
@@ -17,7 +31,15 @@
         pytest.param({"appname": "foo", "version": "v1.0"}, id="app_name_version"),
     ],
 )
-def test_macos(params: dict[str, Any], func: str) -> None:
+def test_macos(mocker: MockerFixture, params: dict[str, Any], func: str) -> None:
+    # Make sure we are not in Homebrew
+    py_version = sys.version_info
+    builtin_py_prefix = (
+        "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework"
+        f"/Versions/{py_version.major}.{py_version.minor}"
+    )
+    mocker.patch("sys.prefix", builtin_py_prefix)
+
     result = getattr(MacOS(**params), func)
 
     home = str(Path("~").expanduser())
@@ -45,3 +67,45 @@
     expected = expected_map[func]
 
     assert result == expected
+
+
+@pytest.mark.parametrize(
+    "params",
+    [
+        pytest.param({}, id="no_args"),
+        pytest.param({"appname": "foo"}, id="app_name"),
+        pytest.param({"appname": "foo", "version": "v1.0"}, id="app_name_version"),
+    ],
+)
+@pytest.mark.parametrize(
+    "site_func",
+    [
+        "site_data_dir",
+        "site_config_dir",
+        "site_cache_dir",
+        "site_runtime_dir",
+    ],
+)
+@pytest.mark.parametrize("multipath", [pytest.param(True, id="multipath"), pytest.param(False, id="singlepath")])
+def test_macos_homebrew(mocker: MockerFixture, params: dict[str, Any], multipath: bool, site_func: str) -> None:
+    mocker.patch("sys.prefix", "/opt/homebrew/opt/python")
+
+    result = getattr(MacOS(multipath=multipath, **params), site_func)
+
+    home = str(Path("~").expanduser())
+    suffix_elements = tuple(params[i] for i in ("appname", "version") if i in params)
+    suffix = os.sep.join(("", *suffix_elements)) if suffix_elements else ""  # noqa: PTH118
+
+    expected_map = {
+        "site_data_dir": f"/opt/homebrew/share{suffix}",
+        "site_config_dir": f"/opt/homebrew/share{suffix}",
+        "site_cache_dir": f"/opt/homebrew/var/cache{suffix}",
+        "site_runtime_dir": f"{home}/Library/Caches/TemporaryItems{suffix}",
+    }
+    if multipath:
+        expected_map["site_data_dir"] += f":/Library/Application Support{suffix}"
+        expected_map["site_config_dir"] += f":/Library/Application Support{suffix}"
+        expected_map["site_cache_dir"] += f":/Library/Caches{suffix}"
+    expected = expected_map[site_func]
+
+    assert result == expected