python distutils: कैसे एक उपयोगकर्ता परिभाषित पैरामीटर setup.py करने के लिए पारित करने के लिए?




(6)

मैंने टोटैम के सुझाव के समान समाधान का उपयोग करने के लिए वर्कअराउंड का सफलतापूर्वक उपयोग किया। मैंने sys.argv सूची से अपने अतिरिक्त तर्क को समाप्त कर दिया:

import sys
from distutils.core import setup
foo = 0
if '--foo' in sys.argv:
    index = sys.argv.index('--foo')
    sys.argv.pop(index)  # Removes the '--foo'
    foo = sys.argv.pop(index)  # Returns the element after the '--foo'
# The foo is now ready to use for the setup
setup(...)

इनपुट्स अच्छे हैं, यह सुनिश्चित करने के लिए कुछ अतिरिक्त मान्यता जोड़ी जा सकती है, लेकिन मैंने इसे कैसे किया

कृपया मुझे संकेत दें कि कमांड लाइन और setup.cfg कॉन्फ़िगरेशन फ़ाइल से डिस्टिल्ट्स सेटअप स्क्रिप्ट में उपयोगकर्ता-परिभाषित पैरामीटर कैसे पास किया जाए। मैं एक सेटअप एरो स्क्रिप्ट लिखना चाहता हूं, जो मेरे पैकेज विशिष्ट मापदंडों को स्वीकार करता है। उदाहरण के लिए:

python setup.py install -foo myfoo

धन्यवाद,
Mher


शायद आप मेरे जैसे एक अप्रशिक्षित प्रोग्रामर हैं जो अभी भी उपरोक्त सभी उत्तरों को पढ़ने के बाद संघर्ष कर रहे हैं। इस प्रकार, आपको संभावित रूप से सहायक एक और उदाहरण मिल सकता है ( और कमांड लाइन आर्ग्युमेंट्स में प्रवेश करने के बारे में पिछले उत्तरों में टिप्पणियों को संबोधित करने के लिए ):

class RunClientCommand(Command):
    """
    A command class to runs the client GUI.
    """

    description = "runs client gui"

    # The format is (long option, short option, description).
    user_options = [
        ('socket=', None, 'The socket of the server to connect (e.g. '127.0.0.1:8000')',
    ]

    def initialize_options(self):
        """
        Sets the default value for the server socket.

        The method is responsible for setting default values for
        all the options that the command supports.

        Option dependencies should not be set here.
        """
        self.socket = '127.0.0.1:8000'

    def finalize_options(self):
        """
        Overriding a required abstract method.

        The method is responsible for setting and checking the 
        final values and option dependencies for all the options 
        just before the method run is executed.

        In practice, this is where the values are assigned and verified.
        """
        pass

    def run(self):
        """
        Semantically, runs 'python src/client/view.py SERVER_SOCKET' on the
        command line.
        """
        print(self.socket)
        errno = subprocess.call([sys.executable, 'src/client/view.py ' + self.socket])
        if errno != 0:
            raise SystemExit("Unable to run client GUI!")
setup(
    # Some other omitted details
    cmdclass={
        'runClient': RunClientCommand,
    },

ऊपर परीक्षण किया गया है और कुछ कोड से मैंने लिखा है। मैंने चीजों को समझने में आसान बनाने के लिए थोड़ा और विस्तृत डॉकस्ट्रिंग्स को भी शामिल किया है।

जैसा कि कमांड लाइन के लिए: python setup.py runClient --socket=127.0.0.1:7777 । प्रिंट स्टेटमेंट्स का उपयोग करके एक त्वरित डबल चेक दिखाता है कि वास्तव में सही तर्क रन विधि द्वारा उठाया गया है।

अन्य संसाधन जो मुझे उपयोगी लगे ( अधिक से अधिक उदाहरण):

this

https://seasonofcode.com/posts/how-to-add-custom-build-steps-and-commands-to-setuppy.html


जैसा कि सेप्टुपूलस / डिस्टिल्स को बहुत ही बुरे तरीके से प्रलेखित किया गया है, मुझे स्वयं इस बात का उत्तर खोजने में समस्याएँ थीं। लेकिन आखिरकार मैं this उदाहरण से लड़खड़ा गया। साथ ही, this समान प्रश्न सहायक था। असल में, एक विकल्प के साथ एक कस्टम कमांड की तरह दिखेगा:

from distutils.core import setup, Command

class InstallCommand(Command):
    description = "Installs the foo."
    user_options = [
        ('foo=', None, 'Specify the foo to bar.'),
    ]
    def initialize_options(self):
        self.foo = None
    def finalize_options(self):
        assert self.foo in (None, 'myFoo', 'myFoo2'), 'Invalid foo!'
    def run(self):
        install_all_the_things()

setup(
    ...,
    cmdclass={
        'install': InstallCommand,
    }
)

आप वास्तव में स्क्रिप्ट के लिए कस्टम पैरामीटर पास नहीं कर सकते। हालाँकि निम्नलिखित बातें संभव हैं और आपकी समस्या को हल कर सकती हैं:

  • वैकल्पिक सुविधाओं को --with-featurename का उपयोग करके सक्षम किया जा सकता है, मानक सुविधाओं को --without-featurename उपयोग से अक्षम किया जा सकता है। [AFAIR के लिए इसके सेट की आवश्यकता है]
  • आप पर्यावरण चर का उपयोग कर सकते हैं, हालांकि इनको विंडोज़ पर set करने की आवश्यकता होती है, जबकि उपसर्ग उन्हें लिनक्स / OS X ( FOO=bar python setup.py ) पर काम करता है।
  • आप अपने स्वयं के cmd_class es के साथ cmd_class विस्तार कर सकते हैं जो नई सुविधाओं को लागू कर सकते हैं। वे श्रृंखलाबद्ध भी हैं, इसलिए आप इसका उपयोग अपनी स्क्रिप्ट में चर बदलने के लिए कर सकते हैं। ( python setup.py foo install ) python setup.py foo install से पहले foo कमांड निष्पादित करेगा।

आशा है कि किसी तरह मदद करता है। आम तौर पर बोलते हुए मैं थोड़ा और जानकारी प्रदान करने का सुझाव दूंगा कि वास्तव में आपके अतिरिक्त पैरामीटर को क्या करना चाहिए, शायद एक बेहतर समाधान उपलब्ध है।


हां, यह 2015 है और setuptools और setuptools दोनों में कमांड और विकल्प जोड़ने के लिए दस्तावेज अभी भी काफी हद तक गायब है।

कुछ निराशाजनक घंटों के बाद, मैंने install कोड के setup.py कमांड में एक कस्टम विकल्प जोड़ने के लिए निम्नलिखित कोड का पता लगाया:

from setuptools.command.install import install


class InstallCommand(install):
    user_options = install.user_options + [
        ('custom_option=', None, 'Path to something')
    ]

    def initialize_options(self):
        install.initialize_options(self)
        self.custom_option = None

    def finalize_options(self):
        #print('The custom option for install is ', self.custom_option)
        install.finalize_options(self)

    def run(self):
        global my_custom_option
        my_custom_option = self.custom_option
        install.run(self)  # OR: install.do_egg_install(self)

यह उल्लेख के लायक है कि install.run () जाँच करता है कि क्या इसे "मूल" कहा जाता है या पैच किया गया है:

if not self._called_from_setup(inspect.currentframe()):
    orig.install.run(self)
else:
    self.do_egg_install()

इस बिंदु पर आप setup साथ अपनी कमांड रजिस्टर करते हैं:

setup(
    cmdclass={
        'install': InstallCommand,
    },
    :

यहाँ एक बहुत ही सरल उपाय है, आपको बस इतना करना है कि sys.argv को फ़िल्टर करें और डिस्टुटिल्स setup(..) कॉल करने से पहले इसे स्वयं संभाल लें। कुछ इस तरह:

if "--foo" in sys.argv:
    do_foo_stuff()
    sys.argv.remove("--foo")
...
setup(..)

डिस्टुटिल्स के साथ यह कैसे किया जाए, इस पर प्रलेखन बहुत ही भयानक है, आखिरकार मैं इस पर आया: पैकेजिंग के लिए सहयात्री गाइड , जो sdist और उसके user_options का उपयोग करता है। मुझे लगता है कि विचलित करने वाले संदर्भ विशेष रूप से उपयोगी नहीं हैं।

यद्यपि यह डिस्टिल्ट के साथ करने का "उचित" तरीका लगता है (कम से कम केवल एक ही जो मुझे मिल सकता है जो अस्पष्ट रूप से प्रलेखित है)। अन्य उत्तर में उल्लेखित --with और --without स्विच पर मुझे कुछ भी नहीं मिला।

इस डिस्टुटिल सॉल्यूशन के साथ समस्या यह है कि मैं जिस चीज़ की तलाश कर रहा हूँ, उसके लिए यह बहुत ही अच्छा तरीका है (जो आपके लिए भी हो सकता है)। दर्जनों पंक्तियों को जोड़ना और उपवर्ग को sdist मेरे लिए गलत है।





setup.py