Returns a set containing all available time zones. .. caution:: This may attempt to open a large number of files, since the best way to determine if a given file on the time zone search path is to open it and check for the "magic string" at the beginning.
()
| 116 | |
| 117 | |
| 118 | def available_timezones(): |
| 119 | """Returns a set containing all available time zones. |
| 120 | |
| 121 | .. caution:: |
| 122 | |
| 123 | This may attempt to open a large number of files, since the best way to |
| 124 | determine if a given file on the time zone search path is to open it |
| 125 | and check for the "magic string" at the beginning. |
| 126 | """ |
| 127 | from importlib import resources |
| 128 | |
| 129 | valid_zones = set() |
| 130 | |
| 131 | # Start with loading from the tzdata package if it exists: this has a |
| 132 | # pre-assembled list of zones that only requires opening one file. |
| 133 | try: |
| 134 | zones_file = resources.files("tzdata").joinpath("zones") |
| 135 | with zones_file.open("r", encoding="utf-8") as f: |
| 136 | for zone in f: |
| 137 | zone = zone.strip() |
| 138 | if zone: |
| 139 | valid_zones.add(zone) |
| 140 | except (ImportError, FileNotFoundError): |
| 141 | pass |
| 142 | |
| 143 | def valid_key(fpath): |
| 144 | try: |
| 145 | with open(fpath, "rb") as f: |
| 146 | return f.read(4) == b"TZif" |
| 147 | except Exception: # pragma: nocover |
| 148 | return False |
| 149 | |
| 150 | for tz_root in TZPATH: |
| 151 | if not os.path.exists(tz_root): |
| 152 | continue |
| 153 | |
| 154 | for root, dirnames, files in os.walk(tz_root): |
| 155 | if root == tz_root: |
| 156 | # right/ and posix/ are special directories and shouldn't be |
| 157 | # included in the output of available zones |
| 158 | if "right" in dirnames: |
| 159 | dirnames.remove("right") |
| 160 | if "posix" in dirnames: |
| 161 | dirnames.remove("posix") |
| 162 | |
| 163 | for file in files: |
| 164 | fpath = os.path.join(root, file) |
| 165 | |
| 166 | key = os.path.relpath(fpath, start=tz_root) |
| 167 | if os.sep != "/": # pragma: nocover |
| 168 | key = key.replace(os.sep, "/") |
| 169 | |
| 170 | if not key or key in valid_zones: |
| 171 | continue |
| 172 | |
| 173 | if valid_key(fpath): |
| 174 | valid_zones.add(key) |
| 175 |
nothing calls this directly
no test coverage detected
searching dependent graphs…