Reference#

build#

Create .conda packages from wheels.

Create wheels from pypa projects.

conda_pypi.build.build_conda(whl, build_path, output_path, python_executable, project_path=None, test_dir=None, is_editable=False, pypi_to_conda_name_mapping=None)[source]#
Parameters:
  • build_path (Path)

  • output_path (Path)

  • project_path (Path | None)

  • test_dir (Path | None)

  • pypi_to_conda_name_mapping (dict | None)

Return type:

Path

conda_pypi.build.build_pypa(path, output_path, prefix, distribution='editable')[source]#
Parameters:
  • distribution – “editable” or “wheel”

  • path (Path)

  • prefix (Path)

conda_pypi.build.filter(tarinfo)[source]#

Anonymize uid/gid; exclude .git directories.

conda_pypi.build.flatten(iterable)[source]#
conda_pypi.build.json_dumps(object)[source]#

Consistent json formatting.

conda_pypi.build.paths_json(base)[source]#

Build simple paths.json with only ‘hardlink’ or ‘symlink’ types.

Parameters:

base (Path | str)

conda_pypi.build.pypa_to_conda(project, prefix, distribution='editable', output_path=None, test_dir=None, pypi_to_conda_name_mapping=None)[source]#
Parameters:
  • prefix (Path)

  • output_path (Path | None)

  • test_dir (Path | None)

  • pypi_to_conda_name_mapping (dict | None)

conda_pypi.build.update_RECORD(record_path, base_path, changed_path)[source]#

Rewrite RECORD with new size, checksum for updated_file.

Parameters:
  • record_path (Path)

  • base_path (Path)

  • changed_path (Path)

conda_build_utils#

class conda_pypi.conda_build_utils.PathType(value)[source]#

Bases: Enum

Refers to if the file in question is hard linked or soft linked. Originally designed to be used in paths.json

directory = 'directory'#
linked_package_record = 'linked_package_record'#
pyc_file = 'pyc_file'#
unix_python_entry_point = 'unix_python_entry_point'#
windows_python_entry_point_exe = 'windows_python_entry_point_exe'#
windows_python_entry_point_script = 'windows_python_entry_point_script'#
conda_pypi.conda_build_utils.sha256_checksum(filename, entry=None, buffersize=262144)[source]#
Parameters:

entry (DirEntry | None)

translate#

Convert Python *.dist-info/METADATA to conda info/index.json

class conda_pypi.translate.CondaMetadata(metadata: importlib.metadata._meta.PackageMetadata, console_scripts: List[str], package_record: conda_pypi.translate.PackageRecord, about: Dict[str, Any])[source]#

Bases: object

Parameters:
  • metadata (PackageMetadata)

  • console_scripts (List[str])

  • package_record (PackageRecord)

  • about (Dict[str, Any])

about: Dict[str, Any]#
console_scripts: List[str]#
classmethod from_distribution(distribution, pypi_to_conda_name_mapping=None)[source]#
Parameters:
  • distribution (Distribution)

  • pypi_to_conda_name_mapping (dict | None)

info/link.json used for console scripts; None if empty.

Note the METADATA file aka PackageRecord does not list console scripts.

Return type:

dict | None

metadata: PackageMetadata#
package_record: PackageRecord#
class conda_pypi.translate.FileDistribution(raw_text)[source]#

Bases: Distribution

From a file e.g. a single .metadata fetched from pypi instead of a *.dist-info folder.

locate_file(path)[source]#

Given a path to a file in this distribution, return a path to it.

read_text(filename)[source]#

Attempt to load metadata file given by the name.

Parameters:

filename (str) – The name of the file in the distribution info.

Returns:

The text if found, otherwise None.

Return type:

str | None

class conda_pypi.translate.PackageRecord(name: str, version: str, subdir: str, depends: List[str], extras: Dict[str, List[str]], build_number: int = 0, build_text: str = 'pypi', license_family: str = '', license: str = '', noarch: str = '', timestamp: int = 0)[source]#

Bases: object

Parameters:
  • name (str)

  • version (str)

  • subdir (str)

  • depends (List[str])

  • extras (Dict[str, List[str]])

  • build_number (int)

  • build_text (str)

  • license_family (str)

  • license (str)

  • noarch (str)

  • timestamp (int)

property build#
build_number: int = 0#
build_text: str = 'pypi'#
depends: List[str]#
extras: Dict[str, List[str]]#
license: str = ''#
license_family: str = ''#
name: str#
noarch: str = ''#
property stem#
subdir: str#
timestamp: int = 0#
to_index_json()[source]#
version: str#
conda_pypi.translate.conda_to_requires(match_spec)[source]#
Parameters:

match_spec (MatchSpec)

Return type:

Requirement | None

conda_pypi.translate.remap_match_spec_name(match_spec, name_map)[source]#
Parameters:
  • match_spec (MatchSpec)

  • name_map (Callable[[str], str])

Return type:

MatchSpec

conda_pypi.translate.requires_to_conda(requires, pypi_to_conda_name_mapping=None)[source]#
Parameters:
  • requires (List[str] | None)

  • pypi_to_conda_name_mapping (dict | None)

conda_pypi.translate.validate_name_mapping_format(mapping)[source]#

Validate that the name mapping dict has the correct format.

Expected format: - A dict where keys are PyPI package names (strings) - Values are dicts with at least “conda_name” key (string) - Optionally can have “pypi_name”, “import_name”, “mapping_source” keys - Empty dict is allowed

Raises ArgumentError if format is invalid.

Parameters:

mapping (dict)

Return type:

None

name_mapping#

PyPI ↔ conda package name mapping.

The default table is grayskull_pypi_mapping.json (regro/grayskull). Keys are canonical PyPI names, resolved the same way as the table via packaging.utils.canonicalize_name().

When a name is missing from the table, the conda name is derived from the original string: lowercase, underscores become hyphens, dots are unchanged. That often matches conda-forge dotted packages; canonical form alone would map jaraco.tidelift to jaraco-tidelift.

Grayskull (or a custom dict for pypi_to_conda_name()) is still required when the conda package name does not follow that rule, for example typing-extensionstyping_extensions.

conda_pypi.name_mapping.conda_to_pypi_name(name)[source]#
Parameters:

name (str)

Return type:

str

conda_pypi.name_mapping.pypi_to_conda_name(pypi_name, pypi_to_conda_name_mapping=None)[source]#
Parameters:
  • pypi_name (str)

  • pypi_to_conda_name_mapping (dict | None)

Return type:

str

markers#

Marker conversion.

Marker conversion includes: - Convert Python markers to python… matchspec fragments, including

python_version not in “x, y” -> (python!=x and python!=y).

  • Convert platform/os markers to virtual packages when feasible (__win, __linux, __osx, __unix).

  • Keep extras in extra_depends, with remaining non-extra marker logic encoded via [when=”…”].

  • Drop unsupported marker dimensions (for example interpreter/machine-specific variants) for these noarch channel tests.

class conda_pypi.markers.MarkerOp(value)[source]#

Bases: StrEnum

An enumeration.

EQ = '=='#
NE = '!='#
NOT_IN = 'not in'#
class conda_pypi.markers.MarkerVar(value)[source]#

Bases: StrEnum

An enumeration.

EXTRA = 'extra'#
IMPLEMENTATION_NAME = 'implementation_name'#
OS_NAME = 'os_name'#
PLATFORM_MACHINE = 'platform_machine'#
PLATFORM_PYTHON_IMPLEMENTATION = 'platform_python_implementation'#
PLATFORM_SYSTEM = 'platform_system'#
PYTHON_FULL_VERSION = 'python_full_version'#
PYTHON_VERSION = 'python_version'#
SYS_PLATFORM = 'sys_platform'#
class conda_pypi.markers.StrEnum(value)[source]#

Bases: str, Enum

An enumeration.

conda_pypi.markers.dependency_extras_suffix(requirement_extras)[source]#

Bracket suffix for conda MatchSpec optional dependency extras (PEP 508 extras).

Output order is sorted for stability.

Parameters:

requirement_extras (set[str] | frozenset[str])

Return type:

str

conda_pypi.markers.dependency_when(dependency, condition)[source]#
Parameters:
  • dependency (str)

  • condition (str | None)

Return type:

str

conda_pypi.markers.extract_marker_condition_and_extras(marker)[source]#

Split a Marker into optional non-extra condition and extra group names.

Examples: - extra == “docs” -> (None, [“docs”]) - python_version < “3.11” and extra == “test” -> (“python<3.11”, [“test”]) - sys_platform == “win32” -> (“__win”, [])

Parameters:

marker (Marker)

Return type:

tuple[str | None, list[str]]

conda_pypi.markers.pypi_to_repodata_noarch_whl_entry(pypi_data, pypi_to_conda_name_mapping=None)[source]#

Convert PyPI JSON API payload to a repodata.json v3.whl entry for a pure-Python wheel.

Dependency and record names use pypi_to_conda_name (same default table and unmapped-name fallback as conda_pypi.translate.requires_to_conda()). depends / extra_depends strings keep PEP 508 optional extras and specifier spelling. .whl.conda conversion uses conda_dep_string_from_pep508_requirement() instead. This repodata path may emit [when=…], wheel conversion does not until conda has support for [when=”…”] syntax in MatchSpec.

Parameters:
  • pypi_data (dict[str, Any])

  • pypi_to_conda_name_mapping (dict | None)

Return type:

dict[str, Any] | None

editable#

Convert a dependency tree from pypi into .conda packages

class conda_pypi.convert_tree.ConvertTree(prefix, override_channels=False, repo=None, finder=None)[source]#

Bases: object

Parameters:
  • prefix (Optional[Union[pathlib.Path, str]])

  • repo (Optional[pathlib.Path])

  • finder (Optional[PackageFinder])

convert_tree(requested, max_attempts=80)[source]#

Preform a solve on the list of requested packages and converts the full dependency tree to conda packages if required. The converted packages will be stored in the local conda-pypi channel.

Parameters:
  • requested (List[MatchSpec]) – The list of requested packages.

  • max_attempts (int) – max number of times to try to execute the solve.

Returns:

A two-tuple of PackageRef sequences. The first is the group of packages to remove from the environment, in sorted dependency order from leaves to roots. The second is the group of packages to add to the environment, in sorted dependency order from roots to leaves.

Return type:

tuple[tuple[PrefixRecord, …], tuple[PrefixRecord, …]] | None

default_package_finder()[source]#
conda_pypi.convert_tree.parse_libmamba_solver_error(message)[source]#

Parse missing packages out of UnsatisfiableError message.

Parameters:

message (str)

conda_pypi.convert_tree.parse_rattler_solver_error(message)[source]#

Parse missing packages out of UnsatisfiableError message.

Parameters:

message (str)

index#

Interface to conda-index.

conda_pypi.index.update_index(path)[source]#

installer#

Install a wheel / install a conda.

conda_pypi.installer.install_ephemeral_conda(prefix, package)[source]#

Install [editable] conda package without adding it to the environment’s package cache, since we don’t want to accidentally re-install “a link to a source checkout” elsewhere.

Installing packages directly from a file does not resolve dependencies. Should we automatically install the project’s dependencies also?

Parameters:
  • prefix (Path)

  • package (Path)

conda_pypi.installer.install_installer(python_executable, whl, build_path)[source]#
Parameters:
  • python_executable (str)

  • whl (Path)

  • build_path (Path)

conda_pypi.installer.install_pip(python_executable, whl, build_path)[source]#
Parameters:
  • python_executable (str)

  • whl (Path)

  • build_path (Path)

downloader#

Fetch matching wheels from pypi.

conda_pypi.downloader.find_and_fetch(finder, target, package)[source]#

Find package on PyPI, download best link to target.

Parameters:
  • finder (PackageFinder)

  • target (Path)

  • package (str)

Return type:

Path

conda_pypi.downloader.find_package(finder, package)[source]#

Convert :package: to MatchSpec; return best Link.

Parameters:
  • finder (PackageFinder)

  • package (str)

conda_pypi.downloader.get_package_finder(prefix, index_urls=('https://pypi.org/simple/',))[source]#

Finder with prefix’s Python, not our Python.

Parameters:
  • prefix (Path)

  • index_urls (Iterable[str])

Return type:

PackageFinder