Repository: pylint-dev/pylint

Issue:
Source root not correctly used
### Bug description

I have a package that sits in a child folder of the current working directory (./src). Now if I want to to run pyreverse for this module I add ./src as a source-root. However pyreverse does not find the module.

Here is an example:

```cmd
ex/
└── src/
    ├── __init__.py
    └── mymodule/
        ├── __init__.py
        └── testmodule.py
```

### Configuration

_No response_

### Command used

pyreverse -o html --source-root ./src mymodule

### Pylint output

raise ImportError(f"No module named {'.'.join(module_parts)}")
ImportError: No module named mymodule

### Expected behavior

When specifiy source-roots, pyreverse should also search the modules in this path

### Pylint version

pylint 3.3.1
astroid 3.3.5
Python 3.12.7 | packaged by conda-forge | (main, Oct  4 2024, 15:47:54) [MSC v.1941 64 bit (AMD64)]

### OS / Environment

win64

### Additional dependencies

_No response_


Discussion:

Patch:
diff --git a/doc/whatsnew/fragments/10026.bugfix b/doc/whatsnew/fragments/10026.bugfix
new file mode 100644
index 0000000000..3a80c19309
--- /dev/null
+++ b/doc/whatsnew/fragments/10026.bugfix
@@ -0,0 +1,3 @@
+Fixes the issue with --source-root option not working when the source files are in a subdirectory of the source root (e.g. when using a /src layout).
+
+Closes #10026
diff --git a/pylint/lint/expand_modules.py b/pylint/lint/expand_modules.py
index f40bdeea5b..a7d31dea6b 100644
--- a/pylint/lint/expand_modules.py
+++ b/pylint/lint/expand_modules.py
@@ -33,7 +33,7 @@ def discover_package_path(modulepath: str, source_roots: Sequence[str]) -> str:
     # Look for a source root that contains the module directory
     for source_root in source_roots:
         source_root = os.path.realpath(os.path.expanduser(source_root))
-        if os.path.commonpath([source_root, dirname]) == source_root:
+        if os.path.commonpath([source_root, dirname]) in [dirname, source_root]:
             return source_root
 
     # Fall back to legacy discovery by looking for __init__.py upwards as


Test patch:
diff --git a/tests/pyreverse/test_main.py b/tests/pyreverse/test_main.py
index e8e46df2c1..59fcab16f4 100644
--- a/tests/pyreverse/test_main.py
+++ b/tests/pyreverse/test_main.py
@@ -65,6 +65,42 @@ def test_project_root_in_sys_path() -> None:
         assert sys.path == [PROJECT_ROOT_DIR]
 
 
+def test_discover_package_path_source_root_as_parent(tmp_path: Any) -> None:
+    """Test discover_package_path when source root is a parent of the module."""
+    # Create this temporary structure:
+    # /tmp_path/
+    # └── project/
+    #     └── my-package/
+    #         └── __init__.py
+    project_dir = tmp_path / "project"
+    package_dir = project_dir / "mypackage"
+    package_dir.mkdir(parents=True)
+    (package_dir / "__init__.py").touch()
+
+    # Test with project_dir as source root (parent of package)
+    result = discover_package_path(str(package_dir), [str(project_dir)])
+    assert result == str(project_dir)
+
+
+def test_discover_package_path_source_root_as_child(tmp_path: Any) -> None:
+    """Test discover_package_path when source root is a child of the module."""
+    # Create this temporary structure:
+    # /tmp_path/
+    # └── project/
+    #     └── src/
+    #         └── my-package/
+    #             └── __init__.py
+    project_dir = tmp_path / "project"
+    src_dir = project_dir / "src"
+    package_dir = src_dir / "mypackage"
+    package_dir.mkdir(parents=True)
+    (package_dir / "__init__.py").touch()
+
+    # Test with src_dir as source root (child of project)
+    result = discover_package_path(str(project_dir), [str(src_dir)])
+    assert result == str(src_dir)
+
+
 @mock.patch("pylint.pyreverse.main.Linker", new=mock.MagicMock())
 @mock.patch("pylint.pyreverse.main.DiadefsHandler", new=mock.MagicMock())
 @mock.patch("pylint.pyreverse.main.writer")