Cách chỉ định nhiều (các) tác giả / (các) email trong setup.py


82

Chúng tôi đã viết một trình bao bọc nhỏ cho một ứng dụng twitter và xuất bản thông tin này lên http://pypi.python.org . Nhưng setup.py chỉ chứa một trường duy nhất để chỉ định email / tên của tác giả. Làm cách nào để chỉ định nhiều người đóng góp / danh sách email, vào các trường sau vì chúng tôi muốn gói này được liệt kê dưới tên của chúng tôi, giống với cách nó hiển thị trong http://rubygems.org .

   author='foo',
   author_email='foo.bar@gmail.com',

1
Họ có chấp nhận các email được phân tách bằng dấu phẩy hoặc dấu chấm phẩy không?
heltonbiker

Câu trả lời:


81

Theo như tôi biết, setuptoolskhông hỗ trợ sử dụng danh sách các chuỗi để chỉ định nhiều tác giả. Đặt cược tốt nhất của bạn là liệt kê các tác giả trong một chuỗi duy nhất:

author='Foo Bar, Spam Eggs',
author_email='foobar@baz.com, spameggs@joe.org',

Tôi không chắc liệu PyPI có xác thực author_email trường hay không, vì vậy bạn có thể gặp rắc rối với trường đó. Trong mọi trường hợp, tôi khuyên bạn nên giới hạn những điều này ở một tác giả duy nhất và đề cập đến tất cả những người đóng góp trong tài liệu hoặc mô tả.

[Chỉnh sửa] Một số nguồn:

Thực ra, điều này đã được ghi nhận là một lỗi , nhưng có vẻ như hỗ trợ cho nhiều tác giả đã không được triển khai. Đây là một giải pháp thay thế. Đây là ý tưởng về cách cung cấp email liên hệ cho một dự án có nhiều tác giả.


1
+1 cho bản chỉnh sửa và các liên kết có liên quan ... Cuộc thảo luận về lỗi này thực sự thú vị, nhưng thật đáng buồn là dường như không có sự đồng thuận nào được tìm thấy và PEP 345 vẫn không nói về các phương pháp hay nhất và nhiều tác giả
Stefano

0

Tôi chỉ tóm tắt câu trả lời của @ modocache, trong trường hợp bạn muốn một số chi tiết cụ thể.

Trong suốt câu trả lời này, tôi sẽ tham khảo phiên bản python3.6 của FOO-PYTHON-ENV\Lib\distutils\dist.pytệp

Để nhắc lại, bạn không thể sử dụng danh sách trong authortrường. Đây là lý do tại sao:

Spoiler: Hai phương thức thuộc DistributionMetadatalớp là lý do -

def _read_field(name):
    value = msg[name]
    if value == 'UNKNOWN':
        return None
    return value

def _read_list(name):
    values = msg.get_all(name, None)
    if values == []:
        return None
    return values

Đây là nơi bạn sẽ gặp lỗi nếu bạn cố gắng đưa một danh sách vào authortrường:

class DistributionMetadata:

#*...(R E D A C T E D)...*#

    def read_pkg_file(self, file):
        """Reads the metadata values from a file object."""
    #*...(R E D A C T E D)...*#
        # ####################################
        # Note the usage of _read_field() here
        # ####################################
        self.name = _read_field('name')
        self.version = _read_field('version')
        self.description = _read_field('summary')
        # we are filling author only.
        self.author = _read_field('author')
        self.maintainer = None
        self.author_email = _read_field('author-email')
        self.maintainer_email = None
        self.url = _read_field('home-page')
        self.license = _read_field('license')
    #*...(R E D A C T E D)...*#
        # ###################################
        # Note the usage of _read_list() here
        # ###################################
        self.platforms = _read_list('platform')
        self.classifiers = _read_list('classifier')
    #*...(R E D A C T E D)...*#

& Đây là toàn bộ điều:

class DistributionMetadata:
        """Dummy class to hold the distribution meta-data: name, version,
        author, and so forth.
        """

        _METHOD_BASENAMES = ("name", "version", "author", "author_email",
                     "maintainer", "maintainer_email", "url",
                     "license", "description", "long_description",
                     "keywords", "platforms", "fullname", "contact",
                     "contact_email", "classifiers", "download_url",
                     # PEP 314
                     "provides", "requires", "obsoletes",
                     )

    def __init__(self, path=None):
        if path is not None:
            self.read_pkg_file(open(path))
        else:
            self.name = None
            self.version = None
            self.author = None
            self.author_email = None
            self.maintainer = None
            self.maintainer_email = None
            self.url = None
            self.license = None
            self.description = None
            self.long_description = None
            self.keywords = None
            self.platforms = None
            self.classifiers = None
            self.download_url = None
            # PEP 314
            self.provides = None
            self.requires = None
            self.obsoletes = None

    def read_pkg_file(self, file):
        """Reads the metadata values from a file object."""
        msg = message_from_file(file)

        def _read_field(name):
            value = msg[name]
            if value == 'UNKNOWN':
                return None
            return value

        def _read_list(name):
            values = msg.get_all(name, None)
            if values == []:
                return None
            return values

        metadata_version = msg['metadata-version']
        self.name = _read_field('name')
        self.version = _read_field('version')
        self.description = _read_field('summary')
        # we are filling author only.
        self.author = _read_field('author')
        self.maintainer = None
        self.author_email = _read_field('author-email')
        self.maintainer_email = None
        self.url = _read_field('home-page')
        self.license = _read_field('license')

        if 'download-url' in msg:
            self.download_url = _read_field('download-url')
        else:
            self.download_url = None

        self.long_description = _read_field('description')
        self.description = _read_field('summary')

        if 'keywords' in msg:
            self.keywords = _read_field('keywords').split(',')

        self.platforms = _read_list('platform')
        self.classifiers = _read_list('classifier')

        # PEP 314 - these fields only exist in 1.1
        if metadata_version == '1.1':
            self.requires = _read_list('requires')
            self.provides = _read_list('provides')
            self.obsoletes = _read_list('obsoletes')
        else:
            self.requires = None
            self.provides = None
            self.obsoletes = None
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.