Алтернативни реализации на входни точки (разширения) на python/setuptools на други езици/приложения

Докато този въпрос има бекенд на Python, въпросът не е свързан със самия Python, а по-скоро относно механизмите за разширение и как да се регистрират/търсят плъгини.

В Python концепцията за входни точки е въведена от setuptools и е свързана с метаданните на инсталираните дистрибуции на Python (наричани пакети в други системи за пакетиране).

Доколкото разбирам, една от функциите, предоставени от входни точки, е да позволи на приложение да дефинира място, където другите могат да поставят неща, така че всяко приложение, което иска да използва входна точка, може да получи списък с регистрирани класове/функции там. Да вземем пример:

  • Foo дефинира входната точка "entrypoint1" и търси плъгини, регистрирани под това име.
  • Бар регистрира извикваем (Bar.callable) на входната точка "entrypoint1".
  • След това всеки скрипт на python може да посочи Bar.callable като един от регистрираните извиквания за "entrypoint1".

С setuptools приложенията регистрират входни точки по време на инсталиране и информацията се съхранява в метаданни, свързани с опаковането, наречени .egginfo (които обикновено съдържат информация за името на разпространението, неговите зависимости и още някои метаданни за опаковането).

Имам чувството, че метаданните за пакетиране не са правилното място за съхраняване на този вид информация, тъй като не разбирам защо тази информация е обвързана с пакетирането.

Любопитен съм да чуя за такива функции за входни точки/разширения/плъгини на други езици и особено дали концепцията е свързана с метаданни и пакетиране или не. И така въпросът е...

Имате ли примери, които трябва да разгледам? Бихте ли обяснили защо изборът на дизайн е направен по този начин?

Можете ли да видите различни начини за справяне с този проблем? Знаете ли как този проблем вече е решен в различни инструменти? Какви са недостатъците и предимствата на текущата реализация на Python пред другите?


Какво открих досега

Намерих в различни проекти начин за създаване и разпространение на "плъгини", които специално обръщат внимание на "как да правим плъгини".

Например libpeas (рамката на плъгина gobject) дефинира набор от начини за разширяване на поведение по подразбиране чрез указване добавки. Въпреки че това е интересно, аз се интересувам само от частта за „регистриране и намиране“ (и евентуално зареждане).

Ето някои от откритията ми досега:

Libpeas дефинира собствен файл с метаданни (*.plugin), който съхранява информация за типа на callable (възможно е да има различни добавки на различни езици). Основната информация тук е името на модула за зареждане.

Maven има проектен документ, съдържащ информация за това как се управляват нещата там. Maven управлява плъгини с техните зависимости и метаданни, така че изглежда като интересно място за търсене как са внедрили нещата.

Както е посочено в тяхната документация, добавките на maven използват анотации (@goal) в класовете, което след това се използва за намиране на всички добавки, регистрирани с определен @goal. Докато този подход е възможен в статични езици, той не е в интерпретирани езици, тъй като ние знаем само кои са всички възможни класове / извикваеми в даден момент от времето, което може да се промени.

Mercurial използва централен конфигурационен файл (~/.hgrc), съдържащ съпоставяне на името на плъгин към пътя, по който може да бъде намерен.


Още няколко мисли

Въпреки че това не е отговор на този въпрос, също така е интересно да се отбележи как са внедрени входните точки на setuptools и как се сравняват по отношение на производителността с mercurial.

Когато поискате конкретна входна точка с setuptools, всички метаданни се четат по време на изпълнение и по този начин се изгражда списък. Това означава, че това четене може да отнеме известно време, ако имате много дистрибуции на Python по пътя си. Mercurial от другата страна твърдо кодира тази информация в един файл, което означава, че трябва да посочите пълния път до вашето извикване там, след което регистрираните извиквания не се „откриват“, а „четат“ директно от конфигурацията файл. Това позволява по-фина конфигурация за това какво трябва да е налично и какво не трябва да бъде и изглежда по-бързо.

От друга страна, тъй като пътят на Python може да бъде променен по време на изпълнение, това означава, че извикваните, предоставени по такъв начин, трябва да бъдат проверени спрямо пътя, за да се знае дали трябва да бъдат върнати или не във всички ситуации.


Защо входните точки в момента са обвързани с опаковката

Също така е интересно да се разбере защо входните точки са обвързани с пакетиране в setuptools. Основната причина е, че изглежда полезно дистрибуциите на python да могат да регистрират част от себе си като разширяване на входна точка по време на инсталиране: тогава инсталирането означава също така регистриране на входните точки: няма нужда от допълнителна стъпка за регистрация.

Въпреки че това работи доста добре в голяма част от случаите (когато дистрибуциите на Python действително се инсталират), не работи, когато не са инсталирани или просто не са пакетирани. С други думи, доколкото разбирам, не можете да регистрирате входна точка по време на изпълнение, без да имате .egg-info файл.


person Community    schedule 13.08.2011    source източник
comment
И аз много бих искал да знам. Входните точки се появяват на места, които са малко извън обхвата на метаданните за опаковане, напр. supervisor ги използва в много от своите дефиниции на conf-файл: supervisord.org/... за такива неща би било хубаво да не зависи от setup.py файлове и други подобни.   -  person fish2000    schedule 13.08.2011


Отговори (2)


като една от възможните идеи можете да разгледате концепцията OSGi, която се използва за управление на плъгин система на Eclipse. Може да е прекалено за вашия конкретен случай, но определено е източникът на вдъхновение.

person Community    schedule 20.10.2013

Тъй като започнахте да говорите за внедряване/обработка на език за програмиране, може би си струва да се отбележи, че наскоро gcc придоби възможности на плъгини също.

person Community    schedule 19.08.2011