2525import importlib .machinery
2626import sys
2727import warnings
28+ from dataclasses import dataclass
2829from pathlib import Path
29- from typing import Optional , Set , Generator , Tuple , Sequence , Iterable , Union
30+ from typing import Optional , Set , Generator , Sequence , Iterable , Union
3031
3132from .line import (
3233 current_word ,
4748 ),
4849)
4950
51+ _LOADED_INODE_DATACLASS_ARGS = {"frozen" : True }
52+ if sys .version_info [2 :] >= (3 , 10 ):
53+ _LOADED_INODE_DATACLASS_ARGS ["slots" ] = True
54+
55+
56+ @dataclass (** _LOADED_INODE_DATACLASS_ARGS )
57+ class _LoadedInode :
58+ dev : int
59+ inode : int
60+
5061
5162class ModuleGatherer :
5263 def __init__ (
@@ -60,7 +71,7 @@ def __init__(
6071 # Cached list of all known modules
6172 self .modules : Set [str ] = set ()
6273 # Set of (st_dev, st_ino) to compare against so that paths are not repeated
63- self .paths : Set [Tuple [ int , int ] ] = set ()
74+ self .paths : Set [_LoadedInode ] = set ()
6475 # Patterns to skip
6576 self .skiplist : Sequence [str ] = (
6677 skiplist if skiplist is not None else tuple ()
@@ -216,8 +227,9 @@ def find_modules(self, path: Path) -> Generator[Optional[str], None, None]:
216227 stat = path_real .stat ()
217228 except OSError :
218229 continue
219- if (stat .st_dev , stat .st_ino ) not in self .paths :
220- self .paths .add ((stat .st_dev , stat .st_ino ))
230+ loaded_inode = _LoadedInode (stat .st_dev , stat .st_ino )
231+ if loaded_inode not in self .paths :
232+ self .paths .add (loaded_inode )
221233 for subname in self .find_modules (path_real ):
222234 if subname is None :
223235 yield None # take a break to avoid unresponsiveness
0 commit comments