# 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:

1. Może wymagać pakietów lub modułów.

2. Może dostarczać pakiety lub moduły.

3. 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
--- | ---
`==1.0` | Tylko wersja `1.0` jest zgodna
`>1.0, !=1.5.1, <2.0` | Wszystkie wersje po `1.0` i przed `2.0` są zgodne z wyjątkiem `1.5.1`

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
--- | ---
`mojpakiet` | Dostarcza `mojpakiet`, używając wersji dystrybucji
`mojpakiet (1.1)` | Dostarcz `mojpakiet` w wersji 1.1, niezależnie od wersji dystrybucji

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']),
                      ('/etc/init.d', ['init-script'])]
         )

Note that you can specify the directory names where the data files will be installed, but you cannot rename the data files themselves.

Each (directory, files) pair in the sequence specifies the installation directory and the files to install there. If directory is a relative path, it is interpreted relative to the installation prefix (Python’s `sys.prefix` for pure-Python packages, `sys.exec_prefix` for packages that contain extension modules). Each file name in files is interpreted relative to the `setup.py` script at the top of the package source distribution. 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` | nazwa pakietu | krótki ciąg znaków | (1)
`wersja` | wersja tego wydania | krótki ciąg znaków | (1)(2)
`autor` | nazwisko i imie autora pakietu | krótki ciąg znaków | (3)
`adres_email_autora` | adres email autora pakietu | adres email | (3)
`zarządca` | imie (i nazwisko) zarządcy pakietu | krótki ciąg znaków | (3)
`adres_email_zarządcy` | adres email zarządcy pakietu | adres email | (3)
`url` | adres strony domowej pakietu | URL | (1)
`opis` | krótki opis podsumowujący pakietu | krótki ciąg znaków |
`dlugi_opis` | dłuższy opis pakietu | długi ciąg znaków | (5)
`adres_sciagniecia` | miejsce skąd pakiet może być pobrany | URL | (4)
`klasyfikatory` | lista klasyfikatorów | lista ciągów znaków | (4)
`maszyny_srodowiska` | lista maszyn/środowisk | lista ciągów znaków |
`licencja` | licencja pakietu | krótki ciąg znaków | (6)

Uwagi:

1. Te pola są wymagane.

2. Jest zalecane aby wersja miała postać major.minor[.patch[.sub]].

3. Either the author or the maintainer must be identified. If maintainer is provided, distutils lists it as the author in `PKG-INFO`.

4. These fields should not be used if your package is to be compatible with Python versions prior to 2.2.3 or 2.3. The list is available from the PyPI website.

5. The `long_description` field is used by PyPI when you are registering a package, to build its home page.

6. Pole `licencja` - z ang. - `license` jest tekstem oznaczającym licencję ochraniającą pakiet gdzie licencja nie jest wybrana z klasyfikacji „Licencji” Znaleźnych. Zobacz pole `Classifier` - `klasyfikator`. Zauważ, że istnieje opcja dystrybucji `licencji` która choć jest przestarzała ale wciąż służy jako synonim `licencji`.

«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` are specified in a Python 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',
              ],
          )

## 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.