import os import stat path = '/tmp/pytest' bytes_path = os.fsencode(path) os.mkdir(dirname) # Filename used for testing if os.name == 'java': # Jython disallows @ in module names TESTFN = '$test' else: TESTFN = '@test' # Disambiguate TESTFN for parallel testing, while letting it remain a valid # module name. TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid()) _can_symlink = None def can_symlink(): global _can_symlink if _can_symlink is not None: return _can_symlink symlink_path = TESTFN + "can_symlink" try: os.symlink(TESTFN, symlink_path) can = True except (OSError, NotImplementedError, AttributeError): can = False else: os.remove(symlink_path) _can_symlink = can return can def _create_file(filename, content=b'content'): with open(filename, "xb", 0) as fp: fp.write(content) def create_file(name="file.txt"): _path = bytes_path if isinstance(name, bytes) else path filename = os.path.join(_path, name) _create_file(filename, b'python') return filename def get_entries(names): entries = dict((entry.name, entry) for entry in os.scandir(path)) assert sorted(entries.keys()) == names return entries def assert_stat_equal(stat1, stat2, skip_fields): if skip_fields: for attr in dir(stat1): if not attr.startswith("st_"): continue if attr in ("st_dev", "st_ino", "st_nlink"): continue assert getattr(stat1, attr) == getattr(stat2, attr) == (stat1, stat2, attr) else: assert stat1 == stat2 def check_entry(entry, name, is_dir, is_file, is_symlink): assert isinstance(entry, os.DirEntry) assert entry.name == name assert entry.path == os.path.join(path, name) assert entry.inode() == os.stat(entry.path, follow_symlinks=False).st_ino entry_stat = os.stat(entry.path) assert entry.is_dir() == stat.S_ISDIR(entry_stat.st_mode) assert entry.is_file() == stat.S_ISREG(entry_stat.st_mode) assert entry.is_symlink() == os.path.islink(entry.path) entry_lstat = os.stat(entry.path, follow_symlinks=False) assert entry.is_dir(follow_symlinks=False) == stat.S_ISDIR(entry_lstat.st_mode) assert entry.is_file(follow_symlinks=False) == stat.S_ISREG(entry_lstat.st_mode) assert_stat_equal(entry.stat(), entry_stat, os.name == 'nt' and not is_symlink) assert_stat_equal(entry.stat(follow_symlinks=False), entry_lstat, os.name == 'nt') link = hasattr(os, 'link') symlink = can_symlink() dirname = os.path.join(path, "dir") os.mkdir(dirname) filename = create_file("file.txt") if link: os.link(filename, os.path.join(path, "link_file.txt")) if symlink: os.symlink(dirname, os.path.join(path, "symlink_dir"), target_is_directory=True) os.symlink(filename, os.path.join(path, "symlink_file.txt")) names = ['dir', 'file.txt'] if link: names.append('link_file.txt') if symlink: names.extend(('symlink_dir', 'symlink_file.txt')) entries = get_entries(names) entry = entries['dir'] check_entry(entry, 'dir', True, False, False) entry = entries['file.txt'] check_entry(entry, 'file.txt', False, True, False) if link: entry = entries['link_file.txt'] check_entry(entry, 'link_file.txt', False, True, False) if symlink: entry = entries['symlink_dir'] check_entry(entry, 'symlink_dir', True, False, True) entry = entries['symlink_file.txt'] check_entry(entry, 'symlink_file.txt', False, True, True)