2025, Oct 06 01:31
PyInstaller में spire.xls पैकेजिंग: DLLs को data नहीं, binaries के रूप में जोड़ें
IDE में चलने वाला spire.xls कोड PyInstaller से बने exe में AttributeError क्यों देता है? जानें सही तरीका: DLLs को --add-binary से शामिल करें और त्रुटि से बचें.
spire.xls का उपयोग करने वाले किसी Python टूल को पैकेज करना ऊपर-से आसान लगता है: IDE से यह बिना किसी रुकावट के चलता है, लेकिन PyInstaller से बने executable के रनटाइम पर फेल हो जाता है. संकेत स्पष्ट है—फ्रीज़ करने के बाद ही दिखने वाला AttributeError. अच्छी बात यह है कि यह आपके कोड की लॉजिक-सम्बंधी गलती नहीं है; समस्या पैकेजिंग की है, जो इस बात से जुड़ी है कि PyInstaller अलग-अलग resource प्रकारों को कैसे संभालता है.
समस्या का लक्षण
सोर्स से चलाने पर सब ठीक रहता है, लेकिन पैकेज किए गए .exe में यह नहीं चलता. executable इस तरह का संदेश देकर बंद हो जाता है:
An exception of type AttributeError occurred. Arguments: ('NoneType' object has no attribute 'Workbook_CreateWorkbook',)
फेल होने से पहले, बिल्ड को ऐसे कमांड से चलाया गया था जो .dll फ़ाइलों को data की तरह भेजने की कोशिश करता है. उदाहरण:
pyinstaller --noconfirm --onefile --console 
  --add-data "D:\work\apps\venv\Lib\site-packages\spire\xls\lib\Spire.Xls.Base.dll;." 
  --add-data "D:\work\apps\venv\Lib\site-packages\spire\xls\bin\Spire.XLS.dll;." 
  --add-data "D:\work\apps\venv\Lib\site-packages\spire\xls\lib\libSkiaSharp.dll;." 
  "D:\work\apps\RunReports.py"
क्या हो रहा है
PyInstaller गैर-बाइनरी संपत्तियों और नेटिव लाइब्रेरीज को अलग तरह से हैंडल करता है. ऊपर उपयोग किया गया फ्लैग गैर-बाइनरी resources के लिए है. .dll फ़ाइलों को शामिल करने के लिए उन्हें binaries के रूप में देना जरूरी है. जब .dlls गलत तरीके से बंडल की जाती हैं, तो उन पर निर्भर रनटाइम कोड अपेक्षित रूप से लोड नहीं हो पाता, और ऑब्जेक्ट बनाते समय या मेथड कॉल पर त्रुटियाँ मिलने लगती हैं.
समाधान
.dll फ़ाइलों को data की जगह binaries के रूप में शामिल करें. समाधान का सार यही है.
pyinstaller 
  --add-binary ./libSkiaSharp.dll:./spire/pdf/lib 
  --add-binary ./Spire.Pdf.Base.dll:./spire/pdf/lib 
  invoice_build.py
अपने वातावरण के अनुसार .dll के नाम और पथ अपडेट करें. सबसे अहम बात यह है कि हर .dll के लिए --add-binary का प्रयोग करें और उसे बंडल की गई एप्लिकेशन के भीतर उचित गंतव्य पर मैप करें.
यह क्यों मायने रखता है
spire.xls जैसी लाइब्रेरीज़ नेटिव कंपोनेंट्स पर निर्भर रहती हैं. यदि पैकेजिंग के दौरान वे binaries के रूप में शामिल नहीं की गईं, तो executable रनटाइम पर उन्हें एक्सेस नहीं कर पाएगा. सही PyInstaller फ्लैग का उपयोग बिल्ड को उस तरीके के अनुरूप रखता है, जिस तरह नेटिव लाइब्रेरीज़ वास्तव में लोड होती हैं, और उन मुश्किल-से-ट्रेस होने वाली विफलताओं को रोकता है जो केवल फ्रीज़ के बाद सामने आती हैं.
निष्कर्ष
यदि आपका spire.xls-आधारित स्क्रिप्ट इंटरप्रिटर से चलती है लेकिन पैकेजिंग के बाद टूट जाती है, तो सबसे पहले देखें कि आप .dlls को कैसे शामिल कर रहे हैं. उन्हें data की तरह न भेजें. हर आवश्यक .dll के लिए --add-binary का उपयोग करें, पथों की जाँच करें और दोबारा बिल्ड करें. यही एक बदलाव विकास और पैकेज्ड व्यवहार के बीच के अंतर को दूर कर देता है और आपकी डिस्ट्रीब्यूशन को अनुमानित बनाए रखता है.
यह लेख StackOverflow पर प्रश्न (लेखक: goryef) और Dheeraj Malik के उत्तर पर आधारित है।