2. Pisanie Skryptu Instalacyjnego¶
Skrypt instalacyjny jest w centrum wszystkich czynności podczas budowania, rozprowadzania i instalowania modułów przy użyciu Distutils. Głównym zadaniem skryptu instalacyjnego jest opisanie dystrybucji twojego modułu dla Distutils, tak aby różne polecenia które operują na twoich modułach robiły to prawidłowo. Jak widzieliśmy w rozdziale Prosty przykład powyżej, skrypt instalacyjny składa się głównie z wywołania zadania setup()
, i większość informacji dostarczonych do Distutils przez twórcę modułu jest dostarczonych jako parametrów kluczowych dla zadania setup()
.
Tutaj jest trochę bardziej zaangażowany przykład, który będziemy śledzić przez następne parę rozdziałów: własny skrypt instalacyjny Distutils. (Pamiętaj, że chociaż Distutils są zawarte w języku pytonowskim 1.6 i wyższej, Distutils istnieją także niezależnie, tak, że użytkownicy języka pytonowskiego w wersji 1.5.2 mogą używać ich aby zainstalować dystrybucje innych modułów. Własny skrypt instalacyjny Distutils, pokazany tutaj, używany jest tutaj do zainstalowania pakietu dla języka pytonowskiego 1.5.2.)
#!/usr/bin/env python
from distutils.core import setup
setup(name='Distutils',
version='1.0',
description='Python Distribution Utilities',
author='Greg Ward',
author_email='gward@python.net',
url='https://www.python.org/sigs/distutils-sig/',
packages=['distutils', 'distutils.command'],
)
Istnieją tylko dwie różnice pomiędzy tą i prostą jedno-plikową dystrybucją prezentowaną w rozdziale Prosty przykład: więcej danych, i wyszczególnienie czysto pytonowskich modułów „przez pakiet”, zamiast przez nazwę modułu. Jest to istotne skoro Distutils składają się z paru modułów rozdzielonych na (jak dotejpory) dwa pakiety; jawną listę wszystkich modułów byłaby żmudna w wytworzeniu i trudna w utrzymaniu. Po więcej informacji o dodatkowych danych o danych, sięgnij do rozdziału Dodatkowe dane o danych ( - z ang. - meta-dane - dane o danych).
Zauważ, że jakiekolwiek nazwy ścieżek (plików lub katalogów) dostarczony w skrypcie instalacyjnym powinien być napisany używając konwencji Unixa, tj. separowanej-ukośnikami. Distutils zajmie się zamianą reprezentacji obojętnej wobec maszyny/środowiska zanim użycie ścieżki będzie możliwe. To sprawia że twój skrypt instalacyjny jest przenośny pomiędzy systemami operacyjnymi, co oczywiście jest jednym z głównych celów Distutils. W tym duchu nazwy ścieżek dostępu w tym dokumencie są separowane ukośnikiem.
To rzecz jasna, stosuje się tylko do nazw ścieżek danych dla zadań Distutils. Jeśli na przykład używasz zadań standardowych języka pytonowskiego takich jak glob.glob()
lub os.listdir()
aby określać pliki, powinieneś uważać aby pisać przenośny kod zamiast go usztywniać w sprawie separatorów ścieżek:
glob.glob(os.path.join('mydir', 'subdir', '*.html'))
os.listdir(os.path.join('mydir', 'subdir'))
2.1. Tworzenie list całych pakietów¶
The packages
option tells the Distutils to process (build, distribute,
install, etc.) all pure Python modules found in each package mentioned in the
packages
list. In order to do this, of course, there has to be a
correspondence between package names and directories in the filesystem. The
default correspondence is the most obvious one, i.e. package distutils
is
found in the directory distutils
relative to the distribution root.
Thus, when you say packages = ['foo']
in your setup script, you are
promising that the Distutils will find a file foo/__init__.py
(which
might be spelled differently on your system, but you get the idea) relative to
the directory where your setup script lives. If you break this promise, the
Distutils will issue a warning but still process the broken package anyway.
If you use a different convention to lay out your source directory, that’s no
problem: you just have to supply the package_dir
option to tell the
Distutils about your convention. For example, say you keep all Python source
under lib
, so that modules in the „root package” (i.e., not in any
package at all) are in lib
, modules in the foo
package are in
lib/foo
, and so forth. Then you would put
package_dir = {'': 'lib'}
w swoim skrypcie instalacyjnym. Kluczami do tego słownika są nazwy pakietów, a nazwa pakietu pustego oznacza pakiet nadrzędny ( - z ang. - dosł. - „root package”). Wartościami są nazwy katalogów względne wobec katalogu głównego dystrybucji. W tym przypadku gdy mówisz packages = ['foo']
, składasz obietnicę że plik lib/foo/__init__.py
istnieje.
Inną możliwą konwencją jest umieszczenie pakietu foo
od razu w katalogu lib
, pakietu foo.bar
w katalogu lib/bar
itd. To byłoby zapisane w skrypcie instalacyjnym jako
package_dir = {'foo': 'lib'}
A package: dir
entry in the package_dir
dictionary implicitly
applies to all packages below package, so the foo.bar
case is
automatically handled here. In this example, having packages = ['foo',
'foo.bar']
tells the Distutils to look for lib/__init__.py
and
lib/bar/__init__.py
. (Keep in mind that although package_dir
applies recursively, you must explicitly list all packages in
packages
: the Distutils will not recursively scan your source tree
looking for any directory with an __init__.py
file.)
2.2. Tworzenie list pojedynczych modułów¶
Dla małej dystrybucji modułu, mógłbyś chcieć wypisać wszystkie moduły zamiast wypisywać pakiety—szczególnie w przypadku pojedynczego modułu, który wchodzi w skład „nadrzędnego pakietu” - z ang. - „root package” (tj. żadnego pakietu wcale). Najprostszy przypadek został pokazany w sekcji Prosty przykład; tutaj jest pokazany trochę bardziej zaangażowany przykład:
py_modules = ['mod1', 'pkg.mod2']
This describes two modules, one of them in the „root” package, the other in the
pkg
package. Again, the default package/directory layout implies that
these two modules can be found in mod1.py
and pkg/mod2.py
, and
that pkg/__init__.py
exists as well. And again, you can override the
package/directory correspondence using the package_dir
option.
2.3. Opisywanie modułów rozszerzających¶
Tak jak pisanie modułów rozszerzających języka pytonowskiego jest trochę bardziej skomplikowane niż pisanie czystych modułów języka pytonowskiego, opisywanie ich dla Distutils jest trochę bardziej skomplikowane. W przeciwieństwie do modułów czysto pytonowskich, nie wystarczy po prostu wypisać po prostu wszystkich modułów lub pakietów i oczekiwać, że Distutils znajdzie właściwe pliki; musisz określić nazwę rozszerzenia, plik(i) źródłowe, i wszystkie wymagania kompilacji i łączenia plików wynikowych (katalogi załączane, biblioteki z którymi nastąpi łączenie, itd.).
All of this is done through another keyword argument to setup()
, the
ext_modules
option. ext_modules
is just a list of
Extension
instances, each of which describes a
single extension module.
Suppose your distribution includes a single extension, called foo
and
implemented by foo.c
. If no additional instructions to the
compiler/linker are needed, describing this extension is quite simple:
Extension('foo', ['foo.c'])
Uogólnienie Extension
może być importowane z modułu distutils.core
razem z zadaniem setup()
. Zatem skrypt instalacyjny dla dystrybucji modułu, który zawiera tylko to rozszerzenie i nic więcej mógłby wyglądać:
from distutils.core import setup, Extension
setup(name='foo',
version='1.0',
ext_modules=[Extension('foo', ['foo.c'])],
)
Uogólnienie Extension
(właściwie leżąca pod spodem machina budowania rozszerzeń wypełniona przez polecenie build_ext daje całkiem sporo możliwości w opisywaniu rozszerzeń języka pytonowskiego, które są opisywane w następnych paragrafach.
2.3.1. Nazwy i pakiety rozszerzeń.¶
The first argument to the Extension
constructor is
always the name of the extension, including any package names. For example,
Extension('foo', ['src/foo1.c', 'src/foo2.c'])
opisuje rozszerzenie które przebywa w nadrzędnym pakiecie, podczas gdy:
Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c'])
opisuje tożsame rozszerzenie w pakiecie pkg
. Pliki źródłowe i wynikający kod obiektowy są identyczne w obu przypadkach; jedyną różnicą jest gdzie w systemie plików (i stąd też gdzie w hierarchii przestrzeni nazw) wynikające rozszerzenie będzie przebywać.
If you have a number of extensions all in the same package (or all under the
same base package), use the ext_package
keyword argument to
setup()
. For example,
setup(...,
ext_package='pkg',
ext_modules=[Extension('foo', ['foo.c']),
Extension('subpkg.bar', ['bar.c'])],
)
skompiluje plik foo.c
do rozszerzenia pkg.foo
, i plik bar.c
do pkg.subpkg.bar
.
2.3.2. pliki źródłowe rozszerzenia¶
The second argument to the Extension
constructor is
a list of source
files. Since the Distutils currently only support C, C++, and Objective-C
extensions, these are normally C/C++/Objective-C source files. (Be sure to use
appropriate extensions to distinguish C++ source files: .cc
and
.cpp
seem to be recognized by both Unix and Windows compilers.)
Jednakże, możesz też załączyć sprzęg plików SWIG (.i
) na liście; polecenie build_ext wie jak radzić sobie z rozszerzeniami SWIG: uruchomi SWIG na pliku sprzęgu i skompiluje wynikający plik C/C++ do twojego rozszerzenia.
Pomimo tego ostrzeżenia, opcje dla sprzęgu SWIG mogą być obecnie przekazywane w następujący sposób:
setup(...,
ext_modules=[Extension('_foo', ['foo.i'],
swig_opts=['-modern', '-I../include'])],
py_modules=['foo'],
)
Lub w wierszu poleceń w następujący sposób:
> python setup.py build_ext --swig-opts="-modern -I../include"
Na niektórych maszynach/środowiskach, możesz załączyć nie-źródłowe pliki które są przetwarzane przez kompilator i załączane w twoim rozszerzeniu. Obecnie, to po prostu oznacza pliki Windowsowych wiadomości tekstowych (.mc
) i definicji zasobów (.rc
) dla Visual C++. Te będą skompilowane do plików zasobów binarnych (.res
) i połączonych w plik wykonywalny.
2.3.3. Opcje preprocesora¶
Three optional arguments to Extension
will help if
you need to specify include directories to search or preprocessor macros to
define/undefine: include_dirs
, define_macros
, and undef_macros
.
Dla przykładu, jeśli twoje rozszerzenie wymaga pliku nagłówkowego w katalogu include
pod twoim katalogiem nadrzędnym dystrybucji, użyj opcji include_dirs
Extension('foo', ['foo.c'], include_dirs=['include'])
Możesz także określić bezwzględne ścieżki katalogów tutaj; jeśli wiesz że twoje rozszerzenie będzie budowane tylko na systemie Unix-owym z X11R6 zainstalowanym do pliku /usr
, może Ci ujść na sucho nawet:
Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11'])
Powinieneś unikać tego rodzaju nie-przenośnego użycia jeśli planujesz rozprowadzać swój kod: jest prawdopodobnie dużo lepiej pisać kod C w następujący sposób
#include <X11/Xlib.h>
If you need to include header files from some other Python extension, you can
take advantage of the fact that header files are installed in a consistent way
by the Distutils install_headers command. For example, the Numerical
Python header files are installed (on a standard Unix installation) to
/usr/local/include/python1.5/Numerical
. (The exact location will differ
according to your platform and Python installation.) Since the Python include
directory—/usr/local/include/python1.5
in this case—is always
included in the search path when building Python extensions, the best approach
is to write C code like
#include <Numerical/arrayobject.h>
Jeśli jednak musisz wstawić katalog załączeń Numerical
w całości do twojej ścieżki poszukiwań nagłówków, jednakże, możesz znaleźć ten katalog używając modułu distutils.sysconfig
Distutils:
from distutils.sysconfig import get_python_inc
incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical')
setup(...,
Extension(..., include_dirs=[incdir]),
)
Chociaż nawet to jest całkiem przenośne—będzie działać na każdej instalacji języka pytonowskiego, niezależnie od maszyny/środowiska—jest prawdopodobnie dużo łatwiej po prostu napisać twój kod C w rozsądny sposób.
Możesz definiować i odwoływać definicje makropoleceń pre-procesora za pomocą opcji define_macros
i undef_macros
. define_macros
bierze listę (nazwy, wartości)
par-krotek, gdzie nazwa
jest nazwą makropolecenia do zdefiniowania (ciągiem znaków) i wartość
jest jej wartością: albo ciągiem znaków albo None
. Definiowanie makropolecenia FOO
na None
jest równoznaczne czystej definicji #define FOO
w twoim kodzie C: w większości kompilatorów, to ustawia FOO
na ciąg znaków 1
. undef_macros
jest po prostu listą makropoleceń do odwołania definicji.
Dla przykładu:
Extension(...,
define_macros=[('NDEBUG', '1'),
('HAVE_STRFTIME', None)],
undef_macros=['HAVE_FOO', 'HAVE_BAR'])
jest jednoznaczne z ustawieniem tego ponad każdym plikiem źródłowym C:
#define NDEBUG 1
#define HAVE_STRFTIME
#undef HAVE_FOO
#undef HAVE_BAR
2.3.4. Opcje bibliotek¶
Możesz także określić biblioteki do dołączenia gdy budujesz swoje rozszerzenie, i katalogi aby poszukiwać tych bibliotek. Opcja biblioteki
jest listą bibliotek do łączenia, opcja library_dirs
jest listą katalogów do poszukiwania bibliotek w czasie łączenia wynikowego kodu, i runtime_library_dirs
jest listą katalogów do poszukiwania współdzielonych (ładowanych dynamicznie) bibliotek w czasie wykonania.
Dla przykładu, jeśli potrzebujesz łączyć z bibliotekami znanymi z tego, że są w standardowej ścieżce poszukiwań w docelowym systemie
Extension(...,
libraries=['gdbm', 'readline'])
Jeśli musisz podłączyć z bibliotekami w nie-standardowym położeniu, musisz załączyć to położenie w opcji library_dirs
:
Extension(...,
library_dirs=['/usr/X11R6/lib'],
libraries=['X11', 'Xt'])
(Znów, tego rodzaju nie-przenośnych konstrukcji powinno się unikać jeśli zamierzasz rozprowadzać twój kod.)
2.3.5. Inne opcje¶
Istnieją wciąż poza tym inne opcje, które mogą być użyte do radzenia sobie ze szczególnymi przypadkami.
The optional
option is a boolean; if it is true,
a build failure in the extension will not abort the build process, but
instead simply not install the failing extension.
The extra_objects
option is a list of object files to be passed to the
linker. These files must not have extensions, as the default extension for the
compiler is used.
extra_compile_args
and extra_link_args
can be used to
specify additional command line options for the respective compiler and linker
command lines.
export_symbols
is only useful on Windows. It can contain a list of
symbols (functions or variables) to be exported. This option is not needed when
building compiled extensions: Distutils will automatically add initmodule
to the list of exported symbols.
The depends
option is a list of files that the extension depends on
(for example header files). The build command will call the compiler on the
sources to rebuild extension if any on this files has been modified since the
previous build.
2.4. Relacje pomiędzy dystrybucją a pakietami¶
Dystrybucja może odnosić się do pakietów na trzy szczególne sposoby:
Może wymagać pakietów lub modułów.
Może dostarczać pakiety lub moduły.
Może powodować że pakiety lub moduły staną się niepotrzebne.
Te relacje mogą być określane przy użyciu kluczowych parametrów zadania distutils.core.setup()
.
Zależności od innych modułów pytonowskich i pakietów mogą być określane przez dostarczenie słowa kluczowego requires jako parametru do zadania setup()
. Wartość musi być listą ciągów znaków. Każdy ciąg znaków określa pakiet, który jest wymagany, i opcjonalnie które wersje są wystarczające.
Aby określić, że któraś wersja modułu lub pakietu jest wymagana, ciąg znaków powinien składać się w całości z nazwy modułu lub pakietu. Przykłady obejmują 'mojmodul'
i 'xml.parsers.expat'
.
Jeśli szczególne wersje są wymagane, sekwencja kwalifikatorów może być dostarczona w nawiasach. Każdy kwalifikator może składać się z operatora porównania i numeru wersji. Akceptowane operatory porównania to:
< > ==
<= >= !=
Te mogą być łączone przez użycie wielu kwalifikatorów rozdzielonych przecinkami (i nadobowiązkowymi znakami białymi). W tym przypadku, wszystkie kwalifikatory muszą się zgadzać; logiczna koniunkcja jest używana do wiązania wyników.
Spójrzmy na wiecheć przykładów:
Wyrażenie wymagania |
Wytłumaczenie |
---|---|
|
Tylko wersja |
|
Wszystkie wersje po |
Teraz gdy możemy określić zależności, potrzebujemy także móc określić co dostarczamy a czego inne dystrybucje mogłyby wymagać. To jest dokonywane przy użyciu parametru kluczowego provides dla zadania setup()
. Wartość tego słowa kluczowego jest listą ciągów znaków, z których każdy nazywa pytonowski moduł lub pakiet, i dodatkowo (nadobowiązkowo) określa wersję. Jeśli wersja nie jest określona, zakładana jest zgodność wersji z wersją dystrybucji.
Trochę przykładów:
Wyrażenie dostarczania |
Wytłumaczenie |
---|---|
|
Dostarcza |
|
Dostarcz |
Pakiet może deklarować że powoduje że inny pakiet staje się niepotrzebny używając parametru kluczowego obsoletes. Wartość tego jest podobna do tej słowa kluczowego requires: lista ciągów znaków dających wyszczególnienie modułu lub pakietu. Każdy ciąg wyszczególniający składa się z nazwy modułu lub pakietu po której dodatkowo (nadobowiązkowo) występuje jeden lub więcej kwalifikator wersji. Kwalifikatory wersji dane są w nawiasie po nazwie modułu lub pakietu.
Wersje określone przez kwalifikatory to te które stają się zbędne z powodu dystrybucji której dotyczy opis. Jeśli nie są dane żadne kwalifikatory wszystkie wersje nazwanego modułu lub pakietu rozumie się jako zbędne.
2.5. Instalowanie skryptów¶
Do tej pory zajmowaliśmy się czystymi i nie-czystymi modułami pytonowskimi, które nie są zwykle uruchamiane same przez siebie ale importowane przez skrypty.
Scripts are files containing Python source code, intended to be started from the
command line. Scripts don’t require Distutils to do anything very complicated.
The only clever feature is that if the first line of the script starts with
#!
and contains the word „python”, the Distutils will adjust the first line
to refer to the current interpreter location. By default, it is replaced with
the current interpreter location. The --executable
(or -e
)
option will allow the interpreter path to be explicitly overridden.
The scripts
option simply is a list of files to be handled in this
way. From the PyXML setup script:
setup(...,
scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
)
Zmienione w wersji 3.1: All the scripts will also be added to the MANIFEST
file if no template is
provided. See Określanie plików do rozprowadzenia.
2.6. Instalowanie danych pakietu¶
Często dodatkowe pliki konieczne są do zainstalowania dla pakietu. Te pliki są często plikami danych które są blisko związane z wypełnieniem zadań pakietu, lub plikami tekstowymi zawierającymi dokumentację która może być interesująca dla programisty używającego pakietu. Te pliki zwane są danymi pakietu.
Dane pakietu mogą być dodawane do pakietów używając słowa kluczowego package_data
- z ang. - danych pakietu
parametru dla zadania setup()
. Wartość musi być mapowaniem z nazwy pakietu na listę odnoszących się nazw ścieżek które powinny zostać skopiowane do pakietu. Ścieżki są interpretowane jako względne do katalogu zawierającego pakiet (informacja z mapowania package_dir
jest używana jeśli jest to właściwe); to jest, pliki oczekiwane są aby były częścią pakietu w katalogach źródłowych. Mogą zawierać znaczniki „globalne” także.
Nazwy ścieżek mogą zawierać porcje katalogów; wszystkie konieczne katalogi zostaną utworzone w instalacji.
Na przykład, jeśli pakiet zawiera podkatalog z wieloma plikami danych, pliki mogą być ułożone w taki sposób w drzewie źródłowym:
setup.py
src/
mypkg/
__init__.py
module.py
data/
tables.dat
spoons.dat
forks.dat
Odpowiadające wezwanie zadania setup()
mogłoby być:
setup(...,
packages=['mypkg'],
package_dir={'mypkg': 'src/mypkg'},
package_data={'mypkg': ['data/*.dat']},
)
Zmienione w wersji 3.1: All the files that match package_data
will be added to the MANIFEST
file if no template is provided. See Określanie plików do rozprowadzenia.
2.7. Instalowanie dodatkowych plików¶
The data_files
option can be used to specify additional files needed
by the module distribution: configuration files, message catalogs, data files,
anything which doesn’t fit in the previous categories.
data_files
specifies a sequence of (directory, files) pairs in the
following way:
setup(...,
data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
('config', ['cfg/data.cfg'])],
)
Each (directory, files) pair in the sequence specifies the installation directory and the files to install there.
Each file name in files is interpreted relative to the setup.py
script at the top of the package source distribution. Note that you can
specify the directory where the data files will be installed, but you cannot
rename the data files themselves.
The directory should be a relative path. It is interpreted relative to the
installation prefix (Python’s sys.prefix
for system installations;
site.USER_BASE
for user installations). Distutils allows directory to be
an absolute installation path, but this is discouraged since it is
incompatible with the wheel packaging format. No directory information from
files is used to determine the final location of the installed file; only
the name of the file is used.
You can specify the data_files
options as a simple sequence of files
without specifying a target directory, but this is not recommended, and the
install command will print a warning in this case. To install data
files directly in the target directory, an empty string should be given as the
directory.
Zmienione w wersji 3.1: All the files that match data_files
will be added to the MANIFEST
file if no template is provided. See Określanie plików do rozprowadzenia.
2.8. Dodatkowe dane o danych¶
Skrypt instalacyjny może zawierać dodatkowe dane pośrednie poza nazwą i wersją. Te informacje zawierają:
dane-o-danych |
Opis |
Wartość |
Notatki |
---|---|---|---|
|
nazwa pakietu |
krótki ciąg znaków |
(1) |
|
wersja tego wydania |
krótki ciąg znaków |
(1)(2) |
|
nazwisko i imie autora pakietu |
krótki ciąg znaków |
(3) |
|
adres email autora pakietu |
adres email |
(3) |
|
imie (i nazwisko) zarządcy pakietu |
krótki ciąg znaków |
(3) |
|
adres email zarządcy pakietu |
adres email |
(3) |
|
adres strony domowej pakietu |
URL |
(1) |
|
krótki opis podsumowujący pakietu |
krótki ciąg znaków |
|
|
dłuższy opis pakietu |
długi ciąg znaków |
(4) |
|
miejsce skąd pakiet może być pobrany |
URL |
|
|
lista klasyfikatorów |
lista ciągów znaków |
(6)(7) |
|
lista maszyn/środowisk |
lista ciągów znaków |
(6)(8) |
|
a list of keywords |
lista ciągów znaków |
(6)(8) |
|
licencja pakietu |
krótki ciąg znaków |
(5) |
Uwagi:
Te pola są wymagane.
Jest zalecane aby wersja miała postać major.minor[.patch[.sub]].
Either the author or the maintainer must be identified. If maintainer is provided, distutils lists it as the author in
PKG-INFO
.The
long_description
field is used by PyPI when you publish a package, to build its project page.Pole
licencja
- z ang. -license
jest tekstem oznaczającym licencję ochraniającą pakiet gdzie licencja nie jest wybrana z klasyfikacji „Licencji” Znaleźnych. Zobacz poleClassifier
-klasyfikator
. Zauważ, że istnieje opcja dystrybucjilicencji
która choć jest przestarzała ale wciąż służy jako synonimlicencji
.This field must be a list.
The valid classifiers are listed on PyPI.
To preserve backward compatibility, this field also accepts a string. If you pass a comma-separated string
'foo, bar'
, it will be converted to['foo', 'bar']
, Otherwise, it will be converted to a list of one string.
- «short string»
Pojedyncza linia tekstu, nie więcej niż 200 znaków.
- «long string»
Multiple lines of plain text in reStructuredText format (see http://docutils.sourceforge.net/).
- «list of strings»
Zob poniżej.
Kodowanie informacji o wersji jest sztuką samą w sobie. Pakiety języka pytonowskiego zwykle stosują się do formatu wersji główna.poboczna[.łatka][pod]. Główny numer jest 0 w początkowych eksperymentalnych wydaniach oprogramowania. Jest zwiększane dla wydań, które reprezentują główne kroki milowe w pakiecie. Liczba poboczna jest zwiększana gdy istotne nowe własności są dodawane do pakietu. Numer łatki zwiększa się gdy naprawy błędów są robione. Dodatkowe informacje o wersji kończące są czasem używane do zaznaczenia pod-wydań. To są „a1,a2,…,aN” (dla wydań alfa gdzie działanie i sprzęgi programowania mogą ulec zmianie), „b1,b2,…,bN” (dla wydań beta, które tylko naprawiają błędy) i „pr1,pr2,…,prN” (dla końcowych testów wydań przed-wydaniem). Niektóre przykłady:
- 0.1.0
pierwsze, eksperymentalne wydanie pakietu
- 1.0.1a2
drugie wydanie alpha pierwszej łatki w wersji 1.0
classifiers
must be specified in a list:
setup(...,
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Console',
'Environment :: Web Environment',
'Intended Audience :: End Users/Desktop',
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: Python Software Foundation License',
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Programming Language :: Python',
'Topic :: Communications :: Email',
'Topic :: Office/Business',
'Topic :: Software Development :: Bug Tracking',
],
)
Zmienione w wersji 3.7: setup
now warns when classifiers
, keywords
or platforms
fields are not specified as a list or a string.
2.9. Odpluskwianie skryptu instalacyjnego¶
Czasami sprawy źle idą, i skrypt instalacyjny nie robi tego czego chce twórca oprogramowania.
Distutils przechwytuje wszelkie wyjątki gdy uruchamiasz skrypt instalacyjny, i wypisuje prosty komunikat o błędzie zanim skrypt zostanie zakończony. Motywacją dla tego zachowania jest to aby nie wprowadzać zamieszania administratora który nie wie za wiele o języku pytonowskim i próbuje zainstalować pakiet. Jeśli dostanie długi duży wypis z głębi gardzieli Distutils, mogą pomyśleć że pakiet lub instalacja języka pytonowskiego jest popsuta gdyż nie przeczytali wszystkiego do dna i będą sądzić że jest to błąd dostępu.
On the other hand, this doesn’t help the developer to find the cause of the
failure. For this purpose, the DISTUTILS_DEBUG
environment variable can be set
to anything except an empty string, and distutils will now print detailed
information about what it is doing, dump the full traceback when an exception
occurs, and print the whole command line when an external program (like a C
compiler) fails.