Pipenv: اقتراح: أنماط وأنماط "pipenv" لمشروع مكتبة Python

تم إنشاؤها على ٥ أبريل ٢٠١٨  ·  74تعليقات  ·  مصدر: pypa/pipenv

القرصنة maya تعلمت القليل من الدروس التي أدت إلى اقتراحي التالي بشأن الاستخدام الموصى به لـ pipenv في مكتبات Python. أتوقع من الآخرين مراجعة الاقتراح وإذا توصلنا إلى اتفاق ، فقد ينتهي الأمر بالنص (المحدث) في مستندات pipenv .

أنماط pipenv وأنماط مضادة لمشروع مكتبة Python

تعديل
ما يلي هو الأفضل للتطبيق على مكتبات Python العامة (مفتوحة المصدر في الغالب) ، والتي من المفترض أن تعمل على إصدارات وأنظمة تشغيل مختلفة من Python. المكتبات التي تم تطويرها في بيئة مؤسسية صارمة قد تكون حالة مختلفة (تأكد من مراجعة جميع أقسام المشاكل على أي حال).

نهاية التحرير

TL ؛ DR : من المحتمل أن تؤدي إضافة ملفات pipenv إلى مشروع مكتبة Python إلى تعقيد إضافي ويمكن أن تخفي بعض الأخطاء مع عدم إضافة أي شيء إلى أمان المكتبة. لهذا السبب ، احتفظ بـ Pipfile و Pipfile.lock و .env خارج التحكم في مصدر المكتبة.

ستتمكن من استخدام القوة الكاملة البالغة pipenv بغض النظر عن ملفاتها التي تعيش في .gitignore .

مكتبة بايثون مقابل تطبيق بيثون

من خلال مكتبة python ، أعني مشروعًا ، عادةً ما يكون به setup.py ، يتم استهدافه للتوزيع والاستخدام على نظام أساسي مختلف يختلف في إصدار python و / أو OS.

الأمثلة هي maya ، requests ، flask إلخ.

على الجانب الآخر (وليس مكتبة python) ، توجد تطبيقات تستهدف مترجم لغة Python ونظام تشغيل محددًا وغالبًا ما يتم نشرها في بيئة متسقة تمامًا.

يصف pipfile هذه الاختلافات جيدًا في Pipfile مقابل setup.py .

ما هو pipenv (أداة النشر)

أوافق تمامًا على العبارة ، أن pipenv هي أداة نشر حيث تتيح:

  • تحديد المتطلبات الصارمة ( Pipfile.lock ) لنشر البيئة الافتراضية
  • تطبيق تلك المتطلبات الصارمة بطريقة قابلة للتكرار على أجهزة مختلفة

إنه يساعد عندما يتعين على المرء نشر تطبيق أو تطويره في بيئة Python بشكل متسق للغاية عبر مطورين متعددين.

إن استدعاء أداة التعبئة والتغليف pipenv يعد أمرًا pipenv كثيرًا (في التطوير المحلي للمكتبات) ولكن يمكن أن يضر (غالبًا في اختبارات CI عند استخدامه دون تفكير عميق).

تطبيق "أسباب أمنية" في سياق خاطئ

TL ؛ DR : يوفر pipenv بيئة آمنة من خلال تطبيق التبعيات الملموسة المعتمدة الموضحة في ملف Pipfile.lock ومكتبة python يُسمح لها فقط بتعريف التبعيات المجردة (وبالتالي لا يمكنها توفير Pipfile.lock ).

يتألق pipenv في سيناريوهات النشر باتباع الخطوات التالية:

  • تحديد التبعيات المجردة (عبر Pipfile )
  • تولد منه تبعيات ملموسة ينتج عنها Pipfile.lock
  • إنشاء بيئة بيثون (افتراضية) تعكس تلك التبعيات الملموسة
  • قم بإجراء الاختبارات للتأكد من أن البيئة المعينة تعمل كما هو متوقع وأنها آمنة
  • إطلاق "Golden" Pipfile.lock المختبرة كتعريف لبيئة Python المعتمدة
  • يمكن للآخرين استخدام pipenv sync لتطبيق "الذهبي" Pipfile.lock مكان آخر للحصول على بيئة Python متطابقة.

مع تطوير مكتبة Python ، لا يمكن للمرء تحقيق مثل هذا الأمان ، لأن المكتبات يجب ألا تحدد التبعيات الملموسة . كسر هذه القاعدة (وبالتالي محاولة إعلان التبعيات الملموسة بواسطة مكتبة بايثون) ينتج عنه مشاكل مثل:

  • مشاكل في العثور على نسخة مرضية من المكتبات المشتركة (تحدد كل حزمة صارمة الإصدار الدقيق للمكتبة المشتركة ومن المحتمل جدًا أن تختلف الإصدارات وتمنع العثور على إصدار مقبول بشكل عام)
  • قد تعتمد التبعيات الملموسة على إصدار python أو نظام التشغيل أو علامات البيئة الأخرى ومحاولة تثبيت الحزمة في سياق مختلف يمكن أن تفشل بسهولة في تلبية بعض القواعد المحددة في التبعيات الأصلية المجردة.

المشكلة: إخفاء التبعيات المعطلة setup.py

يحدد setup.py كل التبعيات المجردة عبر install_requires .

إذا حدد Pipfile تلك التبعيات أيضًا ، فقد يخفي بسهولة مشكلات مثل:

  • التبعية المفقودة في install_requires
  • يحدد Pipfile قواعد محددة (نطاقات الإصدار وما إلى ذلك) لتبعية و install_requires لا يفعل ذلك.

لمنعه ، اتبع القواعد التالية:

  • يجب ألا تظهر التبعيات المعرفة بالمكتبة في Pipfile
  • يجب أن يكون القسم [packages] في Pipfile إما فارغًا أو يحدد تبعية واحدة فقط في المكتبة نفسها.

المشكلة: Pipfile.lock في المستودع

يعد الاحتفاظ بـ Pipfile.lock (عادةً "لأسباب أمنية") في مستودع المكتبة أمرًا خاطئًا ، لأن:

  • من المحتمل أن تكون التبعيات الموصوفة غير صالحة لإصدارات Python المختلفة أو في نظام تشغيل آخر
  • يضطر المطورون إلى تحديث الملف ليس فقط عند إضافة / إزالة بعض التبعيات ، ولكن أيضًا عند تحديث مكتبات أخرى وقد تكون قابلة للاستخدام داخل المكتبة.

لمنعه ، يجب على المرء:

  • إزالة Pipfile.lock من المستودع وإضافته إلى .gitignore

المشكلة: التنافس مع tox (إخفاء usedevelop )

إذا كان tox.ini يحتوي على إدخالات قسم commands مثل:

  • pipenv install
  • pipenv install --dev
  • pipenv lock

غالبًا ما تكون مشكلة ، لأن:

  • pipenv install بتثبيت المكتبة نفسها فقط ، و tox (افتراضيًا) يقوم بذلك أيضًا. بصرف النظر عن الازدواجية ، فإنه يمنع أيضًا usedevelop=True و usedevelop=False في tox.ini لأن Pipenv قادر على التعبير عنها فقط في متغير واحد (و tox.ini يسمح بالاختلافات في بيئات مختلفة).

لمنعه ، يجب على المرء:

  • الامتناع عن استخدام pipenv في tox.ini . انظر طلباتox.ini

المشكلة: كسر البنيات ، إذا فشل pipenv

pipenv قيد التطوير المكثف والأشياء تتعطل في وقت ما. إذا عطلت هذه المشكلة بنية CI الخاصة بك ، فهناك فشل يمكن منعه من خلال عدم استخدام pipenv واستخدام الأدوات التقليدية (والتي غالبًا ما تكون أكثر نضجًا).

لمنعه ، يجب على المرء:

  • فكر مرتين قبل إضافة pipenv إلى نص CI أو tox.ini أو مكان مشابه. هل تعرف ما هي القيمة التي تحصل عليها من إضافتها؟ هل يمكن إنجاز المهمة باستخدام الأدوات الموجودة؟
  • لا تضيفه "لأسباب أمنية فقط" أو لأن "الجميع يفعل ذلك".

ملخص

الأسئلة الرئيسية المتعلقة بدور pipenv في تطوير مكتبة Python هي:

  • ما القيمة التي يجلبها pipenv حقًا؟ ج: أداة إدارة Virtualenv.
  • ما هي حالة الاستخدام ذات الصلة لـ pipenv ؟ ج: إدارة virtualenv.
  • هل تظهر في مستودع المكتبة؟ ج: لا.

يتبع القليل من التفاصيل والحيل.

pipenv لن يضيف أي حماية لحزمتك

لا تدفعه إلى مشروع لمجرد أن الجميع يفعل ذلك أو لأنك تتوقع أمانًا إضافيًا. سوف يخيب ظنك.

يجب أن يتم التأمين باستخدام التبعيات الملموسة (والمعتمدة) في مرحلة لاحقة من التطبيق الذي سيستخدم مكتبتك.

احتفظ بملفات Pipfile و Pipfile.lock و .env خارج المستودع

ضع الملفات في .gitignore .

Pipfile السهل إعادة إنشاء setup.py . وربما يحتوي الملف .env على معلومات خاصة لن يتم مشاركتها.

سيؤدي الاحتفاظ بهذه الملفات خارج المستودع إلى منع جميع المشكلات التي قد تحدث مع إنشاءات CI عند استخدام pipenv في مواقف غير مناسبة.

pipenv كمربع أدوات خاص بالمطور

pipenv قد يبسط عمل المطور كأداة لإدارة virtualenv.

الحيلة هي أن تتعلم ، كيفية إعادة إنشاء الملفات ذات الصلة (الخاصة) بسرعة pipenv ، على سبيل المثال:

$ cd <project_repository>
$ # your library will bring the dependencies (via install_requires in setup.py)
$ pipenv install -e .   
$ # add more dev tools you preffer 
$ pipenv install --dev ipython pdbpp
$ # start hacking
$ pipenv shell
...

استخدم ملف .env إذا كنت بحاجة إلى طريقة ملائمة لإعداد متغيرات البيئة.

تذكر: احتفظ باستخدام pipenv خارج تصميمات CI الخاصة بك وستكون حياتك أبسط.

الحيلة: استخدم القدرة setup.py للإعلان عن تبعيات الإضافات

في setup.py استخدم قسم extras_requires :

from setuptools import setup

setup(
    name='mypackage',
    ....,
    install_requires=["jinja2", "simplejson"],
    extras_require={
        'tests': ['pytest', 'pyyaml'],
        'pg': ['psycopg2'],
    },
    ....
)

لتثبيت جميع التبعيات المعلنة مقابل tests إضافي:

$ pipenv install -e .[tests]

لاحظ أنه سيتضمن دائمًا تبعيات install_requires .

لا تسمح هذه الطريقة بتقسيم التبعيات إلى أقسام افتراضية وأقسام تطويرية ، ولكن لن تكون هذه مشكلة حقيقية في السيناريوهات المتوقعة.

Discussion Type

التعليق الأكثر فائدة

@ Moritz90 قد تكون العديد من قوائم بايثون البريدية أماكن جيدة لإجراء هذه المناقشة.

يعد pypa-dev الأكثر تحديدًا للمناقشات التي تركز على

أفكار python هي مكان لمناقشة الأفكار ، ولها رؤية عالية جدًا لمجتمع Python بأكمله. ستكون أيضًا نقطة انطلاق جيدة إذا كنت تريد دفع هذا إلى مستوى PEP (في النهاية ، على ما أعتقد).

ال 74 كومينتر

هذا مثير للإعجاب ، شكرًا جزيلاً على التجميع. بالتأكيد سنراجع بمزيد من التفصيل قليلا

/ سم مكعبuranusjrjtratnerncoghlan

بعض الإشارات إلى مشكلات maya :

  • kennethreitz / maya # 138 (RemovePipfile.lock من المستودع)
  • كينيثريتز / مايا # 139 (تخطي تشغيل pipenv فيox.ini ...)
  • kennethreitz / maya # 145 (إصلاح pendulum>=1.0 في setup.py: الإصدار كان في Pipfile لكنه كان مفقودًا في setup.py)
  • kennethreitz / maya # 143 (العلاقات العامة تُظهر كيف حطمت المشكلة pipenv تشغيل Travis بالكامل)
  • kennethreitz / Maya # 144 (استخدام PR Refactor pipenv وفقًا لأفضل الممارسات شبه الرسمية)

أنا أحب هذا أيضًا. ربما يجب أن نضيف هذا إلى وثائق Pipenv ، أو حتى دليل مستخدم Python Packaging .

يبدو أن النتيجة الطبيعية للنصيحة أعلاه هي "التخلي عن بنى CI الحتمية / القابلة للتكرار" ، والتي صدمتني على أنها نموذج مضاد كبير جدًا.

ما الذي تقترحه كبديل لا يزال يسمح بالحتمية؟

@ tsiq-oliverc التصميمات الحتمية لها مكانها في الوقت الحالي ، يجب إنشاء تطبيق.

تخيل المحاولة التالية لأداء تصميمات حتمية حقًا لمكتبة بيثون:

  • يجب أن تستند الإنشاءات إلى Pipfile.lock
  • قد يكون لكل سياق تنفيذ (مزيج من كل متغير من Python و OS) مختلف Pipfile.lock الناتج عن تبعيات مجردة للمكتبة المحددة في Pipfile
  • يجب أن يوفر المستودع مثيلات Pipfile.lock منفصلة محددة في المستودع. لاحظ أن المبنى Pipfile.lock تلقائيًا أثناء إنشاء CI لا يضيف أي حتمية

هذا الكثير من الجهد الإضافي. وما تحصل عليه هو مكتبة ، سيتم تثبيتها في سياق مختلف (على سبيل المثال ، بعد أسبوع من التثبيت القياسي سوف يلتقط التبعية التي تمت ترقيتها أو اثنتين) والتي لن تحصل على أي شيء من الحقيقة ، لقد استخدمت Pipfile.lock ، والتي في الوقت الحالي عفا عليه الزمن.

الصراع هو في حقيقة أن المكتبة يجب ألا تحدد التبعيات الصارمة بالداخل.

إذا كنت تعتقد ، هناك بديل آخر لاكتساب تصميمات حتمية لمكتبة بايثون - صِفها.

vlcinsky - إذا كان مستهلك مكتبتك يستخدم إصدارات مختلفة من التبعيات ، وما إلى ذلك ، فهذا خارج عن

لكن الهدف هنا يفترض أن يكون نطاقًا أصغر بكثير. على وجه الخصوص ، أرى أهداف مشرف المكتبة على النحو التالي (والتي هي تقريبًا معادلات):

  1. إذا قمت بتشغيل CI مرتين ، فمن المؤكد أنك ستحصل على نفس النتيجة (بغض النظر عن مشكلات الشبكة!).
  2. يمكنك إعادة إنشاء (وبالتالي تصحيح) السلوك الذي تلاحظه على CI محليًا ، حتى لو كان ذلك يعني تشغيل Docker / إلخ. محليا.
  3. يمكنك بثقة أن تقول للمستهلكين "تتصرف مكتبتي كما هو متوقع مع إصدارات التبعية X و Y و Z".

إذا لم يكن أي من هذه الأشياء الثلاثة صحيحًا ، فإنه يبدو لي مناقضًا لمراقبة الجودة.

لذا ، نعم ، أود أن أقول إنه إذا ضمنت دعم متغيرات Python A و B و C للمستهلك الخاص بك ، وكانوا يتصرفون بشكل مختلف بما فيه الكفاية بحيث لا يقطعها ملف قفل واحد (وما إلى ذلك) ، فيجب أن يكون لديك ثلاثة ملفات قفل (أو ايا كان).

لم أستخدم Pipenv بما يكفي لمعرفة مدى سهولة ذلك عمليًا.

أفكر حاليًا في إضافة Pipfile s إلى بعض مشاريع المكتبات لنظام CI أيضًا.

أحتاج تمامًا إلى قفل التبعية (+ التجزئة) للامتثال لإرشادات الأمان على مستوى الشركة ولست بحاجة حاليًا إلى اختبار إصدارات Python المختلفة ، نظرًا لوجود نسخة واحدة فقط مدعومة رسميًا. وحقيقة أن pipenv يبسط إنشاء بيئة تطوير محلية ، بما في ذلك virtualenv ، هو أثر جانبي لطيف.

وما تحصل عليه هو مكتبة ، سيتم تثبيتها في سياق مختلف (على سبيل المثال ، بعد أسبوع من التثبيت القياسي سوف يلتقط التبعية التي تمت ترقيتها أو اثنتين) والتي لن تحصل على أي شيء من الحقيقة ، لقد استخدمت Pipfile.lock ، والتي في الوقت الحالي عفا عليه الزمن.

هذا ليس صحيحا عالميا. في عالم برامج المؤسسات ، لا يزال لديك بيئات محددة جدًا مدعومة رسميًا وتؤدي مشكلة أمنية في التبعية إلى تحديث منتجك بدلاً من قيام العميل بتحديث التبعية بأنفسهم.

(نعم ، أنا أتحدث عن مكتبة ، وليس عن تطبيق هنا ...)

@ Moritz90 السيناريو الخاص بك هو لمكتبة pipenv قد يساعدك لأنها بيئة حتمية أكثر بكثير.

يستهدف وصفي مكتبات Python العامة مثل flask و request و maya وما إلى ذلك حيث يكون السياق متغيرًا بدرجة أكبر. في محاولة لإصلاح أمرين في maya شعرت بالإحباط من التعلم ، حيث أدى استخدام pipenv في كثير من الحالات إلى مشاكل حقيقية (عادةً إخفاء المشكلات التي يتم اكتشافها عادةً) مع عدم تقديم الكثير أو أي إضافة القيمة.

الحصول على بنيات حتمية أمر جيد ، لكنه ينطوي على تكاليف. وإذا حدث خطأ ، فقد تدفع مبلغًا إضافيًا للحصول على نتيجة أقل جودة - وهذا ما أردت منعه.

أود أن أزعم أن هذه واحدة من الحالات التي لا نريد أن تكون فيها البنيات حتمية تمامًا . إذا لم تقم بتثبيت تبعياتك بـ == ، فأنت تلتزم بالحفاظ على الدعم لإصدارات متعددة بشكل افتراضي ، ويجب عليك تصميم المكتبة بهذه الطريقة. تعد ترقية التبعية التي تكسر البناء على CI أمرًا جيدًا في الواقع لأنها تكشف عن خطأ في المكتبة. التبعيات القطعية تمامًا (كما يديرها Pipenv) ستخفي ذلك. لا يزال من المفيد أن تكون قادرًا على أن تكون حاسمًا عندما تريد ذلك ، فهذا ليس الأفضل بشكل عام.

تضمين التغريدة أوافق على أنه إذا كانت الرغبة "بناء غير حتمي" ، فإن النصيحة الأعلى قد تكون منطقية. في الواقع ، إنه تكافؤ منطقي تقريبًا ، ويمكن تحديده بشكل أكثر إيجازًا: "إذا كنت لا تريد إنشاءات حتمية ، فلا تستخدم أداة ( pipenv ) الغرض منها هو ضمان إنشاءات حتمية" 😄.

لكن هذا بالتأكيد ليس هدفًا مرغوبًا بشكل عام.

@ tsiq-oliverc تعريف نطاق لطيف - فهو يدعم المناقشة المركزة. أود أن أضيف متطلبًا آخر: يجب ألا تخفي حتمية CI المشكلات المحتملة داخل المكتبة المختبرة.

إذا استخدمنا Pipenv.lock ، فقمنا بإنشاء Virtualenv بناءً على ذلك وقمنا بتشغيل اختبار CI للمكتبة ، فقد قمنا بجزء من الوظيفة التي من المفترض أن تقوم بها المكتبة - تثبيت التبعيات المناسبة. إذا كانت المكتبة معطلة بطريقة ما في هذا الصدد - فإن البيئة المثبتة مسبقًا ستخفي هذه المشكلة.

بالنسبة لي ، يبدو أن اكتشاف المشكلات داخل المكتبة أكثر أهمية من تشغيل CI بطريقة حتمية. إذا كانت هناك طريقة للقيام بالأمرين (على سبيل المثال ، إجراء الاختبار خلف مؤشر pypi الخاص ، والذي يمكن أن يدعم أيضًا الحتمية) ، فليس لدي مشكلة ، ولكن إذا كان هناك تعارض ، فلدي أولوياتي.

لا تسيئوا فهمي: لا توجد رغبة في تشغيل بنى غير حتمية ، رغبتي هي تشغيل CI builds ، والتي ستكتشف أكبر قدر ممكن من المشكلات.

vlcinsky بالتأكيد ، أردت فقط مشاركة تجربتي للتأكد من أن الوثائق المحدثة تعكسها أيضًا. تقوم الوثائق الحالية بعمل رائع في شرح المفاضلات:

بالنسبة للمكتبات ، حدد التبعيات المجردة عبر install_requires in setup.py. [...]
بالنسبة للتطبيقات ، حدد التبعيات ومكان الحصول عليها في ملف Pipfile واستخدم هذا الملف لتحديث مجموعة التبعيات الملموسة في Pipfile.lock. [...]
بالطبع ، لا يزال Pipfile و pipenv مفيدًا لمطوري المكتبات ، حيث يمكن استخدامهما لتحديد بيئة التطوير أو الاختبار.
وبالطبع ، هناك مشاريع لا يكون التمييز بين المكتبة والتطبيق فيها واضحًا.

(أبرزت الجزء الذي ينطبق في حالتي.)

أريد فقط أن أتأكد من بقائها على هذا النحو. أعتقد أن منشورك الأصلي يحتوي على الكثير من البيانات الشاملة دون إخلاء مسؤولية بأنك تتحدث عن مشروع مفتوح المصدر سيتم نشره على PyPI.

@ Moritz90 أتفق تماما. كنت أحاول تسليط الضوء على هذا التركيز ولكن يمكنني جعله أكثر وضوحًا.

@ Moritz90 أضفت ملاحظة تمهيدية تعكس تعليقك.

vlcinsky - هذا منطقي. أفهم أنك لا تريد صراحة غير القطعية يبني، ولكن أعتقد أنه يعادل حتما إلى ما كنت لا تريد (أي لقضايا الصيد عندما تبعيات المنبع الخاص التحديث).

بالتفكير بصوت عالٍ ، ما هي أفضل طريقة لحل هذين الهدفين المتضاربين؟ أحد الاحتمالات هو الحصول على عملية CI من مرحلتين:

  1. المرحلة الحتمية. تستفيد من Pipfile.lock في الريبو الخاص بك ، لذا فهي قابلة للتكرار تمامًا.
  2. المرحلة اللاحتمية. تشغيل pipenv update ثم إجراء الاختبارات ، بحيث يسحب في أحدث تبعياتك (وهو في الأساس نفس السلوك مع عدم وجود ملف قفل ، على ما أعتقد؟).

@ tsiq-oliverc للحصول على تصميمات حتمية ، سأفكر في الإعداد التالي:

  • إنشاء وظيفة ذاكرة التخزين المؤقت pypi: تشغيل مرة واحدة ، وإنتاج شكل من أشكال ذاكرة التخزين المؤقت لمؤشر pypi (كدليل للملفات أو أي شيء مشابه)
  • وظيفة اختبار المكتبة: استخدام ذاكرة التخزين المؤقت pypi ، مع تجنب pipenv

استخدام pipenv لإجراء التثبيت مشابه لما يجب أن يفعله تثبيت المكتبة نفسها ، لكنه بالتأكيد مختلف لأنه رمز مختلف يقوم بالعمل.

بناء وظيفة ذاكرة التخزين المؤقت pypi

$ git clone <repo_url> <project_dir>
$ cd <project_dir>
$ pip install pipenv
$ $ # clean pypi cache and make it ready to cache somehow - not described here
$ pipenv install -e .[test]
$ # if we need extra testing packages in pipenv
$ pipenv install <extra_test_packages>
$ # record current requirements expressed in `Pipfile.lock`
$ pipenv lock
$ # if needed, record the `Pipfile.lock` somewhere

مخرجات هذه الوظيفة هي:

  • Pipfile.lock كاعتماديات مسجلة (قد تساعد المطورين على إعادة إنتاج البيئة بسهولة)
  • مخبأ pypi المحلي المملوء مسبقًا

وظيفة اختبار المكتبة

هناك مراحل:

  • تكوين البيئة لفرض tox ، pip وما إلى ذلك باستخدام ذاكرة التخزين المؤقت pypi المحلية فقط
  • قم بتشغيل اختبارات CI (تجنب استخدام pipenv )

ما نحصل عليه

  • يتم اختبار المكتبة في بيئة حتمية
  • يتم اختبار المكتبة بما في ذلك. قدرته على تثبيت نفسه بنفسه
  • Pipfile.lock يسجل حزم pypi التي تم استخدامها لتثبيت المكتبة. يمكن استخدامه لإعادة إنتاج البيئة في موقع المطور.
  • يعد التكيف مع الحزم التي تمت ترقيتها على pypi (ربما خارجيًا) أمرًا بسيطًا (أعد تشغيل "وظيفة إنشاء ذاكرة تخزين مؤقت لـ pypi) ويتم التحكم فيه (يتم تسجيل محتوى pypi بما في ذلك التجزئة)

ميزة أخرى هي أن هذا الإعداد لا يتطلب من المطورين الحفاظ على Pipfile أو Pipfile.lock . كما أن إجراء الاختبارات في سياقات مختلفة هو نفسه دائمًا (يتم دائمًا إعادة إنشاء Pipfile.lock في سياق معين).

ما الذي لا يزال مفقودًا (ويمكن فعله)

ذاكرة التخزين المؤقت pypi هي الجزء الذي يحتاج إلى بعض البحث. أعتقد أن الدليل البسيط سيكون كافيًا وربما يكون pipenv جاهزًا بالفعل للمساعدة في ذلك. ربما تكون المشكلة رقم 1731 هي الجزء المفقود.

كحزمة تعمل على حل التبعية ، تعتمد العديد من اختباراتنا الخاصة على البنيات الحتمية - أي أخذ الأشياء المعروفة وتوقع رسم بياني تم حله. نستخدم pytest-pypi لهذا الغرض.

أحب المناقشة الحية حول هذا الموضوع. أعتقد أن الفوارق الدقيقة مهمة ويجب عليك دائمًا اختبار التبعيات المعروفة بالإضافة إلى التبعيات غير المثبتة

يجب عليك دائمًا اختبار التبعيات المعروفة بالإضافة إلى التبعيات غير المثبتة

أنا أؤيد هذا الاقتراح. إنها لفكرة جيدة أن يكون لديك دائمًا "حالة جيدة معروفة" للبنيات القابلة للتكرار وتبسيط تصحيح الأخطاء في حالة تعطل أحد التحديثات بالإضافة إلى التأكد من أن الإصدارات الأحدث الثانوية / إصلاح الأخطاء تعمل أيضًا.

(في رأيي الشخصي للغاية ، سيكون الموقف المثالي هو أن يقوم مدير الحزم بتثبيت أحدث الإصدارات الثانوية افتراضيًا بحيث يمكن للمكتبات دائمًا تحديد إصدارات التبعية الملموسة التي تم اختبارها باستخدامها ، لكنني أدرك أن هذا رأي مثير للجدل للغاية ويتطلب من الجميع لمتابعة semver.)

MustafaHosny اللهم امين يارب

هنا ملخصي من المناقشة السابقة.

مشاكل معينة والحلول المقترحة

العديد من سياقات التنفيذ - من الذي سيحتفظ بملف (ملفات) Pipfile.lock ؟

يساهم كل مترجم فوري من أنظمة التشغيل و Python في مصفوفة سياقات التنفيذ الممكنة.

يدعم Eg Flask (على الأقل عناصر CI المرئية في المستودع):

  • نظام التشغيل Windows (python 2.7 و Python 3.6)
  • Linux (python 2.7، 3.4، 3.5، 3.6، nightly، pypi)
  • OSX (py - لست متأكدًا مما إذا كان هناك المزيد من الإصدارات)

يجعل 9 سياقات تنفيذ مختلفة والتي قد تختلف.

قد يكون لكل سياق تنفيذ Pipfile.lock .

من سيحافظ عليهم؟

الخيارات هي:

  • دع المطورين يفعلون ذلك يدويًا (بلا طريقة)
  • احتفظ بعملة واحدة فقط Pipfile.lock لمنصة التطوير الرئيسية (ما النظام الأساسي الذي يستمتع بتجاهله؟)
  • أتمتة الإنشاء عبر CI (نعم)

الاقتراح: دع CI ينشئ الملف بواسطة pipenv install -e . . لا تقم بتضمينه في الريبو ، ساعد المطورين على اختيار Pipfile.lock المناسب نتيجة الإنشاءات الآلية.

يحتاج المطورون إلى بيئة يمكن التنبؤ بها

عند إصلاح مشكلة ، قد تكون ناجمة عن تغييرات في التبعيات على pypi ، قد يحتاج المطور إلى وسيلة بسيطة لإعادة إنتاج البيئة من الاختبار الفاشل.

عرض:

  • بالنسبة للعديد من الحزم ، تعد تغييرات تبعيات pypi نادرة جدًا ، لدرجة أنها ليست مشكلة حقيقية
  • لإصلاح البيئة بنفسه ، يمكن للمطور إنشاء Pipfile.lock بواسطة pipenv install -e . متبوعًا بـ pipenv lock .
  • لتكرار البيئة من الاختبار الفاشل ، يختار المطور Pipfile.lock من الاختبار الفاشل.
  • المهام: اعرض الأمثلة ، كيفية تطبيق Pipfile.lock في tox.ini .

يجب أن تكشف CI عن كسر setup.py

مكتبة setup.py قد تكون معطلة (التبعية مفقودة في install_requires ، محدد الإصدار مفقود وما إلى ذلك) ويجب ألا يخفي اختبار CI هذه المشكلة (عن طريق التثبيت المسبق للتبعيات المحذوفة).

عرض:

  • ثق في pipenv install -e . لتقديم نفس نتيجة التثبيت العادي (توجد حاليًا بعض المشكلات في ذلك).
  • قم بتشغيل اختبار التثبيت العادي (بدون pipenv ) وربما قارن أن الناتج pip freeze هو مجموعة فرعية مما تم تثبيته بواسطة pipenv .

قد تؤدي تبعيات pypi المحدثة إلى كسر الأشياء ، ويجب على CI اكتشاف مثل هذه المطاردات

قد يؤدي بعض تحديث التبعية إلى تعطيل المكتبة باستخدامها. يجب على CI اكتشاف الفشل في مثل هذه المشكلة.

عرض:

  • يجب تشغيل اختبار واحد على الأقل مقابل الإصدار غير المثبت
  • إذا كان CI يولد دائمًا Pipfile.lock جديدًا ، فهذه ليست مشكلة (لأننا نعمل في الوضع غير المثبت على أي حال)

أوضاع CI لأنواع المكتبات المختلفة

في جميع الأوضاع المقترحة ، حاولت تجنب الاحتفاظ بملفات pipenv في المستودع مما يوفر للمطورين من الحفاظ على هذه الأشياء المعقدة حقًا (أتمتة !!!).

على عكس النص الأصلي الخاص بي ، يستخدم الوضع الثاني والثالث pipenv في نصوص CI.

الوضع: Run ، Forrest ، Run!

حزمة بسيطة مع عدد أقل من التبعيات التي لا تتغير كثيرًا.

ما عليك سوى تشغيله كما كان من قبل حقبة pipenv واجعل الأمور بسيطة بالنسبة لنا.

من السهل إصلاح الحالات النادرة التي تؤدي فيها التبعيات إلى حدوث مشكلات ولا تبرر جعل CI أكثر تعقيدًا.

الوضع: توليد وختم

في كل مرة يتم فيها تشغيل اختبار CI ، قم بإنشاء Pipfile.lock والذي يصف البيئة المستخدمة في الوقت الحالي بشكل كامل.

سيصبح Pipfile.lock قطعة أثرية من CI.

إذا ساءت الأمور ، يمكن للمطور اختيار Pipfile.lock من الإصدار المعطل ، وتطبيقه محليًا وإجراء الاختبار والإصلاح.

إذا أراد شخص ما النشر ، فيمكن استخدام Pipfile.lock من آخر إصدار ناجح.

الوضع: العصر الجليدي

عندما يكون تغيير التبعيات مشكلة حقيقية ، يجب على CI إنشاء Pipfile.lock مرة واحدة في كل مرة والاحتفاظ بها لفترة معينة (شهر؟).

هذا يجعل إعداد CI أكثر صعوبة ، حيث يجب أن يكون هناك وظيفتان مختلفتان على الأقل (أحدهما يولد Pipfile.lock ، والآخر يطبقه ويستخدم في الاختبارات).

تحذير: Pipfile.lock يجب أن يتم تحديثه أيضًا في الوقت الحالي ، setup.py يغير التبعيات.

لاحظ أن العصر الجليدي يتطلب اختبار Scrat من نوع السنجاب الذي يتجاهل الحالة المجمدة ويتحقق من الإصدارات غير المثبتة.

ملاحظات ختامية

كما رأينا ، فإن الحتمية والتعقيد ينموان نمطًا تلو الآخر.

سيكون اقتراحي:

  • ابدأ بسيطًا ("Run، Forrest، Run"). تكتسب الكفاءة والسرعة.
  • إذا أصبحت الأمور معقدة للغاية بسبب تغير التبعيات ، فانتقل إلى "إنشاء وإغلاق". تكتسب التكرار في البيئة المحلية.
  • إذا كانت الأمور سيئة حقًا ، فانتقل إلى وضع "العصر الجليدي". تكتسب الحتمية (المؤقتة).

كل المكاسب تكلف شيئا.

إذا كان الهدف هنا هو تحديث النصيحة في المستندات ، فمن غير المسؤول قول شيء مختلف تمامًا عن "اتباع أفضل الممارسات (النسخ القابلة للتكرار) افتراضيًا ، حتى لا يكون لديك خيار".

vlcinsky تحت عنوان "الوضع: إنشاء Pipfile.lock يجب الاحتفاظ به دائمًا ، على سبيل المثال من خلال إعلانه على أنه قطعة أثرية من Jenkins. مع هذا التغيير ، سيكون من الجيد التوصية بهذا الإعداد لمعظم المشاريع. مثل @ tsiq-oliverc ، لا أوصي بالوضع الأول على الإطلاق.

كلما فكرت في الأمر أكثر ، كلما شعرت أن هذه الوثائق ستصبح قسمًا عن سبب استخدام pipenv لبناءات CI فكرة رائعة ، حتى لو كنت تقوم بتطوير مكتبة.

@ tsiq-oliverc الغالبية العظمى من حزم بيثون العامة في الوضع "Run، Forrest، Run". لقد ساعدت عددًا قليلاً من هذه الحزم في تقديم tox و pytest ، لأنني شعرت أنها ستساهم في جودة الحزمة المحددة ولأن لدي فكرة واضحة تمامًا ، كيف يمكن القيام بها بشكل جيد.

الآن هناك أداة رائعة أخرى وأتساءل عن كيفية استخدام pipenv بشكل صحيح في مشاريع Python العامة للمساهمة في جودتها. أريد أن أجد واحدة أو اثنتين من الوصفات الناجحة والتي لها ما يبررها ويسهل اتباعها.

ماذا سأقول لمشروع Flask؟

  1. اتبع أفضل الممارسات (النسخ القابلة للتكرار) افتراضيًا ، حتى لا يكون لديك خيار؟
  2. هل تريد إضافة ملفات 9 Pipfile.lock وإعداد سياسة لتحديثها؟
  3. البرامج النصية Refactor CI لـ Travis و Appveyor للعمل بطريقة مرحلتين بعد وضع العصر الجليدي؟
  4. تعديل نصوص CI لـ Travis و Appveyor لتوليد Pipfile.lock قطعة أثرية للحالات ، عندما يحتاج شخص ما إلى إعادة إنتاج اختبار فاشل على جهاز الكمبيوتر الخاص به؟
  5. لا توجد تعليقات ، باستثناء "شكرًا جزيلاً على Flask."

الهدف هو إيجاد أسلوب عمل وظيفي. إذا انتهى بالوثيقة ، جميل ، إذا لم يكن كذلك ، فلا مشكلة.

vlcinsky أود أن أقول إن (1) و (4) يجب أن يكونا التوصية لمثل هذه المشاريع. بينما بدون Pipfile.lock لن تعرف الإصدارات المستخدمة في الإنشاء مسبقًا (وهو أمر جيد خارج بيئات الشركة) ، ستظل تحصل على نتيجة قابلة للتكرار إذا قمت بإنشاء ملف القفل وأرشفته أثناء البناء.

تحرير : نسخة الدكتور من توصيتي ستكون:

  • تأكد دائمًا من أن البنيات الخاصة بك قابلة لإعادة الإنتاج ، بغض النظر عما إذا كنت تقوم بتطوير مكتبة أو تطبيق. يمكن أن يساعدك pipenv تحقيق هذا الهدف.
  • إذا كنت تطور تطبيقًا ، فقم بالتزام Pipfile.lock بالمستودع الخاص بك واستخدمه للنشر. (هذا مغطى بالفعل من خلال الوثائق الحالية.)
  • إذا كنت تقوم بتطوير مكتبة مفتوحة المصدر ، فقم بإنشاء Pipfile.lock أثناء التنقل في بنية CI وأرشفتها في وقت لاحق.
  • إذا كنت تقوم بتطوير مكتبة وتعمل في بيئة شركة مقيدة ، فاحتفظ بالعدد المناسب من ملفات القفل واستخدم تلك الموجودة في تصميمات CI الخاصة بك.

(بالطبع ، يجب أن تحتوي الوثائق الفعلية على مزيد من التفاصيل والأمثلة.)

@ Moritz90 قمت بتعديل "إنشاء وختم" كما اقترحت.

رد (1): سهل القول ، من المستحيل تنفيذه دون أن يكون أكثر تحديدًا.

إعادة (4): نعم ، أعتقد أيضًا ، أن "إنشاء وختم" هو الوضع الأكثر جدوى. لكن في حالة Flask لن أجرؤ (على الأقل ليس في الوقت الحالي).

إعادة Pipfile.lock في بيئة المؤسسة: يجب إنشاؤه بطريقة ما ، إما (شبه) يدويًا أو تلقائيًا. أعتقد ، في بيئة الشركة ، لا تقوم بالتثبيت مباشرة من pypi العامة ولكن تستخدم بعض البرامج الخاصة والتي توفر فقط حزمًا معتمدة ( devpi-server تقدم خدمة رائعة في ذلك - فهارس متعددة ، تقلب متحكم في الحزم المنشورة ، موافقات خارجية الحزم وما إلى ذلك) إذا كانت عملية إنشاء Pipfile.lock تعمل في مثل هذه البيئة ، فيمكنها فقط استخدام ما تمت الموافقة عليه ، لذا إذا ظهرت نسخة جديدة هناك ، يجب على شخص ما أن يقف ويوافق عليه. بعد بناء CI سيختبر أنه لا يكسر الأشياء. وباستخدام pipenv check قد يتم أيضًا إجراء اختبار مشكلات الأمان تلقائيًا.

أعتقد أن سير العمل هذا سيكون أكثر أمانًا مقارنةً بشخص يقوم بإنشائه (شبه) يدويًا. لكن معرفتي ببيئة المؤسسة محدودة للغاية.

مرحبا فريق pipenv. أشارك الكثير مما يقال في هذا النص ، فهو يساعد أي مطور كثيرًا على فهم قيود Pipfile / pipenv بشكل أفضل عند تطوير مكتبة. أرغب في رؤية هذا النص أو جزء منه مدمجًا في وثائق pipenv الرسمية.

لدي التعديل التالي الذي أود مناقشته:

بالنسبة لحزمة python الداخلية الخاصة بنا ، والتي يمكن إعادة استخدامها بالكامل ، والمنشورة على pypi الداخلي ، وما إلى ذلك ، وحتى بالنسبة لحزم python الخاصة بي (على سبيل المثال: cfgtree ، و txrwlock ، و pipenv-to-requirements ) ، أستخدم حزمة قد يعرفها البعض بالفعل أو يستخدمها ، هذا يلخص هذه التفاصيل ويجعل حياة مطور بايثون أسهل: PBR.
تقرأ PBR الأساسي requirements.txt الموجود في المجلد الجذر لحزمة التوزيع وحقنها في install_requires من setup.py . يحتاج المطور ببساطة إلى الاحتفاظ بـ requirements.txt بإعلانات التبعية الفضفاضة. حتى يتم دمج دعم Pipfile رسميًا داخل PBR ، لا بد لي من استخدام pipenv-to-requirements التي تولد تلقائيًا requirements.txt من Pipfile بحيث تتم مزامنتهما وكلاهما ملتزم في المصدر ، ويقوم PBR بالحقن بشكل صحيح بعد بناء حزمة التوزيع. أعتقد أنه يمكن للمرء استخدام pipenv لتوليد هذا requirements.txt

أعمل على دعم Pipfile لـ PBR ، بحيث يكون قادرًا على قراءة Pipfile ( وليس ملف القفل) وحقنه في install_requires كما يفعل بـ requirements.txt .

لا أعرف ما إذا كانت هناك حزم أخرى مماثلة ، لأنها تؤدي أيضًا أشياء أخرى قد لا يريدها الأشخاص (إصدار من سجل git ، والتوليد التلقائي للمؤلفين ، و ChangLog).

لكن في النهاية ، أشعر حقًا أنه من الأسهل كتابة إصدارات مكتبة Python وصيانتها والتعامل معها ، وسأكون حزينًا لعدم مشاركة هذه التجربة. أنا أقوم بالترويج لها باعتبارها الطريقة "الموصى بها" لكتابة مكتبات بيثون الحديثة على شركتي.

أعدت أن الأمر يشبه "الغش" في جميع الصعوبات المتعلقة بالمكتبة و pipenv ، ولكن في النهاية تم الانتهاء من العمل ويسعد المطورون باستخدامه حتى الآن. جزء من تدريب Python ، أعطي لمطور Python الجديد في شركتي ، يتضمن ، أولاً كتابة مكتبة Python تحتفظ بـ install_requires يدويًا ، ثم التبديل إلى PBR لمعرفة كيف يصبح الأمر أسهل ( وبصراحة أنا معجب بميزة الالتزام الدلالية لـ pbr لإنشاء علامة إصدار semver الصحيحة تلقائيًا).

جزء من سبب إعلان تبعيات المكتبات باستخدام ملف مخصص أيضًا للمكتبات هو القدرة على استخدام أدوات مثل readthedocs أو pyup (حتى لو كان pyup أكثر أهمية عند ربطه بتطبيق ما).

لا أرغب بالضرورة في الترويج لهذه الطريقة باعتبارها الطريقة "القياسية" لعمل حزمة Python ، فهي في الواقع طريقة "OpenStack" ، لكنني أود مشاركة تجربتي ، وإذا كان لدى الآخرين تجربة مماثلة أو متناقضة ، فسأكون كذلك يسعدني سماعهم وتحديث وجهة نظري.

أيها الفريق ، ما رأيك في نوع قسم "المجتمع" في التوثيق؟ حتى يتمكن المستخدمون مثلي من مشاركة تجربته حول كيفية استخدامه لـ pipenv ، دون الحاجة إلى المصادقة الكاملة من فريق pipenv؟

ملاحظة: يمكنني نقل هذا إلى مشكلة مخصصة إذا كنت لا ترغب في تعديل هذا الموضوع

من السهل جدًا تنفيذvlcinsky - ضع ملف القفل في الريبو الخاص بك.

أعتقد أن ما تعنيه بدلاً من ذلك هو: من المستحيل تقديم نصيحة محددة بمجرد أن تصبح هذه الاستراتيجية الأساسية غير كافية. هذا صحيح بالتأكيد ، لكن ذلك لأن المشكلة المحددة ربما تختلف على أساس كل حالة على حدة.

أو بعبارة أخرى ، يعتمد الحل على الضمانات الإضافية التي تريد أن يوفرها سير عمل CI الخاص بك.

gsemet هل تعرف ماذا؟ تستند جميع حزم python التي تم إنشاؤها في العامين الماضيين إلى pbr - إنها رائعة حقًا. وأنا أتابع محاولاتك لدعم Pipfile في pbr كلما استطعت (بعض الإعجاب ، التصويتات ، إلخ).

في حالة حدوث هذه المشكلة (البحث عن أنماط وأنماط pipenv لمكتبات Python العامة) لقد حذفت عمدًا pbr لسببين:

  • سيجعل المناقشة المفاهيمية أكثر تعقيدًا
  • بعض الناس لا يحبون pbr لأسباب أخرى (لقد ذكرتهم) وقد يؤدي ذلك إلى انحراف المناقشة على الأرجح

من ناحية أخرى ، أنا أتطلع حقًا إلى وصفة لك لمحبي pbr. أنا سوف قراءتها.

@ tsiq-oliverc قمت بضرب الظفر: ضع ملف القفل في الريبو الخاص بك

هذه بالضبط هي المشكلة التي دفعتني لبدء هذه القضية. إذا أعدت قراءة بداية هذه المشكلة ، فستجد وصفًا لعدد قليل من الحالات ، حيث يمكن أن تؤدي إضافة Pipfile.lock كسر اختبارات CI (إما كسر تشغيل الإنشاء أو إخفاء المشكلات ، والتي سيتم اكتشافها بخلاف ذلك ، أو تثبيت تبعيات خاطئة لسياق معين ...).

إذا أريتني الريبو ، حيث يتم ذلك بشكل صحيح (مكتبة بيثون العامة) ، فسأكون سعيدًا. أو سأوضح ، ما هي المخاطر الموجودة أو الأشياء التي لم تنته بعد.

رائع ! أنا أيضًا أحافظ على

vlcinsky صحيح ، لذا دعنا نعدد المشكلات المحددة ونجد حلولًا لها 😄 (لا أعرف أي مكتبة عالية الجودة تستخدم Pipenv ، لكن هذا يرجع أساسًا إلى أنني لم أبحث.)

أفضل ما يمكنني قوله ، هذه هي الأعراض المحددة في مشاركتك الأصلية:

  • إخفاء تبعيات setup.py المعطلة. هذا يبدو وكأنه ليس مشكلة - pipenv install -e . ، أليس كذلك؟
  • من المحتمل أن تكون التبعيات غير صالحة لإصدارات Python المختلفة أو في نظام تشغيل آخر. أستطيع أن أرى أن هذا يمكن أن يكون مشكلة ، ولكن هل يمكنك تقديم مثال ملموس على ما هو مهم في الممارسة؟ (في سياق ملف مغلق)
  • يضطر المطورون إلى التحديث ... عندما يتم تحديث مكتبات أخرى وقد تكون قابلة للاستخدام داخل المكتبة. إنهم ليسوا مجبرين على فعل ذلك. يفعلون ذلك إذا كانوا يريدون تقديم ضمان بأن مكتبتهم تعمل ضد الإصدار n + 1 بدلاً من الإصدار n من التبعية. لكن لاحظ أنني اقترحت بالفعل بديلاً يوفر أفضل ما في العالمين.
  • تتنافس مع Tox. لا أعرف حقًا أي شيء عن Tox. لكن نعم ، فإن استخدام أداتين في وقت واحد لإدارة تبعياتك يبدو وكأنه وصفة لكارثة. أود أن أقول استخدام أيهما أفضل لهذه المهمة بالذات.
  • فشل Pipenv. يبدو هذا وكأنه ليس مشكلة أخرى - يمكنك فقط تثبيت إصدار Pipenv (هذا هو الحل الحالي ، تمامًا مثل تثبيت صورة Docker الخاصة بي ، وإصدار Pip الخاص بي ، وما إلى ذلك)

@ tsiq-oliverc يجب أن أقول ، لقد ألهمتني تعليقاتك وأنا أعلم أنها ساهمت في مستوى أعلى من إمكانية تكرار الحل المقترح.

يرتبط ما يلي باقتراحك لوضع lockfile ( Pipfile.lock ) في الريبو لضمان التكرار:

إعادة إخفاء تبعيات setup.py المعطلة. . يتبع pipenv install -e . ما أقترحه ، لكن لاحظ أن هذا ليس استخدامًا لـ Pipfile.lock ، إنه طريقة (إعادة) إنشائه. إذا احتفظ شخص ما بـ Pipenv.lock واستخدمه لإنشاء virtualenv قبل تثبيت الحزمة ، فالمشكلة موجودة.

من المحتمل أن تكون إعادة doit المثبت لـ Python 2.7 إصدارًا أقدم حيث تم إسقاط الدعم الأحدث لـ Python 2.x. تتطلب التبعية watchdog مكتبات تعتمد على النظام الأساسي: inotify على Linux ، شيء آخر على Windows ، شيء آخر على OSX. اعتاد موكلي السابق أن يقول "لن يحدث هذا أبدًا" وفي 50٪ من المواقف حدث ذلك في غضون أسبوعين. هذه ليست أفضل ممارسة لنصوص CI.

إعادة المطورين مجبرون على التحديث .. تخيل مكتبة مفتوحة المصدر تضم 15 مساهمًا. من السهل جدًا نسيان تجديد Pipfile.lock بواسطة مبتدئ جديد أو مطور أساسي متعب. على سبيل المثال ، في الحزمة maya ، طُلب مني إعادة إنشاء Pipfile.lock حيث تمت إضافة التبعية الجديدة إلى setup.py . هل كان ذلك ضروريا؟ هل قمت بتحديثه بشكل صحيح؟ هل قمت بتحديثه لجميع سياقات التنفيذ المدعومة؟ الإجابات لا ، لست متأكدا ، لا. على أي حال ، شكرًا على اقتراحك (لقد ألهمني الحل الموضح بجوار تعليقك).

إعادة التنافس مع Tox : يسمح Tox بإنشاء العديد من Virtualenvs وأتمتة إجراء الاختبارات داخلها. يعرّف النموذجي tox.ini أنواعًا افتراضية مختلفة لـ python 2.7 و 3.4 و 3.5 و 3.6 وأي شيء آخر تحتاجه ، ويسمح بتثبيت الحزمة هناك وتشغيل مجموعة الاختبار. تم تأسيسه powertool من المختبرين الجادين. pipenv ليست الأداة لهذا الغرض ، ولكنها قد تتدخل في تثبيت الأشياء المطلوبة. بطريقة ما اتبعت نصيحتك واقترحت استخدام أداة متفوقة (سم) أكثر من pipenv حيثما أمكن ذلك.

فشل إعادة pipenv . إذا كنت أرغب في استخدامه الآن ، فلن يساعد التثبيت حتى يتم تحرير الإصلاح. ولكن هكذا تسير الأمور - سأنتظر.

لاحظ أنه سيتعين تحديث بعض أجزاء رسالتي الأصلية كما يبدو ، باستخدام pipenv في نصوص CI النصية لها مكانها المبرر ("ختم" تكوين virtualenv لاستخدامه لاحقًا).

@ tsiq-oliverc بينما أعجبتني في البداية باقتراحك بإجراء اختبار مقابل "الخير المعروف" والإصدارات الأحدث ، أجد صعوبة وأصعب في تبرير الجهد كلما فكرت فيه. أعتقد أنك يجب أن تقرر أن تفعل أحدهما أو الآخر ، وليس كلاهما.

الشيء الوحيد الذي تكتسبه هو أنك ستعرف على الفور ما إذا كان الفشل ناتجًا عن تحديث التبعية أو تغيير الرمز. ولكن يمكنك تحقيق الشيء نفسه ببساطة عن طريق إجراء التزامات منفصلة (عند تحديث التبعيات المقفلة يدويًا) أو محاولة إعادة إنتاج الخطأ بأحدث ملف قفل تم إنتاجه بواسطة بنية ناجحة (عند استخدام أحدث الإصدارات دائمًا). وفي البيئات المقيدة ، لا يمكنك "التحديث فقط" على أي حال ...

vlcinsky بينما أتفق مع وجهة نظرك العامة حول الاختلافات بين البيئات ، فإن حجة "ملف قفل واحد لكل تكوين" تبدو لي مثل رجل من القش. من الناحية العملية ، ستتمكن من مشاركة ملفات القفل بين بعض البيئات على الأقل.

أحد الأسئلة المفتوحة المتبقية التي لم يتم الرد عليها حتى الآن هو كيفية التعامل مع الحالة التي يحتاج فيها كلاكما للاختبار في بيئة مختلفة وقفل تبعياتك. يجب أن أعترف أنني لا أعرف أي شيء عن tox بخلاف أنه موجود ، ولكن يبدو أن هناك حاجة إلى نوع من الغراء بين tox و pipenv هذا يحل هذه المشكلة بطريقة أو بأخرى.

تضمين التغريدة

لقاء القش

فيما يتعلق بالعديد من المتغيرات لـ Pipfile.lock تعمل كرجل قش (لإبعاد الآخرين عن مجال عملي):

قارورة

أخذت مشروعًا flask (معتبرة أنه ناضج جدًا) وقمت بإجراء اختبارات السموم:

هنا ترى قائمة المتغيرات التي تم اختبارها (محليًا فقط على Linux ، قم بضربها في 3 لأن windows و OSX سيقومان بنفس مجموعة الاختبارات ولكن قد ينتج عنها بيئات مختلفة).

هناك 16 تشغيلًا اختباريًا مختلفًا على نظام تشغيل واحد ، 5 منها فشلت لأنني لم أقم بتثبيتها (لا بأس بذلك) ، أحدها يتعامل مع مستند البناء (يتطلب مكتبة لا يمكن تصديقها) وتغطية أخرى (والتي تتطلب أيضًا مكتبة قابلة للاستيراد ):

  coverage-report: commands succeeded
  docs-html: commands succeeded
  py27-devel: commands succeeded
  py27-lowest: commands succeeded
  py27-simplejson: commands succeeded
  py27: commands succeeded
  py35: commands succeeded
  py36-devel: commands succeeded
  py36-lowest: commands succeeded
  py36-simplejson: commands succeeded
  py36: commands succeeded
ERROR:   py34: InterpreterNotFound: python3.4
ERROR:   pypy-devel: InterpreterNotFound: pypy
ERROR:   pypy-lowest: InterpreterNotFound: pypy
ERROR:   pypy-simplejson: InterpreterNotFound: pypy
ERROR:   pypy: InterpreterNotFound: pypy

لكل من Virtualenvs التي تم إنشاؤها ، قمت بإنشاء ملف requirements.txt بواسطة pip freeze > {venv_name}.txt

ثم تم حساب تجزئة الملفات ، مرتبة وفقًا لقيم التجزئة ، بحيث يتم تجميعها كلها. هنا يأتي القصاصة:

b231a4cc8f30e3fd1ca0bfb0397c4918f5ab5ec3e56575c15920809705eb815e  py35.txt
b231a4cc8f30e3fd1ca0bfb0397c4918f5ab5ec3e56575c15920809705eb815e  py36.txt
cdf69aa2a87ffd0291ea65265a7714cc8c417805d613701af7b22c8ff2b5c0e4  py27-devel.txt
dfe27df6451f10a825f4a82dfe5bd58bd91c7e515240e1b102ffe46b4c358cdf  py36-simplejson.txt
e48cd24ea944fc9d8472d989ef0094bf42eb55cc28d7b59ee00ddcbee66ea69f  py36-lowest.txt
f8c745d16a20390873d146ccb50cf5689deb01aad6d157b77be203b407e6195d  py36-devel.txt
053e107ac856bc8845a1c8095aff6737dfb5d7718b081432f7a67f2125dc87ef  docs-html.txt
45b90aa0885182b883b16cb61091f754b2d889036c94eae0f49953aa6435ece5  py27-simplejson.txt
48bd0f6e66a6374a56b9c306e1c14217d224f9d42490328076993ebf490d61b5  coverage-report.txt
564580dad87c793c207a7cc6692554133e21a65fd4dd6fc964e5f819f9ab249c  py27.txt
8b8ff4633af0897652630903ba7155feee543a823e09ced63a14959b653a7340  py27-lowest.txt

مخيف أليس كذلك؟ من جميع الاختبارات ، يشترك اثنان فقط في نفس التبعيات المجمدة.

هذه هي حقيقة مكتبة بيثون العامة مع مجموعة اختبار جيدة. من المحتمل أن تعترف الآن ، هذا شيء مختلف تمامًا عن مكتبة Python التي تم اختبارها في بيئة المؤسسة.

جينجا 2

تحقق من jinja2 ، والذي يبدو أنه وحش أبسط بكثير:

  coverage-report: commands succeeded
  py26: commands succeeded
  py27: commands succeeded
  py33: commands succeeded
  py35: commands succeeded
  py36: commands succeeded
ERROR:   docs-html: commands failed
ERROR:   py34: InterpreterNotFound: python3.4
ERROR:   pypy: InterpreterNotFound: pypy

أنا مندهش عند رؤية المجاميع الاختبارية ، أن py27.txt و py26.txt يختلفان:

047a880804009107999888a3198f319e5bbba2fa461b74cfdfdc81384499864e  py26.txt
047a880804009107999888a3198f319e5bbba2fa461b74cfdfdc81384499864e  py33.txt
047a880804009107999888a3198f319e5bbba2fa461b74cfdfdc81384499864e  py35.txt
047a880804009107999888a3198f319e5bbba2fa461b74cfdfdc81384499864e  py36.txt
48bd0f6e66a6374a56b9c306e1c14217d224f9d42490328076993ebf490d61b5  coverage-report.txt
743ad9e4b59d19e97284e9a5be7839e39e5c46f0b9653c39ef8ca89c7b0bc417  py27.txt

vlcinsky هذا مخيف بالفعل. أنا أتساءل ما إذا كانت Flask هي حالة خاصة أم أن هذا هو المعيار بالفعل ، لكنك بالتأكيد أثبتت أنني مخطئ.

آمل الآن ألا تعاني مكتبة بايثون الخاصة بنا من نفس المشكلة يومًا ما وأن تكون الاختلافات أكثر قابلية للإدارة هناك.

@ Moritz90 مكتبتك الداخلية تخدم جمهورًا مختلفًا تمامًا ، لذا يمكنك جعل سياق التنفيذ أضيق بكثير.

غالبًا ما تكون مكتبات Python العامة مرنة وقابلة للتكوين ، على سبيل المثال يسمح Flask بتثبيت موزعي json البديل واستخدام ما يتم تغطيته بواسطة تشغيل اختباري منفصل.

يمكن للمرء أن يتعلم الكثير عن الاختبار والسموم من Flask tox.ini

تهتم متغيرات الاختبار الأقل باختبارها مقابل إصدار التبعية الأقدم.

devel هو اختبار مقابل نسخة مطورة من التبعيات الأساسية.

أود أن أقول ، إن Flask على مستوى أعلى من التعقيد ويعرض مجموعة اختبار دقيقة.

يُظهر ox.ini للهرم عددًا مشابهًا من البيئات (يهدفون إلى تغطية الكود بنسبة 100٪ أيضًا).

مايا سموم آيني طازجة جدًا (يومين) وبسيطة ، حتى هنا 4 بيئات مختلفة ويختلف py27 في المتطلبات المجمدة عن py35 و py36.

تضمين التغريدة
فيما يتعلق بالغراء بين البيبنف والسموم

  • يظهر pipenv --man بعض التعليمات ، كيفية استخدام pipenv ضمن أوامر tox.ini
  • يحاول برنامج ox-pipenv توفير بعض التكامل الإضافي ولكنه

يسمح ملف tox.ini بتشغيل أوامر عشوائية لذلك يتضمن هذا pipenv .

pipenv بميزة رائعة ، وهي أنه عند تشغيله في Virtualenv تم تنشيطه بالفعل (ما هو الحال في الاختبار المستند إلى السموم) ، فإنه يتم تثبيته في بيئة افتراضية معينة. هذا حقا لطيف.

نظرًا لأننا ربما نحتاج إلى إنشاء Pipfile.lock ، يجب بذل بعض الجهد الإضافي للحصول عليه والانتقال إلى المكان المناسب (الانتقال إلى .tox/py36/Pipfile.lock لمنع الكتابة فوق الاختبار التالي. سيكون هذا ممكنًا ، ولكن بعض التبسيط سيكون موضع ترحيب. ربما بعض الحيل مع المتغير البيئي للموقع Pipfile ستجعل الأمر أكثر بساطة.

تضمين التغريدة

  • setup.py - ما زلت غير متأكد من فهمي للمشكلة. تقوم بتشغيل pipenv install -e . مرة واحدة حتى يتم تتبع setup.py الآن عبر ملف القفل الخاص بك. ثم قم بتشغيل pipenv install كلما أضفت حزمًا جديدة إلى setup.py.
  • نسيان المطورين لتحديث ملف القفل - pipenv --deploy مصمم للقبض على هذا. قم بتشغيله في CI الخاص بك!
  • فشل Pipenv - تمت الموافقة عليه ، إذا كانت هناك أخطاء في الأداة ، فهذا سيء. ولكن يتم إصلاح الأخطاء بشكل عام. هذا ليس سببًا للتخلي عن فلسفة كاملة 😞
  • توكس

    • إذا كان Tox مفيدًا لإدارة الاختبارات ، فهذا رائع. إذا كان الأمر رائعًا أيضًا لإدارة الحزم والبنيات الحتمية ، فهذا أفضل.

    • ولكن إذا كان هذا صحيحًا ، فلن يكون هناك سبب لوجود Pipenv. لذلك لا يمكنني إلا أن أفترض أن هناك نوعًا من القيود مع Tox.

    • على غرار ما ورد أعلاه ، لا تبدو حالة العالم اليوم (عدم وجود توافق جيد) سببًا لرفض الفلسفة.

  • متعددة الحواف

    • من الواضح أن هناك على الأقل بعض الحالات الخاصة هنا ، مثل Flask.

    • ليس لدي اقتراح أفضل بأن ملفات قفل متعددة (على الرغم من أنه ربما توجد ميزة مستقبلية لـ Pipenv في هذا الصدد؟)

    • ولكن حتى في هذه الحالة ، ما زلت غير مقتنع بأن إدارة ملفات قفل متعددة هي مشكلة في الممارسة. أسوأ الحالات ، يبدو أنه يمكنك إنشاء برنامج نصي بسيط update-all-lockfiles.sh محليًا ، وتشغيل pipenv --deploy على CI الخاص بك لاكتشاف الأخطاء.


@ Moritz90 - متفق عليه ، قد يكون نهج "المرحلتين" مبالغة في معظم الحالات. على وجه الخصوص ، إذا كنت تقوم بإجراء تحديثات "يدوية" متعمدة / مقصودة على ملف القفل الخاص بك ، فهذا غير ضروري على الإطلاق.


بشكل عام ، سيكون من الجيد التأكد من أن هذا "الاقتراح" يركز على الأشياء التي هي في الواقع مشاكل صعبة (من وجهة نظري ، هذا (أ) يخدم عديدًا ، (ب) الرغبة في اللحاق بالتغييرات في التبعيات الأولية). لا ينبغي أن تستند إلى أشياء عابرة (أخطاء في Pipenv) أو سوء فهم محتمل لكيفية استخدام الأداة.

ولكن حتى بالنسبة لتلك المشكلات "الصعبة" ، يجب أن يكون التأطير مثل "في بعض الحالات المعقدة ، قد تجد أن سير عمل Pipenv الأساسي غير كاف ، لذلك إليك بعض الأشياء التي يجب التفكير فيها". IMO ، لا ينبغي تأطيرها كنهج افتراضي (لأن معظم الناس لن يكون لديهم هذه المخاوف).

سيصبح المثال التوثيق lib-dependencies و app-dependencies و dev-dependencies . يمكن أن تبدو المستندات بهذا الشكل:

استخدم الخيار lib-dependencies إذا كانت الحزمة عبارة عن مكتبة مشتركة. مثال Pipfile :

[lib-dependencies]
some-lib=="*"
another-lib=="*"
yet-another-one==">=1.0"

[dev-dependencies]
some-dev-tool=="1.1"

بالنسبة للمكتبات المشتركة ، من المهم الحفاظ على نطاقات الإصدارات أقل من [lib-dependencies] أوسع نطاق ممكن ، لمنع تعارض الإصدارات على نظام المستهلك.

إذا كانت الحزمة الخاصة بك عبارة عن تطبيق (من المفترض أن يتم تثبيته بواسطة pipenv على النظام المستهدف) يتطلب إصدارات تبعية دقيقة ، فيجب عليك استخدام الخيار [app-dependencies] . مثال Pipfile :

[app-dependencies]
some-lib=="1.0.12"
another-lib=="1.*"
yet-another-one=="2.0"

[dev-dependencies]
some-dev-tool=="1.1"

/ مثال على مستند النهاية

قد يكون الأسلوب الآخر هو Pipfile.lib و Pipfile.app .

أعتقد أن شيئًا كهذا سيغفل الحاجة إلى جزء كبير من الأقسام المضادة للنمط وأدوات الطرف الثالث لملء الفراغ.

يعتبر استدعاء أداة التعبئة والتغليف pipenv أمرًا مضللًا إذا كان المرء يتوقع منه إنشاء مكتبات Python أو المشاركة بعمق في إنشائها.

أعتقد أن هذه مشكلة حقيقية تؤدي إلى الكثير من الالتباس. خاصة بين الأشخاص الذين يتم استخدامهم لمديري الحزم في لغات البرمجة الأخرى (مثل JS و Rust و Elm). استغرق الأمر عدة أشهر وقراءة من حين لآخر لقضايا GIthub ، حتى أدركت أنني كنت أستخدم Pipenv و setup.py بطريقة خاطئة.

تضمين التغريدة

[lib-dependencies] أو Pipfile.lib هو ما لدينا اليوم في Pipfile (كاعتمادات مجردة - على أوسع نطاق ممكن).

[app-dependencies] أو Pipfile.app هو ما لدينا في Pipfile.lock (كاعتمادات محددة).

يمكن استخدام ملفات pipenv وملفاته في حالتين مختلفتين - تطوير مكتبة أو إعداد نشر تطبيق ولكن ربما ليس لكليهما في وقت واحد. لهذا السبب لا أرى أسبابًا قوية لإضافة أقسام إضافية إلى Pipenv . تقع على عاتق المطورين مسؤولية معرفة نوع الغرض الذي سيخدمه Pipfile .

أعتقد أن هذه مشكلة حقيقية تؤدي إلى الكثير من الالتباس. خاصة بين الأشخاص الذين يتم استخدامهم لمديري الحزم في لغات البرمجة الأخرى (مثل JS و Rust و Elm). استغرق الأمر عدة أشهر وقراءة من حين لآخر لقضايا GIthub ، حتى أدركت أنني كنت أستخدم Pipenv و setup.py بطريقة خاطئة.

متفق. الحل المكون من ثلاثة أقسام هو أيضًا حل مثير جدًا للاهتمام لم أفكر فيه مطلقًا ، ويبدو أنه صحيح وبسيط (بشكل مدهش!).

قادمًا من خلفية Python بنفسي ، شعرت دائمًا أن حزمة Node's. json تفعل ذلك بشكل خاطئ (Rust أفضل لأنه يحتوي على مترجم ورابط ، ويمكنه حل هذا في مرحلة لاحقة). لن تعمل معالجة تبعيات التطبيقات و lib بنفس الطريقة ببساطة مع لغة برمجة مثل Python ، على الأقل بالمعنى المجرد - أي أنها قد تعمل من أجلك ، لكن أداة عامة مثل Pipenv لا يمكنها فعل ذلك لأنها تحتاج إلى نوعي.

على الرغم من أنني أحب الحل المكون من ثلاثة أقسام من حيث المفهوم ، إلا أنه لا يزال تغييرًا غير متوافق إلى حد ما في النظام البيئي الحالي. يوجد بالفعل setup.py و setup.cfg و (من المحتمل) pyproject.toml يملأ هذه المساحة. إذا أراد Pipenv (Pipfile ، على وجه الدقة) الانتقال إلى الفضاء ، فإنه يحتاج إلى الدمج مع المشاريع ذات الصلة ، مثل pip (يجب دعم دعم المكتبة بشكل مثالي من خلاله) و flit .

كما ذكرت في قضايا أخرى تتعلق بمعالجة تبعية lib / التطبيق ، يجب تصعيد هذه المناقشة إلى pypa-dev (القائمة البريدية) و / أو عملية PEP ، بحيث يمكن سماعها بشكل أفضل من قبل الأطراف الأخرى والأشخاص المعنيين ، قبل Pipenv (ملف Pipfile) يمكنه التحرك في أي اتجاه.

تضمين التغريدة

[تبعيات lib] أو Pipfile.lib هو ما لدينا اليوم في Pipfile (كاتبعيات مجردة - على أوسع نطاق ممكن).

آسف إذا لم يكن هذا واضحا. من المفترض أن يكون lib-dependencies هو ما يضعه الأشخاص حاليًا في setup.py / install_requires . ربما يكون pypi-dependencies اسمًا أفضل لما قصدته.

تضمين التغريدة

يوجد بالفعل setup.py و setup.cfg و (من المحتمل) pyproject.toml يملأ هذه المساحة.

يمكن أن تقوم Pipenv (أداة سطر الأوامر) بواجهة setup.py . فقط قسم التبعية setup.py سيتعين عليه الانتقال إلى Pipfile. على الأقل في مخيلتي :)

كما ذكرت في قضايا أخرى تتعلق بمعالجة تبعية lib / التطبيق ، يجب تصعيد هذه المناقشة إلى pypa-dev (القائمة البريدية) و / أو عملية PEP ، بحيث يمكن سماعها بشكل أفضل من قبل الأطراف الأخرى والأشخاص المعنيين ، قبل Pipenv (ملف Pipfile) يمكنه التحرك في أي اتجاه.

حسنًا ، آسف للإزعاج ؛) إذا وجدت بعض الوقت ، فسأكتب شيئًا لقائمة الطرود.

ومع ذلك ، ضمن نطاق هذا الاقتراح ، أود أن أقترح التركيز على أفضل الممارسات الممكنة حاليًا ، بدلاً من الدخول في حفرة الأرانب للعمل على سير عمل جديد لمجتمع تعبئة Python بأكمله. سيكون من الأفضل اقتراح أفضل ممارسة ضمن القيود الحالية ، ثم بدء المناقشة من أجل التحسينات.

uranusjr - لقد جئت من خلفية "مجمعة" ، لذلك أشعر بالفضول لماذا هذا هو الحال؟

لن تعمل معالجة تبعيات التطبيق و lib بنفس الطريقة ببساطة مع لغة برمجة مثل Python

@ tsiq-oliverc نظرًا لأن أفضل ممارسات التطبيق تتطلب منك تثبيت تبعياتك ، ستبدأ المكتبات في تثبيت تبعياتها أيضًا ، إذا كانت تستخدم نفس مصدر ملفات المتطلبات. هذا من شأنه أن يؤدي إلى مشاكل في حل التبعية.

لنفترض أن تطبيقي يحتوي على اثنين من التبعيات A و B ، كلاهما يعتمد على C ، لكن A pin v1 ، بينما B pin v2. تسمح اللغات المجمعة لسلسلة الأدوات بالكشف عن ذلك في وقت الترجمة ، وحلها بعدة طرق. Rust ، على سبيل المثال ، يقوم بذلك أثناء وقت الربط — سيحتوي الملف التنفيذي النهائي على نسختين من C (v1 و v2) ، مع ارتباط A و B بكل منهما. في C ++ ، سيتم حل هذا من خلال المكتبات الديناميكية ؛ يتم البحث عن الرمز حتى في وقت لاحق (في وقت التشغيل) ، ولكن الفكرة هي نفسها - يعرف المترجم ما تحتاجه (من الواجهة التي تستخدمها) ، ويمكنه التصرف وفقًا لذلك.

لا تستطيع لغات البرمجة النصية القيام بذلك لأنها لا تعرف ما تريد فعله حقًا حتى تصل بالفعل إلى المكالمة. عقدة يعمل حول هذا بافتراض دائما التبعيات تتنافى (A و B تحصل دائما الخاصة C، حتى إذا نسختين متطابقة)، ولكن هذا يؤدي إلى فئة جديدة من المشاكل، والنتائج في الخارقة محرجا مثل تبعيات الأقران أن الجميع (آمل؟) توافق على أنها فظيعة. ربما لا تريد Python الذهاب إلى هناك (لا يمكنها ، على أي حال ، لأن ذلك من المحتمل أن يكسر جميع تثبيتات Python الحالية).

هناك طريقة أخرى للتغلب على هذا وهي القيام بشيء ذكي في أدوات الحزم التي "تزيل" إصدار التبعية. يقوم Bundler (من Ruby) بذلك ، من خلال توصية الأشخاص بعدم تضمين ملف القفل في الجوهرة ، لذلك يمكن لـ Bundler استخدام الإصدارات غير المثبتة في Gemfile ، بدلاً من الإصدارات المثبتة في Gemfile.lock. لكن الناس يميلون إلى تجاهل النصائح والقيام بكل ما يريدون ، لذلك لا تزال تحصل على إصدارات مثبتة في كل مكان.

ربما كنت أقوى من أن أقول إنه ببساطة لن ينجح . لكن على الأقل جميع المحاولات السابقة فشلت ، والعديد ممن حاولوا هم أناس أذكياء جدًا ، وأكثر ذكاءً مني. لا أعتقد أن هذا يمكن القيام به ، شخصيًا ، وسأواصل التفكير بهذه الطريقة حتى أرى الاقتراح الرائع جدًا الذي يقوم بذلك بالفعل.

@ tsiq-oliverc كتب بيتر هينتينز في مكان ما مفهومًا عن "التعليقات مرحب بها في شكل طلب سحب"

يعجبني ذلك لأنه ينقل التركيز من النصائح الفلسفية إلى الأشياء الملموسة والعملية حقًا. كما أنه يحد من عدد التعليقات لأن المعلق غالبًا ما يتعلم كيف أن الفكرة غير مكتملة أو مكسورة بطريقة ما في الاستخدام الحقيقي.

لقد طلبت منك مثالاً لمكتبة بيثون ، حيث يتم استخدام pipenv بشكل صحيح (أو على الأقل مستخدمة) ولم تقدم أيًا منها.

لقد علّقت على صفات tox لكنك تعترف بأنك لست على دراية بها ، وما زلت تكرر شيئًا عن أفضل الممارسات في عالم تطوير حزمة Python.

تقول إن Flask من المحتمل أن يكون حالة خاصة. لذا فقد بحثت في Github عن مشاريع Python باستخدام كلمة "مكتبة" ، مرتبة وفقًا لعدد من المفترقات (لأنها تعكس على الأرجح عدد الأشخاص الذين يقومون ببعض التطوير بها) ، وتجاهلت كل "قائمة متغيرة لشيء ما" وأعدت عددًا من البيئات لواحد نظام التشغيل (عادةً Linux):

سيكون العدد الحقيقي للبيئات التي سيتم إجراء الاختبارات فيها أعلى مرتين (+ Windows) أو 3 مرات (+ OSX).

tox في مشروعين من أصل 3 (لا أقارنه بـ Travis أو Appveyor لأنهم يقومون بمستوى آخر من الاختبار بجانبه).

عدد البيئات التي يجب اختبارها مرتفع نوعًا ما ، Flask بالتأكيد ليس الأكثر برية.

عدد البيئات المراد تحديد التبعيات الثابتة لها لا يمكن إدارته يدويًا.

إن مجرد إسقاط Pipfile.lock في أحد المستودعات أمر سهل إلى حد ما ، لكنه لا يؤدي إلى تحسن سحري (إذا كانت الإجابة بنعم ، أظهر لي سيناريو حقيقيًا ، عندما يؤدي ذلك إلى تحسين الموقف).

ربما تعرف القاعدة الذهبية من العالم "المترجم" وتشعر أن الحتمية (أو التكرار) أمر ضروري لبايثون أيضًا. كما ترى ، فإن العديد من مشاريع Python تعيش بدونها بشكل جيد ، لذا قد تكون القاعدة الذهبية لا تنطبق بشكل صارم هنا.

سأكون سعيدًا ، إذا وجدنا استخدام pipenv لمكتبات Python مما سيحسن الوضع. وأريد منع الاستخدام الذي قد يضر بالجودة الشاملة.

للوصول إلى هذا الهدف ، فإن أسلوبي هو تكرار الأسئلة:

  • هل يجب علي استخدام الأداة؟
  • كيف؟
  • لماذا ، ما هي القيمة التي حصلت عليها؟
  • هل تسبب في بعض المشاكل؟ (عمل إضافي ، أخطاء مخفية ...)

تضمين التغريدة

آسف إذا لم يكن هذا واضحا. من المفترض أن تكون تبعيات lib الخاصة بي هي ما يضعه الأشخاص حاليًا في setup.py / install_requires. ربما تكون تبعيات pypi اسمًا أفضل لما قصدته.

راجع مناقشة pbr في هذه المسألة. إنه جهد لدعم تبعيات المكتبة بواسطة Pipfile.

أعتقد أنه لن يتم استخدام Pipfile لغرضين (lib و app) ، يجب القيام بهذه الأشياء بشكل منفصل. إذا كنت تشعر أن هناك حاجة حقيقية إليه ، فهل يمكنك وصف الغرض من استخدام المشروع؟ عادةً ما أحاول إبقاء تطوير المكتبة ومشروعات النشر منفصلة لأن استخداماتها مختلفة تمامًا في الوقت المناسب.

vlcinsky لست متأكدًا حقًا من أين تريد أن تأخذ هذا (لست متأكدًا من نوع العلاقات العامة التي تطلبها!) ، لذلك سأخرج من هذه المحادثة في الوقت الحالي.

لإعادة ذكر TL ؛ DR من موقفي:

  1. التصميمات الحتمية مرغوبة للغاية ، وهي شائعة في أماكن أخرى في صناعة البرمجيات ، ويسهل تحقيقها باستخدام Pipenv.
  2. هناك بالتأكيد بعض الحالات المتطورة ، ويجب على شخص ما دفع أحدث التقنيات للأمام هناك (من خلال الحلول البديلة أو عبر الأدوات الأفضل).
  3. سيكون من غير المسؤول أن توصي مستندات Pipenv ضد (1) لمجرد أن (2) يؤثر على مجموعة فرعية صغيرة من الحالات.

تضمين التغريدة على الرغم من أنني لا أعتقد أن هناك أي شيء خاص باللغة هنا ، إلا أن المجتمعات المختلفة قد استقرت على أساليب استكشافية مختلفة للتعامل مع مشكلة بدون حل عام - إذا كان لديك تعارض في الإصدار ، فلديك مشكلة.

يجبرك Maven / Java (على سبيل المثال) على التفكير في الأمر في وقت الإنشاء. تعني طريقة NPM أن لديك مشكلات في وقت التشغيل إذا كانت الإصدارات غير المتطابقة تعبر واجهة. دقة وقت التشغيل (مثل Python ، المكتبات الديناميكية) تعني أن التابع قد ينهار / إلخ. إذا لم يكن إصدار التبعية كما هو متوقع.

تضمين التغريدة

انظر مناقشة pbr في هذه المسألة. إنه جهد لدعم تبعيات المكتبة بواسطة Pipfile.

يبدو pbr لطيفًا وكل شيء ، لكنه يندرج تحت الفئة التي كنت أحاول معالجتها بهذا:

أعتقد أن شيئًا كهذا سيغفل الحاجة إلى جزء كبير من الأقسام المضادة للنمط وأدوات الطرف الثالث لملء الفراغ.

أعتقد أن مثل هذه الأدوات لا ينبغي أن تكون ضرورية في المقام الأول.

إذا كنت تشعر أن هناك حاجة حقيقية إليه ، فهل يمكنك وصف الغرض من استخدام المشروع؟ عادةً ما أحاول إبقاء تطوير المكتبة ومشروعات النشر منفصلة لأن استخداماتها مختلفة تمامًا في الوقت المناسب.

عندما يتعلق الأمر بحزم pypi ، انتهى بي الأمر باستخدام Pipenv للتعامل مع تبعيات dev ، Pipfile لوصف تبعيات dev ، setup.py لوصف تبعيات lib بـ install_requires و setuptools في setup.py لنشر حزمتى التي تعمل pipenv run python setup.py bdist_wheel upload . هذا ما أعتبره معقدًا.

في اللغات الحديثة الأخرى ، يجب أن أتعلم أداة سطر أوامر واحدة (مدير الحزم) بالإضافة إلى تنسيق ملف تبعية واحد. التوثيق في مكان واحد ويسهل متابعته وسيحصل الوافد الجديد على كل هذا في غضون ساعتين. إنها مسألة npm init ، npm install foo --dev ، npm publish . يمكن لـ Pipenv / Pipfile القيام بمعظمها بالفعل ، إذا كان بإمكانها القيام بكل ذلك ، فلن تكون هناك مشكلات مثل هذه المشكلة.

أقوم بإعادة دعوة دعوتي لنوع من قسم / ويكي "المجتمع" لهذا التنبيه. هناك العديد من "الأنماط" التي يمكن أن تكون شرعية وقد يرغب البعض منا في مشاركتها "طريقة عمل مكتبات بايثون" ، بعضها مثلي مع pbr ، وقد يكون لدى البعض الآخر نمط جيد جدًا. لكن صفحة داخل مستند pipenv ، لست متأكدًا مما إذا كانت فكرة جيدة.

ملاحظة: لتحضير الترحيل إلى pypi الجديد ، يجب عليك استخدام twine وليس python setup.py upload. يجب اعتبار استخدام "تحميل" على أنه مضاد.

ربما يمكن أن ينمو pipenv أوامر "النشر"؟

feluxe قد ترغب في إلقاء نظرة على الشعر . لقد عثرت عليه للتو ويبدو أنه ما تبحث عنه.

إنه يفعل ما يفعله pipenv وأكثر ويبدو أنهم يفعلون ذلك بشكل أفضل خاصة فيما يتعلق بإدارة التبعية (على الأقل هذا ما يتظاهرون به). يقوم بإدارة التبعية والتعبئة والنشر كل أداة واحدة poetry .

أتساءل عما إذا كان بإمكان pipenv و poetry جمع الجهد لإعطاء Python أخيرًا مدير حزمة حقيقي.

أريد أن أكرر نفسي مرة أخرى قبل أن تذهب هذه المناقشة بعيداً. لا يمكن لـ Pipenv ببساطة تطوير أمر publish ، أو القيام بأي شيء يحاول تولي مهمة التعبئة والتغليف. سيؤدي هذا إلى تجزئة النظام البيئي بشكل أكبر لأن الجميع لا يفعل ذلك بهذه الطريقة ، ومع اختلاف تبعيات التطبيق و lib من الناحية النظرية ، لا يمكنك إخبار أي شخص بدمجها معًا مرة أخرى بمجرد التمييز في سير العمل.

قد يبدو أن الجميع تقريبًا مشترك في هذا الدمج ، ولكن الحقيقة هي أن هناك الكثير من الأشخاص الذين لا ينضمون إلى هذه المناقشة لأن الأشياء تعمل لصالحهم ويفعلون شيئًا آخر. لقد قلت ذلك مرارًا وتكرارًا: يجب أن تحدث المناقشة حول تحسين تصميم سلاسل الأدوات وتنسيقات الملفات في مكان ما أعلى في التسلسل الهرمي لتعبئة بايثون ، لذلك فهي تتلقى المزيد من التعرض للأشخاص الذين يصممون أشياء أساسية أكثر يعتمد عليها Pipenv. من فضلك خذ المناقشة هناك. لا فائدة من اقتراحه هنا ، لأن Pipenv ليس في وضع يسمح له بتغييره.

لقد قلتها مرارًا وتكرارًا: يجب أن تحدث المناقشة حول تحسين تصميم سلاسل الأدوات وتنسيقات الملفات في مكان ما أعلى في التسلسل الهرمي لتعبئة بايثون ، لذا فهي تتلقى مزيدًا من التعرض للأشخاص الذين يصممون أشياء أساسية أكثر يعتمد عليها Pipenv.

أوافق على أن المناقشة حول هذا الخطأ تخرج عن نطاق السيطرة الآن بعد أن ظهر التغليف والنشر (هذا الخطأ يتعلق فقط بإدارة التبعية!) ، ولكن هل يمكنك من فضلك توجيهنا إلى المكان المناسب لإجراء هذه المناقشة؟ يواجهها الناس هنا لأن pipenv يُنظر إليه على أنه خطوة مطلوبة بشدة في الاتجاه الصحيح ، وليس لأنهم يريدون فرض مسؤوليات إضافية على القائمين على صيانة pipenv.

تحرير : آسف ، لا بد أنني فاتني المنشور الذي فعلت ذلك بالضبط عند قراءة التعليقات الجديدة في المرة الأولى.

ومع ذلك ، ضمن نطاق هذا الاقتراح ، أود أن أقترح التركيز على أفضل الممارسات الممكنة حاليًا ، بدلاً من الدخول في حفرة الأرانب للعمل على سير عمل جديد لمجتمع تعبئة Python بأكمله. سيكون من الأفضل اقتراح أفضل ممارسة ضمن القيود الحالية ، ثم بدء المناقشة من أجل التحسينات.

أنا أتفق كثيرا مع هذا. يجب علينا أولاً معرفة أفضل سير عمل ممكن لمسؤولي المكتبات في الوقت الحالي قبل أن نضع خططًا كبيرة. لذلك دعونا نركز على ذلك مرة أخرى ، كما فعلنا في بداية هذا الموضوع. لا أعتقد أننا توصلنا إلى نتيجة بعد.

العودة إلى الموضوع: نقلاً عن منشورuranusjr حول سبب وجوب تحديد التبعيات في ملف مختلف للمكتبات:

هناك طريقة أخرى للتغلب على هذا وهي القيام بشيء ذكي في أدوات الحزم التي "تزيل" إصدار التبعية. يقوم Bundler (من Ruby) بذلك ، من خلال توصية الأشخاص بعدم تضمين ملف القفل في الجوهرة ، لذلك يمكن لـ Bundler استخدام الإصدارات غير المثبتة في Gemfile ، بدلاً من الإصدارات المثبتة في Gemfile.lock. لكن الناس يميلون إلى تجاهل النصائح والقيام بكل ما يريدون ، لذلك لا تزال تحصل على إصدارات مثبتة في كل مكان.

ربما كنت أقوى من أن أقول إنه ببساطة لن ينجح. لكن جميع المحاولات السابقة على الأقل باءت بالفشل

ما زلت لا أفهم لماذا لا يمكن أن تكون التوصية الرسمية للمكتبات في الوقت الحالي هي استخدام pipenv لبناءات CI الخاصة بهم ، ولكن احتفظ بـ Pipfile.lock خارج نطاق التحكم بالمصادر. نظرًا لأنه ، كما أشار عدد قليل من الأشخاص ، لا علاقة لـ pipenv حاليًا بعملية التغليف ، فلا ينبغي أن نواجه المشكلة التي حددتها أعلاه.

وأنا أيضًا لا أفهم سبب اعتبار هذه حجة ضد تحديد التبعيات المجردة الخاصة بك في نفس الملف الذي تستخدمه التطبيقات لتحديد تبعياتها المجردة. لا بأس إذا كان pipenv لا يريد تنفيذ حل مفصل لدمج Pipfile مع setup.py ، لكنني لا أرى سبب هذه الفكرة السيئة بشكل عام.

تضمين التغريدة

أعتقد أنه لا يجوز استخدام ملف Pipfile لغرضين (lib والتطبيق) ، يجب القيام بهذه الأشياء بشكل منفصل.

انظر رسالتي أعلاه. هل يمكنك أن تشرح لماذا تعتقد ذلك؟ أنا ببساطة لا أستطيع أن أرى أي جانب سلبي من حيث المبدأ. في الوقت الحالي ، قد يكون تضمين Pipfile فكرة سيئة ، حيث سيتعين عليك بعد ذلك تحديد التبعيات بنفس الطريقة في ملفين مختلفين ، لكنني لم أر حتى الآن أي حجة تشرح السبب ستكون فكرة سيئة استخدام Pipfile لإقرارات التبعية بشكل عام.

لاحظ أنني وافقت بالفعل على أن Pipfile.lock يجب ألا يكون في التحكم بالمصادر للمكتبات إلا إذا كنت في نفس الموقف الذي أنا فيه.

تحرير : أيضًا ، إذا اتضح أن pipenv نفسه يحتاج بالفعل إلى معرفة الفرق ، فيمكنك فقط تقديم شيء مثل حقل الشحن crate-type قبل البدء في تقديم app-dependencies و lib-dependencies - هذا يبدو معقدًا للغاية.

@ Moritz90 قد تكون العديد من قوائم بايثون البريدية أماكن جيدة لإجراء هذه المناقشة.

يعد pypa-dev الأكثر تحديدًا للمناقشات التي تركز على

أفكار python هي مكان لمناقشة الأفكار ، ولها رؤية عالية جدًا لمجتمع Python بأكمله. ستكون أيضًا نقطة انطلاق جيدة إذا كنت تريد دفع هذا إلى مستوى PEP (في النهاية ، على ما أعتقد).

@ tsiq-oliverc

أعني بالعلاقات العامة: اعرض مثالاً يثبت أن مفهومك قابل للتطبيق.

لذا اختر بعض المكتبات الموجودة ، وقم بتقسيمها ، وقم بتطبيق (1) - أنت تقول إنه سيكون سهلاً مع pipenv وأظهر لي. حاولت جاهدًا ولدي صعوبات.

إذا كان (2) الخاص بك يعني "على شخص آخر القيام بالعمل" ، فلن تكون العلاقات العامة الخاصة بك موجودة.

في (3) تتحدث عن "مجموعة فرعية صغيرة من الحالات" دون إعطاء أي رقم حقيقي. هل جميع المكتبات الكبرى التي وصفتها فيما يتعلق بعدد Virtualenvs تعتبر "مجموعة فرعية صغيرة"؟

لاختتام هذه المناقشة ، قمت بإنشاء ملخص قصير لما تم العثور عليه أثناء المناقشة.

التركيز: أنماط pipenv (المضادة) لمكتبات وتطبيقات Python

لقد غيرت التركيز قليلاً: فهو لا يتحدث فقط عن مكتبات Python (العامة) ، ولكن أيضًا عن التطبيقات لأنها كانت رخيصة إلى حد ما لتضمينها وتوضح الاختلافات جيدًا.

لقد استبعدت عمدًا أي شيء يقترح تغييرات في الأدوات الحالية مثل pipenv ، tox إلخ.

ما هو pipenv وما هو ليس كذلك

  • إنها أداة نشر ، تسمح بتعريف وتطبيق التبعيات الملموسة عن طريق Pipfile.lock .
  • إنها أداة إدارة virtualenv.
  • إنها ليست أداة تغليف بمعنى توليد حزمة بيثون.

المكتبات والتطبيقات

منتج (برنامج python) إما جاهز للاستخدام في منتج آخر (وبالتالي مكتبة) أو أنه تطبيق نهائي جاهز للتشغيل.

أنا شخصياً أعتقد أنه حتى "مكتبات المؤسسة" تندرج ضمن فئة المكتبات (نفس القواعد تنطبق ، فقط عدد سياقات التنفيذ هو أصغر).

أنواع منتجات البرمجيات

  • مكتبة: لاستخدامها في منتج آخر (مكتبة أو تطبيق)
  • التطبيق: ليتم نشرها وتشغيلها

طرق التثبيت:

  • Library: pipenv install <package> وبالتالي "قم بتشغيل الحزمة (حل الإصدارات للمكتبات الأخرى)"
  • التطبيق: pipenv sync وبالتالي "تطبيق تبعيات ملموسة"

تبعيات مجردة وملموسة

تبعيات منتج البرنامج

  • التبعيات المجردة: يجب تسمية المكتبات المستخدمة ، وقد تقيد الإصدارات أو الاستخدام ، ولكن يجب أن تظل مرنة بدرجة كافية (يجب عدم تثبيت الإصدارات)
  • التبعيات الملموسة: يجب تثبيت الإصدارات ، بشكل مثالي مع تجزئات المكتبات المستخدمة

    القطع الأثرية pipenv :

  • Pipfile : تبعيات مجردة

  • Pipfile.lock : تبعيات ملموسة (مقفلة) "

سياقات التنفيذ

العدد النموذجي لسياقات التنفيذ المختلفة

  • مكتبة:

    • python virtualenvs على نظام تشغيل واحد: من 3 إلى 9 (استخدام تورنادو 30)

    • عدد أنظمة التشغيل: 1 إلى 3 (Linux ، OSX ، Windows)

    • العدد الإجمالي: 3 إلى 18

  • تطبيق:

    • python virtualenvs على نظام تشغيل واحد: 1

    • عدد أنظمة التشغيل: 1

    • العدد الإجمالي: 1 (أو قليل جدًا)

أهداف وأولويات CI والحتمية

هدف CI

  • مكتبة:

    • بما في ذلك الرمز. تسمح تبعياتها المجردة بالتثبيت والوظيفة المتوقعة ضمن جميع المتغيرات المتوقعة لسياقات التنفيذ.

    • عندما (خاص / عام) يحصل pypi على تحديث مكتبة التبعية ، يفشل ، إذا كان يؤثر على تثبيت وظيفة المكتبة المختبرة.

  • تطبيق:

    • عند التثبيت (باستخدام التبعيات الملموسة / المثبتة) ، يتم توفير جميع الوظائف المتوقعة في سياق تنفيذ واحد محدد مسبقًا

أهداف CI الخاصة فيما يتعلق بالوظائف:

  • مكتبة:

    • التبعيات المجردة التي أعلنتها المكتبة كاملة وتتضمن جميع القيود الضرورية (فقط عند الحاجة): تقوم المكتبة بتثبيت نفسها بشكل صحيح

    • جميع حالات الاستخدام المتوقعة تعمل بشكل صحيح

  • تطبيق:

    • التبعيات الملموسة كاملة وكلها مثبتة ، الأفضل بما في ذلك. التجزئة: يتم تثبيت التطبيق بشكل صحيح

    • جميع حالات الاستخدام المتوقعة تعمل بشكل صحيح

أوضاع اختبار CI المختلفة

  • الوضع: "Run، Forrest، Run"

    • يتم الآن اختبار الغالبية العظمى من مكتبات Python بهذه الطريقة.

    • استخدم tox أو برنامج اختبار مشابه

    • لا يوجد استخدام لـ pipenv والاعتمادات الملموسة (يمكن أن تكون جيدة للمكتبات)

  • الوضع: "إنشاء وختم"

    • لا يوجد Pipfile في المستودع

    • Pipfile.lock بواسطة pipenv install -e .

    • Pipfile.lock يوثق (أختام) البيئة ويسمح بإعادة إنتاج virtualenv لاحقًا لتحليل المشكلات.

  • الوضع: "العصر الجليدي"

    • اختبار مرحلتين

      • عند تغيير التبعيات المجردة (المحددة ضمن setup.py install_requires ) أو تحديث الحزمة التابعة على pypi ، قم بإعادة إنشاء Pipfile.lock بواسطة pipenv install -e .

    • تشغيل اختبار الوظيفة: تشغيل عندما يتغير رمز المكتبة. يتم تشغيله داخل Virtualenv تم إنشاؤه بواسطة pipenv sync Pipfile.lock

      كيف ومن الذي يمكن أن يكون Pipfile.lock تم إنشاؤه

  • يدويا من قبل المطور (قد تعمل مع التطبيقات)

  • تلقائيًا عن طريق إنشاء CI (واجتياز جميع الاختبارات ، أعلن أنها قطعة أثرية تم التحقق منها)

أولوية الحتمية مقابل المرونة

  • المكتبة: المرونة (تشغيل كلما أمكن ذلك)
  • application: الحتمية (تعمل بنفس الطريقة تمامًا في سياق التنفيذ المحدد)

    ما الذي يمكن أن يؤثر على حتمية المنتج المثبت:

  • pypi العام (حتمية منخفضة ، يتم تحديث الحزم في أي وقت)

  • pypi الخاص (حتمية أعلى ، يمكن التحكم في تحديثات الحزمة)
  • المتطلبات المجردة داخل المكتبات (لا تستخدم في الحتمية)
  • المتطلبات الملموسة ( Pipfile.lock ): الحتمية الكلية

متنوع

بعض حالات الاستخدام لـ Pipfile.lock :

  • (Antipattern) تحديد التبعيات المجردة للمكتبة (لأنه يجب أن تكون مجردة)
  • (antipattern) قم بإعداد Virtualenv للمكتبة المختبرة (قد يخفي تبعيات مجردة للمكتبة المعطلة)
  • توثيق Virtualenv الدقيق ("الختم") ، حيث تم إجراء اختبار (وبالتالي السماح للمطور بإعادة إنشائه لاحقًا للاختبارات المعطلة وتجربة ذلك)
  • قم بإعداد Virtualenv للتطبيق الذي تم اختباره
  • نشر التطبيق في الإنتاج

    تلميحات أخرى

  • تتيح مكتبة pbr تعريف تبعيات المكتبة المجردة عبر requirements.txt . تحديث قراءة Pipfile في الطريق.

  • تحاول الحزمة poetry شيئًا مشابهًا لـ pyenv

    مشاكل شائعة

  • "قم بإسقاط ملف القفل في الريبو" وستحصل على بنيات حتمية:

    • يجب أن تعمل للتطبيقات.
    • لن يعمل مع المكتبات ، حيث يوجد بالفعل العديد من سياقات التنفيذ ولكل منها إمكانية جيدة لإنتاج Pipfile.lock . على محمل الجد: يظهر flask على 11 بيئة افتراضية مختلفة (على نظام تشغيل واحد) 10 تبعيات مقفلة مختلفة. من الذي سيخلقها ويلتزم بها؟
    • لاحظ أنه مع وضع "إنشاء وإغلاق" CI ، لا يزال بإمكانك الحصول على Pipfile.lock (ولكن تم إنشاؤه بواسطة برنامج CI النصي) مما يسمح بإعادة إنشاء Virtualenv في مكان آخر.
  • Pipfile.lock في مستودع المكتبة

    • إذا تم استخدامه لإنشاء virtualenv ، فيمكنه إخفاء التعريف المكسور لتبعيات المكتبة داخل setup.py .

  • Pipfile في مستودع المكتبة

    • إذا كان يكرر التبعيات المجردة (التي سيتم تحديدها ضمن setup.py ) ، فقد يخفي إعلان التبعية المكسور setup.py .

    • موصى به: قم بإنشاء Pipfile بواسطة pipenv install -e . أو pipenv install -e .[tests] إذا كنت بحاجة أيضًا إلى اختبار التبعيات وتم الإعلان عنها كإضافات "اختبارات" في setup.py

  • إضافة pipenv install <something> إلى نصوص CI النصية

    • إنه لا يحسن الحتمية كثيرًا بمفرده

    • راجع وضع CI "إنشاء وإغلاق" (ثم يجب أن تمر جميع عمليات التثبيت في Virtualenv عبر pipenv ).

الاستنتاجات

تعرض مكتبات Python (خاصة العامة منها) عددًا كبيرًا غير متوقع من سياقات التنفيذ. والسبب هو أن الهدف من المكتبات هو المرونة المثبتة في ظل ظروف مختلفة. تبدو المرونة أكثر أهمية من البنيات الحتمية. بالنسبة للأشخاص القادمين من عالم "التجميع" ، قد يبدو هذا وكأنه مضاد سيء للغاية. الحقيقة هي أن معظم مكتبات Python (وربما جميعها) لا توفر تصميمات حتمية (إذا كنت على دراية ببعضها ، فأخبرني بذلك) وما زالت Python تعمل بشكل جيد للغاية. قد تكون الأسباب التي تجعل تطبيقات Python هي أسلوب حي: Python كلغة برمجة تختلف عن العالم المترجم. قد يكون السبب الآخر هو أن الحتمية يمكن (يجب) حلها في وقت لاحق بمجرد أن يحل التطبيق (البناء من مجموعة من المكتبات) الشرط (الطبيعي والمبرر) للحتمية.

بالنسبة للتطبيقات ، يكون الوضع معاكسًا تمامًا وهنا يسهل الوصول إلى الحتمية باستخدام أداة مثل pipenv .

ما العمل التالي؟

  • لن يكون لدي الوقت للتعامل مع هذا الأسبوع أو الأسبوعين المقبلين.
  • يمكنني تخيل إنشاء سلسلة من إدخالات المدونة في مكان ما (لست متأكدًا من المكان). إذا كنت تعرف المكان (من الناحية المثالية السماح ببعض المناقشة) ، فسيكون مكانًا طبيعيًا للسماح للمحتوى بالإشارة إليه ومناقشته وربما أخيرًا (إذا نجا) في مكان ما في مكان ما :-).
  • أقترح uranusjr لتولي السيطرة على هذه المشكلة (إغلاقها ، تحديد ما يجب فعله بعد ذلك ، إعادة توجيه الأشخاص إلى مكان آخر أو أي شيء يبدو عمليًا)

شكرًا للجميع على المناقشة الملهمة للغاية - أشعر أن رسالة "لقد ضللت تمامًا في هذا الموضوع" أعيد تصميمها ثلاث مرات - ما يعني بطبيعة الحال أننا أصبحنا أفضل.

vlcinsky poetry ليس له علاقة بـ pyenv . إنه يشبه إلى حد كبير pipenv (ولكن مع تنفيذ أفضل بكثير فيما يتعلق بإدارة المكتبات والتطبيقات ، IMO) ولكن مع جزء التعبئة والنشر.

لديك ملف pyproject.toml يحدد مشروعك وتبعياته (تبعيات مجردة) و pyproject.lock الذي يصف التبعيات المثبتة ويتم تثبيته لأي إصدار من Python والنظام الأساسي pyproject.toml تم تحديد الملف من أجل الحصول على ملف قفل حتمي واحد فقط لتجنب المشكلات التي يواجهها pipenv . فقط عند التثبيت ، سيتحقق poetry الحزم المراد تثبيتها عن طريق فحصها مقابل البيئة.

وعندما تقوم بحزم مكتبتك ، فإنها ستستخدم التبعيات المجردة (وليس المثبتة) بحيث تحافظ على المرونة عند توزيع الحزمة الخاصة بك (عبر PyPI على سبيل المثال).

ميزة هذا هو أنه سيستخدم التبعيات المجردة للمكتبات وملف القفل للتطبيقات. وهذا هو أفضل ما في العالمين.

zface poetry عدم استخدام التبعيات المثبتة يؤدي حرفيًا إلى هزيمة الغرض بأكمله. Pipenv هو _idempotent_ وهذا يتطلب _إنتاج_ بيئة. يرجى التوقف عن استخدام هذه المشكلة كمنصة لمحاولة بيع شيء ما تم إدراجه باعتباره السبب الأول لاستخدامه عبر pipenv بحيث لا يحب المؤلف cli. في نهاية اليوم ، يتم نشر برنامجنا عبر مئات الآلاف من الأجهزة ويقر بالفعل ويستخدم أفضل الممارسات المتعلقة بالتعبئة. إذا كنت لا تريد بيئة مثالية وتريد طمس الخطوط الفاصلة بين التطوير والتغليف ، فالرجاء عدم المشاركة في هذه المناقشة لأننا لا نتحرك في هذا الاتجاه ولن تكون مثمرة.

بشكل أساسي ، ننفق الكثير من الوقت والجهد على المرونة بحيث لا يتعين على المشاريع الصغيرة التي تقدم مطالبات كبيرة بذل الكثير من الجهد لأن الأشخاص لا يواجهون حالات متطرفة. إذا كنت تعتقد حقًا أن أداة أخرى تقدم لك أفضل ما في العوالم ، فأنا أشجعك على استخدامها - لن تتعامل pipenv نفسها مع التغليف نيابة عنك على المدى القريب ، إن وجدت.

techalchemy أنا لا أبيع أي شيء ، حقًا ، أنا فقط pipenv .

و poetry ينفذ تبعيات الدبوس في pyproject.lock ، تمامًا مثل pipenv في Pipfile.lock . لذلك لديك استنساخ تمامًا مثل ما يوفره pipenv . إذا كان لديك ملف قفل ، فسيتم استخدامه وتثبيت التبعية المثبتة ، وإذا لم أكن مخطئًا ، فهذا أيضًا ما يفعله pipenv .

المرة الوحيدة التي تستخدم فيها التبعيات المجردة هي عندما تقوم بحزم المشروع للتوزيع (لذلك بشكل أساسي للمكتبات) لأنك في هذه الحالة لا تريد التبعيات المثبتة.

vlcinsky لا تزال هناك بعض النقاط التي يجب فرزها أو تصحيحها أو توسيعها ، لكنني ما زلت حريصًا جدًا على الدخول في نموذج التوثيق ، Pipenv أو غير ذلك. هل أنت مهتم بإرسال طلب سحب؟ سأكون أكثر من سعيد للمساعدة في تفصيل المقال.

فيما يتعلق بالشعر ، فأنا شخصياً لست معجبًا بالشعر ككل ، لكنه يفعل الكثير من الأشياء الصحيحة. ربما لا ينبغي ذكره في مستندات Pipenv لأنه ينتهك بعض أفضل الممارسات التي يرغب مطورو Pipenv في دفع الناس نحوها ، ولكن يجب ذكر ذلك إذا كانت المناقشة تجري في pypa-dev أو ما شابه ذلك ، لتقديم صورة كاملة عن كيفية التغليف النظام البيئي حاليا.

يمكن للشعر أيضًا أن يستخدم المزيد من الاهتمام والمساهمة. سيكون هذا هو الأفضل للمجتمع ، بما في ذلك Pipenv. من خلال الخيارات القابلة للتطبيق ، يمكن للناس أن يثقلوا في اختياراتهم بدلاً من الدخول في رأس Pipenv أولاً والتذمر من عدم قيامهم بما يتوقعونه. يمكن أن تؤدي المنافسة الجيدة بين المكتبات أيضًا إلى تحفيز التحسينات التقنية في جبهة حل التبعية ، وهو ما يفعله كل من Pipenv والشعر (وليس بشكل مثالي). يمكننا أن نتعلم الكثير من بعضنا البعض.

uranusjr نعم ، أعتقد أنه تم توضيح القليل من الأشياء وتستحق المشاركة مع جمهور أوسع. مساعدتك مرحب بها حقا

ماذا عن "صياغة الوثائق المزدوجة"؟ أعتقد أنه في هذه اللحظة سيكون من الأكثر فاعلية العمل عليه على نطاق صغير من شخصين فقط.

يعتقد أن تفعل (ربما مع تكرار واحد أو اثنين):

  • أين بالضبط يمكننا نشر ذلك
  • تحديد عناصر التوثيق (مقالات ، أقسام)
  • توضيح نطاق وهدف كل بند
  • نتفق على الخطوط العريضة
  • تحديد القضايا المفتوحة
  • العمل بها
  • اكتب المستند
  • تنشر (وآمل أن يتم قبولها)

إذا كنت ترغب في كتابته بنفسك (بناءً على ما تمت مناقشته) وجعلني مراجعًا ، فلن أشكو.

سأتواصل معك عبر البريد الإلكتروني للموافقة على الإجراءات التالية.

vlcinsky أيضًا أنا متاح كـ @uranusjr على PySlackers (مساحة عمل Slack) إذا كنت تفضل التفاعل في الوقت الفعلي. لدى Pipenv قناة هناك ( #pipenv ).

uranusjr هذا ما قصدته بجمع الجهود. بايثون بحاجة ماسة إلى مدير حزم جيد مثل البضائع. يتضاءل نظام Python البيئي مقارنة باللغات الأخرى بسبب عدم وجود طريقة قياسية للقيام بالأشياء. و pipenv لن يساعد في ذلك ، على ما أعتقد.

ما يزعجني هو أن pipenv يعلن عن نفسه على أنه the officially recommended Python packaging tool حين أنه ليس أداة تغليف ، بعيدًا عن ذلك ، وهو أمر مضلل للمستخدمين. إنه مجرد مدير تبعية مقرونًا بمدير Virtualenv.

أنت تقول أيضًا إنها مستوحاة من البضائع ، npm ، الغزل وهي أدوات تغليف جنبًا إلى جنب مع مديري التبعية بينما الأنابيب ليست كذلك.

وهنا عيب pipenv ، إنه فقط يفسد الماء لأن الناس سيستمرون في ارتكاب نفس الأخطاء كما كان من قبل مع requirements.txt مقابل setup.py . ستظل المشاريع معبأة بشكل سيئ مع التبعيات المحددة بشكل سيئ في setup.py بسبب ذلك. هذا ما فعلته مشاريع مثل البضائع بشكل صحيح: فهم يتعاملون مع جميع جوانب تطوير المشاريع / التطبيقات لضمان الاتساق في حين أن مشروع مثل pipenv لا يفعل ذلك.

وعندما تقول:

وهو ما يفعله بيبنف والشعر (وليس بشكل مثالي)

ماذا تقصد بذلك؟ من خلال ما رأيته ، فإن مدير التبعية لديهم أكثر مرونة بكثير من المدير الذي قدمه pipenv . الجانب السلبي الوحيد هو أنهم يستخدمون واجهة برمجة تطبيقات PyPI JSON والتي لا تحتوي أحيانًا على معلومات تبعية بسبب الحزم المنشورة بشكل سيء.

على أي حال ، أعتقد ، كما قلت ، أن كلا المشروعين يمكن أن يتعلموا من بعضهما البعض.

وهناك شيء آخر ، ما هو مستقبل pipenv إذا تعاملت النقطة في النهاية مع Pipfile ؟ هل سيكون مجرد مدير virtualenv؟

إذا كان مدير تبعية الشعر يعتمد على json api ، فإنه ليس خطأً في بعض الأحيان فقط بسبب "الحزم المنشورة بشكل سيئ" ، بل سيكون محدودًا للغاية فيما يمكن أن يحل بشكل صحيح بالفعل. ينشر المستودع json api _ أحدث تبعيات حتى إذا كنت تتعامل مع إصدار قديم ، وهذا إذا كان يحتوي على تلك المعلومات على الإطلاق. اعتدنا على دمج json api أيضًا ، لقد كان رائعًا لأنه كان سريعًا ، لكن فريق البنية التحتية أخبرنا ألا نثق به. يبدو من المخادع بعض الشيء تسمية شيء مرن إذا كان يعتمد على مصدر غير موثوق للبدء به.

في نهاية المطاف ، تدور التحديات حول إنشاء رسم بياني تبعية ينفذ ملف إعداد لأنه في الوقت الحالي ، هذه هي الطريقة التي تعمل بها الحزم. لا توجد طريقة للتغلب عليها. قد يختلف الرسم البياني التبعية الذي يتم حله على جهازي عن الرسم البياني الذي يتم حله على جهازك حتى بالنسبة للحزمة نفسها.

من السهل تسليم الموجة والقول "حسنًا ، ألا يجعل هذا من pipenv مديرًا افتراضيًا إذا كان بإمكان Pip قراءة ملف Pipfile؟" لا. Pipenv هو مدير تبعية. يدير البيئات غير الفعالة وينشئ ملف قفل قابل للتكرار. أدرك أن هذا يجب أن يبدو تافهاً بالنسبة لك لأنك تلوح به بعيدًا وتحول هذه الأداة إلى مدير Virtualenv ، لكنها ليست كذلك. نقوم بحل ملفات القفل ونقوم بتضمين علامات لإصدارات بايثون التي لا تمتلكها ولا تستخدمها ، ونحتفظ بها متاحة حتى تتمكن من نشرها وإعادة إنتاجها بدقة عبر الأنظمة الأساسية وإصدارات بايثون. نحن نستخدم العديد من طرق الدقة بما في ذلك التعامل مع العجلات والملفات المحلية ومستودعات vcs (نقوم بحل الرسم البياني هناك أيضًا) المصنوعات البعيدة وحزم pypi والفهارس الخاصة وما إلى ذلك.

في نهاية اليوم ، سوف تتعامل النقطة مع ملفات الأنابيب ، هذه هي الخطة ، إنها الخطة منذ إنشاء التنسيق. ولكن هذا هو نفس السؤال "ولكن ماذا عن متى يمكن للنقطة التعامل مع ملفات المتطلبات؟" السؤال مطابق في الأساس. يمكن لـ Pip تثبيت هذا التنسيق. إنها ليست ذات صلة حقًا بأي من الوظائف التي وصفتها بخلاف أننا نقوم أيضًا بتثبيت الملفات (باستخدام pip ، بالمناسبة).

تضمين التغريدة

ينشر المستودع json api أحدث التبعيات حتى لو كنت تتعامل مع إصدار قديم ، وهذا إذا كان يحتوي على تلك المعلومات على الإطلاق

هذا مجرد خطأ واضح ، يمكنك الحصول على تبعيات إصدار معين عن طريق استدعاء https://pypi.org/pypi/{project}/{release}/json . إذا اتصلت فقط بـ https://pypi.org/pypi/{project}/json فتأكد من أنك ستحصل فقط على التبعيات الأخيرة ولكن يمكنك بالفعل الحصول على المجموعة الصحيحة من التبعيات.

ويحتاج جزء التعبئة / النشر في مشاريع Python حقًا إلى التحسين لأنه في النهاية سيفيد الجميع ، لأنه سيجعل من الممكن استخدام JSON API بشكل موثوق.

يدير البيئات غير الفعالة وينشئ ملف قفل قابل للتكرار.
نقوم بحل ملفات القفل ونقوم بتضمين علامات لإصدارات بايثون التي لا تمتلكها ولا تستخدمها ، ونحتفظ بها متاحة حتى تتمكن من نشرها وإعادة إنتاجها بدقة عبر الأنظمة الأساسية وإصدارات بايثون.

وكذلك الحال مع poetry . ويمكنك عدم استخدام واجهة برمجة تطبيقات JSON لتوفير استخدام نفس طريقة الدقة مثل pipenv (باستخدام أدوات النقطة). راجع https://github.com/sdispater/poetry/issues/37#issuecomment -379071989 وسيظل أكثر مرونة من pipenv (https://github.com/sdispater/poetry#dependency-resolution )

zface سأقول هذه المرة الأخيرة ، من فضلك خذ هذا إلى مكان أعلى في التسلسل الهرمي. لا تدعي Pipenv أنها أداة تعبئة Python الموصى بها رسميًا ؛ تقول ذلك لأنها كذلك . إذا شعرت أن هذا غير مناسب ، فأخبره للمسؤولين الذين يوصون بيبينف . من فضلك لا تضع هذه الأشياء على Pipenv dev. هذا هو المكان الخطأ لتقديم شكوى ، ولا يمكنك الحصول على حلول لشكاواك هنا. يمكنك أيضًا الحصول على إجابات أفضل للأسئلة الفنية التي لديك هناك. هذا هو أداة تعقب المشكلات لـ Pipenv ، وليس لوحة مناقشة لأدوات حزم Python وكيفية عمل حزم Python.

لا تعتمد Pipenv فقط على أدوات pip للدقة ، يرجى التوقف عن اختزال برنامجنا إلى خطوط واحدة تظهر عدم فهم. أعرف جيدًا كيف يعمل PyPI api ، لقد تحدثت مباشرة إلى الفريق الذي قام بتطبيقه.

هذا مجرد خطأ واضح ،

هذا النوع من المواقف غير مرحب به هنا. لا تفترض أننا لا نفهم ما نتحدث عنه. يرجى ممارسة المجاملة.

سيظل أكثر مرونة من pipenv (https://github.com/sdispater/poetry#dependency-resolution)

لا يقوم Pipenv حاليًا بتسوية الرسوم البيانية للتبعية. إن الإشارة إلى قضية محددة حيث تم تسطيح الشجرة والادعاء بأن الأداة بأكملها هي الأفضل والأكثر مرونة أمر أحمق ، فأنت تثبت مرارًا وتكرارًا أنك هنا ببساطة لإهانة بيبينف والترويج للشعر. يرجى أن تكون في طريقك ، هذا السلوك غير مرحب به.

أوافق على أن المناقشة بعيدة عن الموضوع ، والتي كانت تحاول الاستفادة من "الممارسات الجيدة" حول بيبينف.

لكن،

[...] سيظل يرتكب نفس الأخطاء التي كان يرتكبها من قبل مع requirements.txt vs setup.py. ستظل المشاريع معبأة بشكل سيئ مع التبعيات سيئة التحديد في إعدادها بسبب ذلك.

أشارك في هذا الرأي ، جعل مطورين جدد يقومون بحزم كود Python الخاص بهم بنجاح أمر معقد ، ومعقد للغاية ، ويتطلب قراءة الكثير من الوثائق عبر الإنترنت.
لكن الأمر لا يرجع إلى pipenv أو أي اعتماد آخر على الحزمة للتعامل مع ذلك بالكامل. لم نتمكن من إعادة كتابة التاريخ. نحن ، كمجتمع ، بحاجة إلى إيجاد طريقة لتحديث سلسلة أدوات Python ، خطوة بخطوة.

و pipenv (وربما الشعر) خطوة جيدة جدًا إلى الأمام.

إن الاضطرار إلى الحفاظ على جانب واحد Pipfile للتطبيق و setup.py للمكتبات على الجانب الآخر ، هو أمر غير منطقي. بغض النظر عن مدى صعوبة شرحنا بالكثير من الكلمات والمقالات الطويلة وأدلة الممارسات الجيدة ، فهي معقدة للغاية بالنسبة لما هي عليه. أوافق تمامًا على أن الأمر كذلك في الوقت الحالي ، لكن لا ينبغي أن يمنعنا ذلك من تخيل طريقة أفضل وأكثر أمانًا.
في النهاية ، بصفتي مطورًا ، أريد أداة واحدة ، ربما بوضعين مختلفين ، لمساعدتي وجعل حياتي أسهل قدر الإمكان.

يجب أن تكون طريقة لاستخراج الجزء الذي يقوم بـ requirements.txt/Pipfile من libs مثل PBR لاقتراح نوع من 'easy setup.py' ، غلاف مدرك لملف Pipfile حول install_requires ، بدون كل السلوك غير المرغوب فيه الذي يجلبه pbr ، وحزمه في غلاف setuptools مخصص يقوم بذلك فقط.

لذلك سنتمكن من الحصول على أفضل ما في كل عالم:

  • pipenv للحفاظ على Pipfile (تم إصداره في كل من المكتبات والتطبيقات)
  • pipenv للحفاظ على Pipfile.lock (إصدار فقط للتطبيقات)
  • يمكن للمرء استخدام حزمة الغلاف السحرية هذه ( pipfile_setuptools ، install_requires_pipfile ؟) التي ستكون تبعية من المستوى الأول وهي الوظيفة فقط لضخ Pipfile في install_requires .

هذا المشروع الآخر الذي لن يكون مرتبطًا بـ pipenv ، لكنه لا يزال بحاجة إلى مكتبة محلل عام Pipfile . ماذا تعتقد؟

gsemet من flit . ستحتاج إلى التحدث إليهم أولاً (على pypa-dev أو distutils-sig) حول هذا الأمر قبل متابعة استخدام Pipfile كتنسيق المصدر. بالنسبة لتحليل ملف Pipfile (وملف القفل) ، يتم التعامل معه في ملف pypa / pipfile (الذي يوفره بائعو Pipenv لمنطق التحليل الأساسي).


تحرير: الرجاء ترك رسالة لي إذا قررت بدء مناقشة حول هذا في أي من القائمتين البريدية. لدي بعض الأفكار حول كيفية تجميع جزأي توزيع حزم Python معًا.

يجب أن أعترف أنني حزين بعض الشيء لرؤية التبعيات المعلنة في pyproject.toml (والتي تأخذ الأدوار كـ setup.cfg قام بها PBR) ، بينما تدعم PyPa أيضًا Pipfile ....

شكرا لمؤشر flit و pipfile. هناك أيضا أنبوب كينيثريتز الذي يبدو أخف وزنا.

يبدو أن setup.cfg الخاص بـ PBR أكثر اكتمالاً مقارنة بالوثائق الرسمية (على سبيل المثال: data_files ) وإعادة استخدام ملف تمت مشاركته بالفعل مع عدة أدوات (flake8 ، pytest ، ...) يمكن أن يستخدم نفس الملف ، مما يقلل من عدد الملفات. ملف في جذر مشروع بيثون)

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

xi picture xi  ·  3تعليقات

marc-fez picture marc-fez  ·  3تعليقات

bgjelstrup picture bgjelstrup  ·  3تعليقات

FooBarQuaxx picture FooBarQuaxx  ·  3تعليقات

jeyraof picture jeyraof  ·  3تعليقات