Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

307
Views
How to specify requirements in Python packages metadata

Core metadata specification documents the metadata field Requires-External which seems to be for specifying system (non-python) dependencies.

How do you actually specify this field though? This is what I've tried:

.
├── mypackage
│   └── __init__.py
└── setup.py

Contents of setup.py

from setuptools import setup

setup(
    name="mypackage",
    description="blah blah",
    url='https://example.org',
    version="0.1",
    packages=["mypackage"],
    requires_external=[
        "C",
        "libpng (>=1.5)",
        'make; sys_platform != "win32"',
    ],
)

When I build this package, that metadata was not included

Metadata-Version: 2.1
Name: mypackage
Version: 0.1
Summary: blah blah
Home-page: https://example.org
License: UNKNOWN
Platform: UNKNOWN

UNKNOWN

So what is the syntax to pass Requires-External to setuptools/distutils? Note: this question is not asking about Requires-Dist metadata.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

So what is the syntax to pass Requires-External to setuptools/distutils?

There is none by default, as neither distutils nor setuptools support the field. Also, requires_external keyword arg is not supported as well - it is silently ignored, just as any other unknown keyword arg.

To add local support for requires_external kwarg, you need to provide your own distribution implementation. Minimal example (requires Python 3.9):

from setuptools.dist import Distribution as DistributionOrig

class Distribution(DistributionOrig):
    _DISTUTILS_UNSUPPORTED_METADATA = DistributionOrig._DISTUTILS_UNSUPPORTED_METADATA | {'requires_external': dict}

You can now pass requires_external to setup() when paired with distclass:

setup(
    ...,
    requires_external=[
        'C',
        'libpng (>=1.5)',
        'make; sys_platform != "win32"',
    ],
    distclass=Distribution,
)

The next goal is to actually write the contents of requires_external to PKG-INFO. This is quite tricky to do via distribution metadata itself because setuptools patches the relevant methods (DistributionMetadata.read_pkg_file() and DistributionMetadata.write_pkg_file()) with own monolithic impls. The easiest way for this IMO is to modify PKG-INFO post factum via a custom egg_info impl:

import email
from pathlib import Path
from setuptools.command.egg_info import egg_info as egg_info_orig


class egg_info(egg_info_orig):
    def run(self):
        super().run()
        # PKG-INFO is now guaranteed to exist
        pkg_info_file = Path(self.egg_info, 'PKG-INFO')
        pkg_info = email.message_from_bytes(pkg_info_file.read_bytes())
        for req in self.distribution.metadata.requires_external:
            pkg_info.add_header('Requires-External', req)
        pkg_info_file.write_bytes(pkg_info.as_bytes())

Pass your own egg_info impl via cmdclass argument in setup():

setup(
    ...,
    requires_external=[
        'C',
        'libpng (>=1.5)',
        'make; sys_platform != "win32"',
    ],
    distclass=Distribution,
    cmdclass={'egg_info': egg_info},
)
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!