1"""Provides a function to report all internal modules for using freezing

2 tools."""

3 import types

4 from typing import Iterator

5 from typing import List

6 from typing import Union

7

8

9 def freeze_includes() -> List[str]:

10 """Return a list of module names used by pytest that should be

11 included by cx_freeze."""

12 import _pytest

13

14 result = list(_iter_all_modules(_pytest))

15 return result

16

17

18 def _iter_all_modules(

19 package: Union[str, types.ModuleType],

20 prefix: str = "",

21) -> Iterator[str]:

22 """Iterate over the names of all modules that can be found in the given

23 package, recursively.

24

25 >>> import _pytest

26 >>> list(_iter_all_modules(_pytest))

27 ['_pytest._argcomplete', '_pytest._code.code', ...]

28 """

29 import os

30 import pkgutil

31

32 if isinstance(package, str):

33 path = package

34 else:

35 # Type ignored because typeshed doesn't define ModuleType.__path__

36 # (only defined on packages).

37 package_path = package.__path__ # type: ignore[attr-defined]

38 path, prefix = package_path[0], package.__name__ + "."

39 for _, name, is_package in pkgutil.iter_modules([path]):

40 if is_package:

41 for m in _iter_all_modules(os.path.join(path, name), prefix=name + "."):

42 yield prefix + m

43 else:

44 yield prefix + name