So geben Sie in setup.py mehrere Autoren / E-Mails an

83

Wir haben einen kleinen Wrapper für eine Twitter-App geschrieben und diese Informationen auf http://pypi.python.org veröffentlicht . Setup.py enthielt jedoch nur ein einziges Feld zur Angabe der E-Mail-Adresse / des Namens des Autors. Wie gebe ich in den folgenden Feldern mehrere Mitwirkende / E-Mail-Listen an, da dieses Paket unter unseren Namen aufgeführt werden soll, ähnlich wie es in http://rubygems.org angezeigt wird .

   author='foo',
   author_email='[email protected]',
Priya
quelle
1
Akzeptieren sie durch Kommas oder Semikolon getrennte E-Mails?
Heltonbiker

Antworten:

82

Soweit ich weiß, setuptoolswird die Verwendung einer Liste von Zeichenfolgen zur Angabe mehrerer Autoren nicht unterstützt. Am besten listen Sie die Autoren in einer einzigen Zeichenfolge auf:

author='Foo Bar, Spam Eggs',
author_email='[email protected], [email protected]',

Ich bin mir nicht sicher, ob PyPI das author_emailFeld validiert , daher können Probleme mit diesem Feld auftreten. In jedem Fall würde ich empfehlen, diese auf einen einzigen Autor zu beschränken und alle Mitwirkenden in der Dokumentation oder Beschreibung zu erwähnen.

[Bearbeiten] Einige Quellen:

Dies wurde tatsächlich als Fehler registriert , aber es scheint, dass die Unterstützung für mehrere Autoren nicht implementiert wurde. Hier ist eine alternative Lösung. Hier finden Sie eine Idee, wie Sie eine Kontakt-E-Mail für ein Projekt mit mehreren Autoren bereitstellen können.

Modocache
quelle
1
+1 für die Bearbeitung und die zugehörigen Links ... Die Diskussion im Fehler ist wirklich interessant, aber es ist traurig, dass kein Konsens gefunden wurde und dass PEP 345 immer noch nicht von Best Practices und mehreren Autoren spricht
Stefano
1

Ich huckepack von der Antwort von @ modocache, falls Sie einige Details wünschen.

In dieser Antwort werde ich auf eine Python3.6-Version der FOO-PYTHON-ENV\Lib\distutils\dist.pyDatei verweisen

Zum Wiederholen können Sie keine Liste im authorFeld verwenden. Hier ist der Grund:

Spoiler: Zwei Methoden, die zur DistributionMetadataKlasse gehören, sind der Grund -

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

Hier tritt ein Fehler auf, wenn Sie versuchen, eine Liste in das authorFeld einzufügen:

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)...*#

& Hier ist das Ganze:

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
Rob Truxal
quelle