Repository: pyinstaller/pyinstaller-hooks-contrib (language: python)

Issue:
Hidden imports not found with pydicom 3
**Describe the bug**
* Which hook/library isn't working? `pydicom`
* Does the error get raised while building or when running?
Warning when building, error when running.

**To Reproduce**

A minimal example file:
```python
from pydicom import dcmread
dcmread("")
```

PyInstaller command:
```
pyinstaller test.py
```

Error:
```
(.venv) C:\Code\project>dist\test\test.exe
Traceback (most recent call last):
  File "C:\ws\project\test.py", line 1, in <module>
    from pydicom import dcmread
  File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
  File "pydicom\__init__.py", line 31, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
  File "pydicom\dataelem.py", line 17, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
  File "pydicom\config.py", line 367, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
  File "pydicom\pixel_data_handlers\__init__.py", line 6, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
  File "pydicom\pixels\__init__.py", line 3, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
  File "pydicom\pixels\decoders\__init__.py", line 3, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
  File "pydicom\pixels\decoders\base.py", line 1805, in <module>
  File "pydicom\pixels\common.py", line 130, in add_plugins
  File "pydicom\pixels\common.py", line 83, in add_plugin
  File "importlib\__init__.py", line 90, in import_module
ModuleNotFoundError: No module named 'pydicom.pixels.decoders.gdcm'
[PYI-32016:ERROR] Failed to execute script 'test' due to unhandled exception!
```

**Expected behavior**
No `ModuleNotFoundError`

**Desktop (please complete the following information):**
 - OS: Windows
 - Python Version: Python 3.12
 - Version of `pyinstaller-hooks-contrib`: 2024.8
 - Version of PyInstaller: 6.10.0



Discussion / hints:
I think Rok's already working on that one. It got flagged up yesterday: https://github.com/pyinstaller/pyinstaller-hooks-contrib/pull/790#issuecomment-2339075464
Yeah, I'm almost done with sorting this one out.

Fix patch:
diff --git a/_pyinstaller_hooks_contrib/stdhooks/hook-pydicom.py b/_pyinstaller_hooks_contrib/stdhooks/hook-pydicom.py
index 940c8a36..8b3d4970 100644
--- a/_pyinstaller_hooks_contrib/stdhooks/hook-pydicom.py
+++ b/_pyinstaller_hooks_contrib/stdhooks/hook-pydicom.py
@@ -10,8 +10,60 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 # ------------------------------------------------------------------
 
-hiddenimports = [
-    "pydicom.encoders.gdcm",
-    "pydicom.encoders.pylibjpeg",
-    "pydicom.encoders.native",
-]
+from PyInstaller.utils.hooks import is_module_satisfies, collect_data_files
+
+hiddenimports = []
+datas = []
+
+# In pydicom 3.0.0, the `pydicom.encoders` plugins were renamed to `pydicom.pixels.encoders`, and
+# `pydicom.pixels.decoders` were also added. We need to collect them all, because they are loaded during
+# `pydicom` module initialization. We intentionally avoid using `collect_submodules` here, because that causes
+# import of `pydicom` with logging framework initialized, which results in error tracebacks being logged for all plugins
+# with missing libraries (see https://github.com/pydicom/pydicom/issues/2128).
+if is_module_satisfies('pydicom >= 3.0.0'):
+    hiddenimports += [
+        "pydicom.pixels.decoders.gdcm",
+        "pydicom.pixels.decoders.pylibjpeg",
+        "pydicom.pixels.decoders.pillow",
+        "pydicom.pixels.decoders.pyjpegls",
+        "pydicom.pixels.decoders.rle",
+        "pydicom.pixels.encoders.gdcm",
+        "pydicom.pixels.encoders.pylibjpeg",
+        "pydicom.pixels.encoders.native",
+        "pydicom.pixels.encoders.pyjpegls",
+    ]
+
+    # With pydicom 3.0.0, initialization of `pydicom` (unnecessarily) imports `pydicom.examples`, which attempts to set
+    # up several test datasets: https://github.com/pydicom/pydicom/blob/v3.0.0/src/pydicom/examples/__init__.py#L10-L24
+    # Some of those are bundled with the package itself, some are downloaded (into `.pydicom/data` directory in user's
+    # home directory) on he first `pydicom.examples` import.
+    #
+    # The download code requires `pydicom/data/urls.json` and `pydicom/data/hashes.json`; the lack of former results in
+    # run-time error, while the lack of latter results in warnings about dataset download failure.
+    #
+    # The test data files that are bundled with the package are not listed in `urls.json`, so if they are missing, there
+    # is not attempt to download them. Therefore, try to get away without collecting them here - if anyone actually
+    # requires them in the frozen application, let them explicitly collect them.
+    additional_data_patterns = [
+        'urls.json',
+        'hashes.json',
+    ]
+else:
+    hiddenimports += [
+        "pydicom.encoders.gdcm",
+        "pydicom.encoders.pylibjpeg",
+        "pydicom.encoders.native",
+    ]
+    additional_data_patterns = []
+
+# Collect data files from `pydicom.data`; charset files and palettes might be needed during processing, so always
+# collect them. Some other data files became required in v3.0.0 - the corresponding patterns are set accordingly in
+# `additional_data_patterns` in the above if/else block.
+datas += collect_data_files(
+    'pydicom.data',
+    includes=[
+        'charset_files/*',
+        'palettes/*',
+        *additional_data_patterns,
+    ],
+)
diff --git a/news/796.update.rst b/news/796.update.rst
new file mode 100644
index 00000000..0c15dfe9
--- /dev/null
+++ b/news/796.update.rst
@@ -0,0 +1,1 @@
+Update ``pydicom`` hook for compatibility with ``pydicom`` v.3.0.0.


Test patch:
diff --git a/requirements-test-libraries.txt b/requirements-test-libraries.txt
index d15ea399..e7677846 100644
--- a/requirements-test-libraries.txt
+++ b/requirements-test-libraries.txt
@@ -75,7 +75,7 @@ publicsuffix2==2.20191221
 pycparser==2.22
 pycryptodome==3.20.0
 pycryptodomex==3.20.0
-pydicom==2.4.4
+pydicom==3.0.0; python_version >= '3.10'
 pyexcelerate==0.12.0
 pyexcel_ods==0.6.0
 pylibmagic==0.5.0; sys_platform != 'win32'