| 331 | |
| 332 | @classmethod |
| 333 | def decode(cls, encoded): |
| 334 | # type: (Text) -> PythonIdentity |
| 335 | TRACER.log("creating PythonIdentity from encoded: {encoded}".format(encoded=encoded), V=9) |
| 336 | values = json.loads(encoded) |
| 337 | if len(values) != 20: |
| 338 | raise cls.InvalidError( |
| 339 | "Invalid interpreter identity: {encoded}".format(encoded=encoded) |
| 340 | ) |
| 341 | try: |
| 342 | format_version = int(values.pop("__format_version__", "0")) |
| 343 | except ValueError as e: |
| 344 | raise cls.InvalidError( |
| 345 | "The PythonIdentity __format_version__ is invalid: {err}".format(err=e) |
| 346 | ) |
| 347 | else: |
| 348 | if format_version < cls._FORMAT_VERSION: |
| 349 | raise cls.InvalidError( |
| 350 | "The PythonIdentity __format_version__ was {format_version}, but the current " |
| 351 | "version is {current_version}. Upgrading existing encoding: {encoded}".format( |
| 352 | format_version=format_version, |
| 353 | current_version=cls._FORMAT_VERSION, |
| 354 | encoded=encoded, |
| 355 | ) |
| 356 | ) |
| 357 | |
| 358 | version = tuple(values.pop("version")) |
| 359 | pypy_version = tuple(values.pop("pypy_version") or ()) or None |
| 360 | |
| 361 | supported_tags = values.pop("supported_tags") |
| 362 | |
| 363 | def iter_tags(): |
| 364 | for (interpreter, abi, platform) in supported_tags: |
| 365 | yield tags.Tag(interpreter=interpreter, abi=abi, platform=platform) |
| 366 | |
| 367 | # N.B.: Old encoded identities may have numeric values; so we support these and convert |
| 368 | # back to strings here as needed. See: https://github.com/pex-tool/pex/issues/1337 |
| 369 | configured_macosx_deployment_target = cls._normalize_macosx_deployment_target( |
| 370 | values.pop("configured_macosx_deployment_target") |
| 371 | ) |
| 372 | |
| 373 | env_markers = MarkerEnvironment(**values.pop("env_markers")) |
| 374 | |
| 375 | site_packages_paths = values.pop("site_packages") |
| 376 | purelib = values.pop("purelib") |
| 377 | platlib = values.pop("platlib") |
| 378 | site_packages = [] # type: List[SitePackagesDir] |
| 379 | for path in site_packages_paths: |
| 380 | if path == purelib: |
| 381 | site_packages.append(Purelib(_adjust_to_current_path(path))) |
| 382 | elif path == platlib: |
| 383 | site_packages.append(Platlib(_adjust_to_current_path(path))) |
| 384 | else: |
| 385 | site_packages.append(SitePackagesDir(_adjust_to_current_path(path))) |
| 386 | |
| 387 | return cls( |
| 388 | binary=_adjust_to_current_path(values.pop("binary")), |
| 389 | prefix=_adjust_to_current_path(values.pop("prefix")), |
| 390 | base_prefix=_adjust_to_current_path(values.pop("base_prefix")), |