PathInfo implementation for an existing zip file member.
| 116 | |
| 117 | |
| 118 | class ZipPathInfo(PathInfo): |
| 119 | """ |
| 120 | PathInfo implementation for an existing zip file member. |
| 121 | """ |
| 122 | __slots__ = ('zip_file', 'zip_info', 'parent', 'children') |
| 123 | |
| 124 | def __init__(self, zip_file, parent=None): |
| 125 | self.zip_file = zip_file |
| 126 | self.zip_info = None |
| 127 | self.parent = parent or self |
| 128 | self.children = {} |
| 129 | |
| 130 | def exists(self, follow_symlinks=True): |
| 131 | if follow_symlinks and self.is_symlink(): |
| 132 | return self.resolve().exists() |
| 133 | return True |
| 134 | |
| 135 | def is_dir(self, follow_symlinks=True): |
| 136 | if follow_symlinks and self.is_symlink(): |
| 137 | return self.resolve().is_dir() |
| 138 | elif self.zip_info is None: |
| 139 | return True |
| 140 | elif fmt := S_IFMT(self.zip_info.external_attr >> 16): |
| 141 | return S_ISDIR(fmt) |
| 142 | else: |
| 143 | return self.zip_info.filename.endswith('/') |
| 144 | |
| 145 | def is_file(self, follow_symlinks=True): |
| 146 | if follow_symlinks and self.is_symlink(): |
| 147 | return self.resolve().is_file() |
| 148 | elif self.zip_info is None: |
| 149 | return False |
| 150 | elif fmt := S_IFMT(self.zip_info.external_attr >> 16): |
| 151 | return S_ISREG(fmt) |
| 152 | else: |
| 153 | return not self.zip_info.filename.endswith('/') |
| 154 | |
| 155 | def is_symlink(self): |
| 156 | if self.zip_info is None: |
| 157 | return False |
| 158 | elif fmt := S_IFMT(self.zip_info.external_attr >> 16): |
| 159 | return S_ISLNK(fmt) |
| 160 | else: |
| 161 | return False |
| 162 | |
| 163 | def resolve(self, path=None, create=False, follow_symlinks=True): |
| 164 | """ |
| 165 | Traverse zip hierarchy (parents, children and symlinks) starting |
| 166 | from this PathInfo. This is called from three places: |
| 167 | |
| 168 | - When a zip file member is added to ZipFile.filelist, this method |
| 169 | populates the ZipPathInfo tree (using create=True). |
| 170 | - When ReadableZipPath.info is accessed, this method is finds a |
| 171 | ZipPathInfo entry for the path without resolving any final symlink |
| 172 | (using follow_symlinks=False) |
| 173 | - When ZipPathInfo methods are called with follow_symlinks=True, this |
| 174 | method resolves any symlink in the final path position. |
| 175 | """ |