PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/share/doc/python3.11-setuptools/userguide
Viewing File: /usr/share/doc/python3.11-setuptools/userguide/quickstart.rst
========== Quickstart ========== Installation ============ You can install the latest version of ``setuptools`` using :pypi:`pip`:: pip install --upgrade setuptools Most of the times, however, you don't have to... Instead, when creating new Python packages, it is recommended to use a command line tool called :pypi:`build`. This tool will automatically download ``setuptools`` and any other build-time dependencies that your project might have. You just need to specify them in a ``pyproject.toml`` file at the root of your package, as indicated in the :ref:`following section <basic-use>`. .. _install-build: You can also :doc:`install build <build:installation>` using :pypi:`pip`:: pip install --upgrade build This will allow you to run the command: ``python -m build``. .. important:: Please note that some operating systems might be equipped with the ``python3`` and ``pip3`` commands instead of ``python`` and ``pip`` (but they should be equivalent). If you don't have ``pip`` or ``pip3`` available in your system, please check out :doc:`pip installation docs <pip:installation>`. Every python package must provide a ``pyproject.toml`` and specify the backend (build system) it wants to use. The distribution can then be generated with whatever tool that provides a ``build sdist``-like functionality. .. _basic-use: Basic Use ========= When creating a Python package, you must provide a ``pyproject.toml`` file containing a ``build-system`` section similar to the example below: .. code-block:: toml [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" This section declares what are your build system dependencies, and which library will be used to actually do the packaging. In addition to specifying a build system, you also will need to add some package information such as metadata, contents, dependencies, etc. This can be done in the same ``pyproject.toml`` [#beta]_ file, or in a separated one: ``setup.cfg`` or ``setup.py`` [#setup.py]_. The following example demonstrates a minimum configuration (which assumes the project depends on :pypi:`requests` and :pypi:`importlib-metadata` to be able to run): .. tab:: pyproject.toml .. code-block:: toml [project] name = "mypackage" version = "0.0.1" dependencies = [ "requests", 'importlib-metadata; python_version<"3.8"', ] See :doc:`/userguide/pyproject_config` for more information. .. tab:: setup.cfg .. code-block:: ini [metadata] name = mypackage version = 0.0.1 [options] install_requires = requests importlib-metadata; python_version < "3.8" See :doc:`/userguide/declarative_config` for more information. .. tab:: setup.py [#setup.py]_ .. code-block:: python from setuptools import setup setup( name='mypackage', version='0.0.1', install_requires=[ 'requests', 'importlib-metadata; python_version == "3.8"', ], ) See :doc:`/references/keywords` for more information. Finally, you will need to organize your Python code to make it ready for distributing into something that looks like the following (optional files marked with ``#``):: mypackage ├── pyproject.toml # and/or setup.cfg/setup.py (depending on the configuration method) | # README.rst or README.md (a nice description of your package) | # LICENCE (properly chosen license information, e.g. MIT, BSD-3, GPL-3, MPL-2, etc...) └── mypackage ├── __init__.py └── ... (other Python files) With :ref:`build installed in your system <install-build>`, you can then run:: python -m build You now have your distribution ready (e.g. a ``tar.gz`` file and a ``.whl`` file in the ``dist`` directory), which you can :doc:`upload <twine:index>` to PyPI_! Of course, before you release your project to PyPI_, you'll want to add a bit more information to help people find or learn about your project. And maybe your project will have grown by then to include a few dependencies, and perhaps some data files and scripts. In the next few sections, we will walk through the additional but essential information you need to specify to properly package your project. .. TODO: A previous generation of this document included a section called "Python packaging at a glance". This is a nice title, but the content removed because it assumed the reader had familiarity with the history of setuptools and PEP 517. We should take advantage of this nice title and add this section back, but use it to explain important concepts of the ecosystem, such as "sdist", "wheel", "index". It would also be nice if we could have a diagram for that (explaining for example that "wheels" are built from "sdists" not the source tree). .. _setuppy_discouraged: .. admonition:: Info: Using ``setup.py`` :class: seealso Setuptools offers first class support for ``setup.py`` files as a configuration mechanism. It is important to remember, however, that running this file as a script (e.g. ``python setup.py sdist``) is strongly **discouraged**, and that the majority of the command line interfaces are (or will be) **deprecated** (e.g. ``python setup.py install``, ``python setup.py bdist_wininst``, ...). We also recommend users to expose as much as possible configuration in a more *declarative* way via the :doc:`pyproject.toml <pyproject_config>` or :doc:`setup.cfg <declarative_config>`, and keep the ``setup.py`` minimal with only the dynamic parts (or even omit it completely if applicable). See `Why you shouldn't invoke setup.py directly`_ for more background. .. _Why you shouldn't invoke setup.py directly: https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html Overview ======== Package discovery ----------------- For projects that follow a simple directory structure, ``setuptools`` should be able to automatically detect all :term:`packages <package>` and :term:`namespaces <namespace>`. However, complex projects might include additional folders and supporting files that not necessarily should be distributed (or that can confuse ``setuptools`` auto discovery algorithm). Therefore, ``setuptools`` provides a convenient way to customize which packages should be distributed and in which directory they should be found, as shown in the example below: .. tab:: pyproject.toml (**BETA**) [#beta]_ .. code-block:: toml # ... [tool.setuptools.packages] find = {} # Scan the project directory with the default parameters # OR [tool.setuptools.packages.find] # All the following settings are optional: where = ["src"] # ["."] by default include = ["mypackage*"] # ["*"] by default exclude = ["mypackage.tests*"] # empty by default namespaces = false # true by default .. tab:: setup.cfg .. code-block:: ini [options] packages = find: # OR `find_namespace:` if you want to use namespaces [options.packages.find] # (always `find` even if `find_namespace:` was used before) # This section is optional as well as each of the following options: where=src # . by default include=mypackage* # * by default exclude=mypackage.tests* # empty by default .. tab:: setup.py [#setup.py]_ .. code-block:: python from setuptools import find_packages # or find_namespace_packages setup( # ... packages=find_packages( # All keyword arguments below are optional: where='src', # '.' by default include=['mypackage*'], # ['*'] by default exclude=['mypackage.tests'], # empty by default ), # ... ) When you pass the above information, alongside other necessary information, ``setuptools`` walks through the directory specified in ``where`` (defaults to ``.``) and filters the packages it can find following the ``include`` patterns (defaults to ``*``), then it removes those that match the ``exclude`` patterns (defaults to empty) and returns a list of Python packages. For more details and advanced use, go to :ref:`package_discovery`. .. tip:: Starting with version 61.0.0, setuptools' automatic discovery capabilities have been improved to detect popular project layouts (such as the :ref:`flat-layout` and :ref:`src-layout`) without requiring any special configuration. Check out our :ref:`reference docs <package_discovery>` for more information, but please keep in mind that this functionality is still considered **beta** and might change in future releases. Entry points and automatic script creation ------------------------------------------- Setuptools supports automatic creation of scripts upon installation, that run code within your package if you specify them as :doc:`entry points <PyPUG:specifications/entry-points>`. An example of how this feature can be used in ``pip``: it allows you to run commands like ``pip install`` instead of having to type ``python -m pip install``. The following configuration examples show how to accomplish this: .. tab:: pyproject.toml .. code-block:: toml [project.scripts] cli-name = "mypkg.mymodule:some_func" .. tab:: setup.cfg .. code-block:: ini [options.entry_points] console_scripts = cli-name = mypkg.mymodule:some_func .. tab:: setup.py [#setup.py]_ .. code-block:: python setup( # ... entry_points={ 'console_scripts': [ 'cli-name = mypkg.mymodule:some_func', ] } ) When this project is installed, a ``cli-name`` executable will be created. ``cli-name`` will invoke the function ``some_func`` in the ``mypkg/mymodule.py`` file when called by the user. Note that you can also use the ``entry-points`` mechanism to advertise components between installed packages and implement plugin systems. For detailed usage, go to :doc:`entry_point`. Dependency management --------------------- Packages built with ``setuptools`` can specify dependencies to be automatically installed when the package itself is installed. The example below shows how to configure this kind of dependencies: .. tab:: pyproject.toml .. code-block:: toml [project] # ... dependencies = [ "docutils", "requests <= 0.4", ] # ... .. tab:: setup.cfg .. code-block:: ini [options] install_requires = docutils requests <= 0.4 .. tab:: setup.py [#setup.py]_ .. code-block:: python setup( # ... install_requires=["docutils", "requests <= 0.4"], # ... ) Each dependency is represented by a string that can optionally contain version requirements (e.g. one of the operators <, >, <=, >=, == or !=, followed by a version identifier), and/or conditional environment markers, e.g. ``sys_platform == "win32"`` (see :doc:`PyPUG:specifications/version-specifiers` for more information). When your project is installed, all of the dependencies not already installed will be located (via PyPI), downloaded, built (if necessary), and installed. This, of course, is a simplified scenario. You can also specify groups of extra dependencies that are not strictly required by your package to work, but that will provide additional functionalities. For more advanced use, see :doc:`dependency_management`. .. _Including Data Files: Including Data Files -------------------- Setuptools offers three ways to specify data files to be included in your packages. For the simplest use, you can simply use the ``include_package_data`` keyword: .. tab:: pyproject.toml (**BETA**) [#beta]_ .. code-block:: toml [tool.setuptools] include-package-data = true # This is already the default behaviour if your are using # pyproject.toml to configure your build. # You can deactivate that with `include-package-data = false` .. tab:: setup.cfg .. code-block:: ini [options] include_package_data = True .. tab:: setup.py [#setup.py]_ .. code-block:: python setup( # ... include_package_data=True, # ... ) This tells setuptools to install any data files it finds in your packages. The data files must be specified via the |MANIFEST.in|_ file or automatically added by a :ref:`Revision Control System plugin <Adding Support for Revision Control Systems>`. For more details, see :doc:`datafiles`. Development mode ---------------- ``setuptools`` allows you to install a package without copying any files to your interpreter directory (e.g. the ``site-packages`` directory). This allows you to modify your source code and have the changes take effect without you having to rebuild and reinstall. Here's how to do it:: pip install --editable . See :doc:`development_mode` for more information. .. tip:: Prior to :ref:`pip v21.1 <pip:v21-1>`, a ``setup.py`` script was required to be compatible with development mode. With late versions of pip, projects without ``setup.py`` may be installed in this mode. If you have a version of ``pip`` older than v21.1 or is using a different packaging-related tool that does not support :pep:`660`, you might need to keep a ``setup.py`` file in file in your repository if you want to use editable installs. A simple script will suffice, for example: .. code-block:: python from setuptools import setup setup() You can still keep all the configuration in :doc:`pyproject.toml </userguide/pyproject_config>` and/or :doc:`setup.cfg </userguide/declarative_config>` Uploading your package to PyPI ------------------------------ After generating the distribution files, the next step would be to upload your distribution so others can use it. This functionality is provided by :pypi:`twine` and is documented in the :doc:`Python packaging tutorial <PyPUG:tutorials/packaging-projects>`. Transitioning from ``setup.py`` to ``setup.cfg`` ------------------------------------------------ To avoid executing arbitrary scripts and boilerplate code, we are transitioning into a full-fledged ``setup.cfg`` to declare your package information instead of running ``setup()``. This inevitably brings challenges due to a different syntax. :doc:`Here </userguide/declarative_config>` we provide a quick guide to understanding how ``setup.cfg`` is parsed by ``setuptools`` to ease the pain of transition. .. _packaging-resources: Resources on Python packaging ============================= Packaging in Python can be hard and is constantly evolving. `Python Packaging User Guide <https://packaging.python.org>`_ has tutorials and up-to-date references that can help you when it is time to distribute your work. .. |MANIFEST.in| replace:: ``MANIFEST.in`` .. _MANIFEST.in: https://packaging.python.org/en/latest/guides/using-manifest-in/ ---- .. rubric:: Notes .. [#setup.py] New projects are advised to avoid ``setup.py`` configurations (beyond the minimal stub) when custom scripting during the build is not necessary. Examples are kept in this document to help people interested in maintaining or contributing to existing packages that use ``setup.py``. Note that you can still keep most of configuration declarative in :doc:`setup.cfg <declarative_config>` or :doc:`pyproject.toml <pyproject_config>` and use ``setup.py`` only for the parts not supported in those files (e.g. C extensions). See :ref:`note <setuppy_discouraged>`. .. [#beta] Support for adding build configuration options via the ``[tool.setuptools]`` table in the ``pyproject.toml`` file is still in **beta** stage. See :doc:`/userguide/pyproject_config`. .. _PyPI: https://pypi.org