# Що нового в Python 2.3

Автор

  A.M. Kuchling

У цій статті пояснюються нові функції Python 2.3. Python 2.3 був випущений 29 липня 2003 року.

Основними темами для Python 2.3 є вдосконалення деяких функцій, доданих у 2.2, додавання різних невеликих, але корисних покращень до основної мови та розширення стандартної бібліотеки. Нова об’єктна модель, представлена в попередній версії, отримала переваги від 18 місяців виправлення помилок і зусиль з оптимізації, які покращили продуктивність класів нового стилю. Було додано кілька нових вбудованих функцій, таких як `sum()` і `enumerate()`. Оператор `in` тепер можна використовувати для пошуку підрядка (наприклад, `"ab" у "abc"` повертає `True`).

Деякі з багатьох нових функцій бібліотеки включають типи даних Boolean, set, heap і date/time, можливість імпортувати модулі з архівів у форматі ZIP, підтримку метаданих для довгоочікуваного каталогу Python, оновлену версію IDLE та модулі. для реєстрації повідомлень, обтікання текстом, аналізу файлів CSV, обробки параметрів командного рядка, використання баз даних BerkeleyDB… список нових і вдосконалених модулів довгий.

Ця стаття не намагається надати повну специфікацію нових функцій, натомість надає зручний огляд. Щоб отримати повну інформацію, зверніться до документації для Python 2.3, такої як Довідник бібліотеки Python і Довідковий посібник Python. Якщо ви хочете зрозуміти повну реалізацію та обґрунтування дизайну, зверніться до PEP для конкретної нової функції.

## PEP 218: Тип даних стандартного набору

The new `sets` module contains an implementation of a set datatype. The `Set` class is for mutable sets, sets that can have members added and removed. The `ImmutableSet` class is for sets that can’t be modified, and instances of `ImmutableSet` can therefore be used as dictionary keys. Sets are built on top of dictionaries, so the elements within a set must be hashable.

Ось простий приклад:

    >>> import sets
    >>> S = sets.Set([1,2,3])
    >>> S
    Set([1, 2, 3])
    >>> 1 in S
    True
    >>> 0 in S
    False
    >>> S.add(5)
    >>> S.remove(3)
    >>> S
    Set([1, 2, 5])
    >>>

The union and intersection of sets can be computed with the `union()` and `intersection()` methods; an alternative notation uses the bitwise operators `&` and `|`. Mutable sets also have in-place versions of these methods, `union_update()` and `intersection_update()`.

    >>> S1 = sets.Set([1,2,3])
    >>> S2 = sets.Set([4,5,6])
    >>> S1.union(S2)
    Set([1, 2, 3, 4, 5, 6])
    >>> S1 | S2                  # Alternative notation
    Set([1, 2, 3, 4, 5, 6])
    >>> S1.intersection(S2)
    Set([])
    >>> S1 & S2                  # Alternative notation
    Set([])
    >>> S1.union_update(S2)
    >>> S1
    Set([1, 2, 3, 4, 5, 6])
    >>>

It’s also possible to take the symmetric difference of two sets. This is the set of all elements in the union that aren’t in the intersection. Another way of putting it is that the symmetric difference contains all elements that are in exactly one set. Again, there’s an alternative notation (`^`), and an in-place version with the ungainly name `symmetric_difference_update()`.

    >>> S1 = sets.Set([1,2,3,4])
    >>> S2 = sets.Set([3,4,5,6])
    >>> S1.symmetric_difference(S2)
    Set([1, 2, 5, 6])
    >>> S1 ^ S2
    Set([1, 2, 5, 6])
    >>>

There are also `issubset()` and `issuperset()` methods for checking whether one set is a subset or superset of another:

    >>> S1 = sets.Set([1,2,3])
    >>> S2 = sets.Set([2,3])
    >>> S2.issubset(S1)
    True
    >>> S1.issubset(S2)
    False
    >>> S1.issuperset(S2)
    True
    >>>

Дивись також

PEP 218 - Додавання вбудованого типу об’єкта Set

  PEP, написаний Грегом В. Вілсоном. Реалізовано Грегом В. Вілсоном, Алексом Мартеллі та GvR.

## PEP 255: Прості генератори

У Python 2.2 генератори були додані як необов’язкова функція, яка вмикається директивою `from __future__ import generators`. У версії 2.3 генератори більше не потребують спеціального вмикання, і тепер вони завжди присутні; це означає, що `yield` тепер завжди є ключовим словом. Решта цього розділу є копією опису генераторів із документа «Що нового в Python 2.2»; якщо ви читали це ще під час виходу Python 2.2, ви можете пропустити решту цього розділу.

Ви, безсумнівно, знайомі з тим, як працюють виклики функцій у Python або C. Коли ви викликаєте функцію, вона отримує приватний простір імен, де створюються її локальні змінні. Коли функція досягає оператора `return`, локальні змінні знищуються, а отримане значення повертається до викликаючого. Пізніший виклик тієї ж функції отримає новий набір локальних змінних. Але що, якби локальні змінні не були викинуті під час виходу з функції? Що, якби ви могли пізніше відновити функцію, де вона була зупинена? Це те, що забезпечують генератори; їх можна розглядати як відновлювані функції.

Ось найпростіший приклад функції генератора:

    def generate_ints(N):
        for i in range(N):
            yield i

Для генераторів було введено нове ключове слово `yield`. Будь-яка функція, що містить оператор `yield`, є функцією-генератором; це виявляється компілятором байт-коду Python, який спеціально компілює функцію в результаті.

Коли ви викликаєте функцію генератора, вона не повертає жодного значення; замість цього він повертає об’єкт генератора, який підтримує протокол ітератора. Під час виконання оператора `yield` генератор виводить значення `i`, подібне до оператора `return`. Велика різниця між `yield` і оператором `return` полягає в тому, що при досягненні `yield` стан виконання генератора призупиняється, а локальні змінні зберігаються. Під час наступного виклику методу `.next()` генератора функція відновить виконання відразу після оператора `yield`. (Зі складних причин оператор `yield` не дозволяється всередині блоку `try` оператора `try`…`finally`; читайте PEP 255 для повного пояснення взаємодії між `yield` і винятками.)

Here’s a sample usage of the `generate_ints()` generator:

    >>> gen = generate_ints(3)
    >>> gen
    <generator object at 0x8117f90>
    >>> gen.next()
    0
    >>> gen.next()
    1
    >>> gen.next()
    2
    >>> gen.next()
    Traceback (most recent call last):
      File "stdin", line 1, in ?
      File "stdin", line 2, in generate_ints
    StopIteration

Так само можна написати `for i in generate_ints(5)` або `a,b,c = generate_ints(3)`.

Усередині функції генератора оператор `return` може використовуватися лише без значення та сигналізує про завершення процесії значень; після цього генератор не може повертати жодних додаткових значень. `return` зі значенням, таким як `return 5`, є синтаксичною помилкою у функції генератора. Кінець результатів генератора також можна вказати, піднявши `StopIteration` вручну, або просто дозволивши потоку виконання впасти з нижньої частини функції.

Ви можете досягти ефекту генераторів вручну, написавши власний клас і зберігши всі локальні змінні генератора як змінні екземпляра. Наприклад, щоб повернути список цілих чисел, можна встановити `self.count` на 0, а метод `next()` збільшити `self.count` і повернути його. Однак для помірно складного генератора написання відповідного класу було б набагато складнішим. `Lib/test/test_generators.py` містить ще кілька цікавих прикладів. Найпростіший реалізує рекурсивний обхід дерева за допомогою генераторів.

    # A recursive generator that generates Tree leaves in in-order.
    def inorder(t):
        if t:
            for x in inorder(t.left):
                yield x
            yield t.label
            for x in inorder(t.right):
                yield x

Два інших приклади в `Lib/test/test_generators.py` створюють рішення для проблеми N-Queens (розміщення $N$ ферзів на $NxN$ шахівниці так, щоб жодна королева не загрожувала іншій) і Knight’s Tour (a маршрут, який веде лицаря до кожного поля $NxN$ шахівниці, не відвідуючи жодного поля двічі).

The idea of generators comes from other programming languages, especially Icon (https://www.cs.arizona.edu/icon/), where the idea of generators is central. In Icon, every expression and function call behaves like a generator. One example from «An Overview of the Icon Programming Language» at https://www.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks like:

    sentence := "Store it in the neighboring harbor"
    if (i := find("or", sentence)) > 5 then write(i)

In Icon the `find()` function returns the indexes at which the substring «or» is found: 3, 23, 33. In the `if` statement, `i` is first assigned a value of 3, but 3 is less than 5, so the comparison fails, and Icon retries it with the second value of 23. 23 is greater than 5, so the comparison now succeeds, and the code prints the value 23 to the screen.

Python не заходить так далеко, як Icon, у прийнятті генераторів як центральної концепції. Генератори вважаються частиною основної мови Python, але їх вивчення або використання не є обов’язковим; якщо вони не вирішують жодних ваших проблем, не соромтеся їх ігнорувати. Однією з нових особливостей інтерфейсу Python порівняно з інтерфейсом Icon є те, що стан генератора представлено як конкретний об’єкт (ітератор), який можна передати іншим функціям або зберегти в структурі даних.

Дивись також

PEP 255 - Прості генератори

  Автори: Ніл Шеменауер, Тім Пітерс, Магнус Лі Хетленд. Реалізовано переважно Нілом Шеменауером і Тімом Пітерсом, інші виправлення внесені командою Python Labs.

## PEP 263: Кодування вихідного коду

Вихідні файли Python тепер можна оголошувати такими, що мають різні кодування набору символів. Кодування оголошується шляхом додавання спеціально відформатованого коментаря в перший або другий рядок вихідного файлу. Наприклад, файл UTF-8 можна оголосити за допомогою:

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-

Без такої декларації кодування за замовчуванням використовується 7-бітне кодування ASCII. Виконання або імпортування модулів, які містять рядкові літерали з 8-бітовими символами та не мають декларації кодування, призведе до того, що Python 2.3 повідомить `DeprecationWarning`; у 2.4 це буде синтаксична помилка.

Оголошення кодування впливає лише на рядкові літерали Unicode, які буде перетворено на Unicode за допомогою вказаного кодування. Зауважте, що ідентифікатори Python все ще обмежуються символами ASCII, тому ви не можете мати імена змінних, які містять символи, окрім звичайних букв і цифр.

Дивись також

PEP 263 - Визначення кодувань вихідного коду Python

  Автори: Марк-Андре Лембург і Мартін фон Льовіс; реалізовано Сузукі Хісао та Мартіном фон Льовісом.

## PEP 273: Імпортування модулів із ZIP-архівів

Новий модуль `zipimport` додає підтримку для імпорту модулів з архіву ZIP-формату. Вам не потрібно явно імпортувати модуль; його буде автоматично імпортовано, якщо назву файлу ZIP-архіву буде додано до `sys.path`. Наприклад:

    amk@nyman:~/src/python$ unzip -l /tmp/example.zip
    Archive:  /tmp/example.zip
      Length     Date   Time    Name
     --------    ----   ----    ----
         8467  11-26-02 22:30   jwzthreading.py
     --------                   -------
         8467                   1 file
    amk@nyman:~/src/python$ ./python
    Python 2.3 (#1, Aug 1 2003, 19:54:32)
    >>> import sys
    >>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
    >>> import jwzthreading
    >>> jwzthreading.__file__
    '/tmp/example.zip/jwzthreading.py'
    >>>

Запис у `sys.path` тепер може бути назвою файлу ZIP-архіву. ZIP-архів може містити будь-які файли, але можна імпортувати лише файли з назвами `*.py`, `*.pyc` або `*.pyo`. Якщо архів містить лише файли `*.py`, Python не намагатиметься змінити архів, додавши відповідний файл `*.pyc`, тобто якщо архів ZIP не містить `*.pyc`, імпортування може бути досить повільним.

Шлях всередині архіву також можна вказати лише для імпорту з підкаталогу; наприклад, шлях `/tmp/example.zip/lib/` імпортуватиметься лише з підкаталогу `lib/` в архіві.

Дивись також

PEP 273 - імпортувати модулі з Zip-архівів

  Написав Джеймс К. Алстром, який також забезпечив реалізацію. Python 2.3 відповідає специфікації в PEP 273, але використовує реалізацію, написану Джастом ван Россумом, яка використовує хуки імпорту, описані в PEP 302. Перегляньте розділ PEP 302: нові імпортні гачки для опису нових хуків імпорту.

## PEP 277: Підтримка імен файлів Unicode для Windows NT

У Windows NT, 2000 і XP система зберігає імена файлів як рядки Unicode. Традиційно Python представляє імена файлів у вигляді байтових рядків, що є неадекватним, оскільки робить деякі імена файлів недоступними.

Python now allows using arbitrary Unicode strings (within the limitations of the file system) for all functions that expect file names, most notably the `open()` built-in function. If a Unicode string is passed to `os.listdir()`, Python now returns a list of Unicode strings. A new function, `os.getcwdu()`, returns the current directory as a Unicode string.

Байтові рядки все ще працюють як імена файлів, і в Windows Python прозоро перетворює їх у Unicode за допомогою кодування `mbcs`.

Other systems also allow Unicode strings as file names but convert them to byte strings before passing them to the system, which can cause a `UnicodeError` to be raised. Applications can test whether arbitrary Unicode strings are supported as file names by checking `os.path.supports_unicode_filenames`, a Boolean value.

У MacOS `os.listdir()` тепер може повертати імена файлів у кодуванні Unicode.

Дивись також

PEP 277 - Підтримка імен файлів Unicode для Windows NT

  Автор Ніл Ходжсон; реалізований Нілом Ходжсоном, Мартіном фон Льовісом і Марком Хаммондом.

## PEP 278: універсальна підтримка нового рядка

Сьогодні використовуються три основні операційні системи: Microsoft Windows, Macintosh OS від Apple і різні похідні Unix. Невелике роздратування кросплатформної роботи полягає в тому, що всі ці три платформи використовують різні символи для позначення кінців рядків у текстових файлах. Unix використовує символ переводу рядка (символ ASCII 10), MacOS використовує символ повернення каретки (символ ASCII 13), а Windows використовує двосимвольну послідовність повернення каретки плюс новий рядок.

Python’s file objects can now support end of line conventions other than the one followed by the platform on which Python is running. Opening a file with the mode `'U'` or `'rU'` will open a file for reading in universal newlines mode. All three line ending conventions will be translated to a `'\n'` in the strings returned by the various file methods such as `read()` and `readline()`.

Universal newline support is also used when importing modules and when executing a file with the `execfile()` function. This means that Python modules can be shared between all three operating systems without needing to convert the line-endings.

Цю функцію можна вимкнути під час компіляції Python, вказавши параметр `--without-universal-newlines` під час виконання сценарію configure Python.

Дивись також

PEP 278 - Універсальна підтримка нового рядка

  Написаний і реалізований Джеком Янсеном.

## PEP 279: enumerate()

Нова вбудована функція, `enumerate()`, зробить певні цикли трохи зрозумілішими. `enumerate(thing)`, де thing є ітератором або послідовністю, повертає ітератор, який поверне `(0, thing[0])`, `(1, thing[1])`, `(2, thing[2])` і так далі.

Загальна ідіома зміни кожного елемента списку виглядає так:

    for i in range(len(L)):
        item = L[i]
        # ... compute some result based on item ...
        L[i] = result

Це можна переписати за допомогою `enumerate()` як:

    for i, item in enumerate(L):
        # ... compute some result based on item ...
        L[i] = result

Дивись також

PEP 279 - Вбудована функція enumerate().

  Написаний і реалізований Реймондом Д. Хеттінгером.

## PEP 282: пакет журналів

Стандартний пакет для запису журналів, `logging`, було додано до Python 2.3. Він забезпечує потужний і гнучкий механізм для генерації результатів журналювання, які потім можна фільтрувати та обробляти різними способами. Файл конфігурації, написаний у стандартному форматі, можна використовувати для керування поведінкою програми в журналі. Python включає обробники, які записуватимуть записи журналу до стандартної помилки або до файлу чи сокета, надсилатимуть їх до системного журналу чи навіть електронною поштою на певну адресу; звичайно, також можна написати власні класи обробників.

The `Logger` class is the primary class. Most application code will deal with one or more `Logger` objects, each one used by a particular subsystem of the application. Each `Logger` is identified by a name, and names are organized into a hierarchy using `.` as the component separator. For example, you might have `Logger` instances named `server`, `server.auth` and `server.network`. The latter two instances are below `server` in the hierarchy. This means that if you turn up the verbosity for `server` or direct `server` messages to a different handler, the changes will also apply to records logged to `server.auth` and `server.network`. There’s also a root `Logger` that’s the parent of all other loggers.

Для простого використання пакет `logging` містить деякі зручні функції, які завжди використовують кореневий журнал:

    import logging

    logging.debug('Debugging information')
    logging.info('Informational message')
    logging.warning('Warning:config file %s not found', 'server.conf')
    logging.error('Error occurred')
    logging.critical('Critical error -- shutting down')

Це дає такий вихід:

    WARNING:root:Warning:config file server.conf not found
    ERROR:root:Error occurred
    CRITICAL:root:Critical error -- shutting down

In the default configuration, informational and debugging messages are suppressed and the output is sent to standard error. You can enable the display of informational and debugging messages by calling the `setLevel()` method on the root logger.

Notice the `warning()` call’s use of string formatting operators; all of the functions for logging messages take the arguments `(msg, arg1, arg2, ...)` and log the string resulting from `msg % (arg1, arg2, ...)`.

There’s also an `exception()` function that records the most recent traceback. Any of the other functions will also record the traceback if you specify a true value for the keyword argument exc_info.

    def f():
        try:    1/0
        except: logging.exception('Problem recorded')

    f()

Це дає такий вихід:

    ERROR:root:Problem recorded
    Traceback (most recent call last):
      File "t.py", line 6, in f
        1/0
    ZeroDivisionError: integer division or modulo by zero

Трохи просунутіші програми використовуватимуть інший реєстратор, ніж кореневий реєстратор. Функція `getLogger(name)` використовується для отримання певного журналу, створення його, якщо він ще не існує. `getLogger(None)` повертає кореневий реєстратор.

    log = logging.getLogger('server')
     ...
    log.info('Listening on port %i', port)
     ...
    log.critical('Disk full')
     ...

Log records are usually propagated up the hierarchy, so a message logged to `server.auth` is also seen by `server` and `root`, but a `Logger` can prevent this by setting its `propagate` attribute to `False`.

There are more classes provided by the `logging` package that can be customized. When a `Logger` instance is told to log a message, it creates a `LogRecord` instance that is sent to any number of different `Handler` instances. Loggers and handlers can also have an attached list of filters, and each filter can cause the `LogRecord` to be ignored or can modify the record before passing it along. When they’re finally output, `LogRecord` instances are converted to text by a `Formatter` class. All of these classes can be replaced by your own specially written classes.

З усіма цими функціями пакет `logging` має забезпечити достатню гнучкість навіть для найскладніших програм. Це лише неповний огляд його функцій, тому, будь ласка, перегляньте довідкову документацію пакета, щоб отримати всі деталі. Читання PEP 282 також буде корисним.

Дивись також

PEP 282 - Система реєстрації

  Автори: Віней Саджип і Трент Мік; реалізовано Вінаєм Саджипом.

## PEP 285: логічний тип

A Boolean type was added to Python 2.3. Two new constants were added to the `__builtin__` module, `True` and `False`. (`True` and `False` constants were added to the built-ins in Python 2.2.1, but the 2.2.1 versions are simply set to integer values of 1 and 0 and aren’t a different type.)

Об’єкт типу для цього нового типу називається `bool`; конструктор для нього приймає будь-яке значення Python і перетворює його на `True` або `False`.

    >>> bool(1)
    True
    >>> bool(0)
    False
    >>> bool([])
    False
    >>> bool( (1,) )
    True

Більшість стандартних бібліотечних модулів і вбудованих функцій було змінено для повернення логічних значень.

    >>> obj = []
    >>> hasattr(obj, 'append')
    True
    >>> isinstance(obj, list)
    True
    >>> isinstance(obj, tuple)
    False

Логічні значення Python були додані з головною метою зробити код зрозумілішим. Наприклад, якщо ви читаєте функцію та зустрічаєте оператор `повернути 1`, ви можете запитати, чи `1` представляє логічне значення істинності, індекс або коефіцієнт, який множить якусь іншу величину. Однак, якщо оператор `повернути Істину`, значення значення, що повертається, цілком зрозуміле.

Логічні значення Python не додано задля суворої перевірки типу. Дуже сувора мова, така як Паскаль, також завадить вам виконувати арифметику з булевими значеннями, і вимагатиме, щоб вираз у операторі `if` завжди обчислювався як логічний результат. Python не є таким суворим і ніколи не буде, про що прямо говорить PEP 285. Це означає, що ви все ще можете використовувати будь-який вираз у операторі `if`, навіть той, який обчислюється як список, кортеж або якийсь випадковий об’єкт. Логічний тип є підкласом класу `int`, тому арифметика з використанням логічного значення все ще працює.

    >>> True + 1
    2
    >>> False + 1
    1
    >>> False * 75
    0
    >>> True * 75
    75

Підводячи підсумок `True` і `False` у реченні: це альтернативні способи написання цілих значень 1 і 0, з тією єдиною різницею, що `str()` і `repr()` повертає рядки `'True'` і `'False'` замість `'1'` і `'0'`.

Дивись також

PEP 285 - Додавання типу bool

  Написано та реалізовано GvR.

## PEP 293: Зворотні виклики обробки помилок кодека

Під час кодування рядка Юнікод у рядок байтів можуть зустрітися некодовані символи. Наразі Python дозволяв вказувати обробку помилок як «строгу» (викликаючи `UnicodeError`), «ігнорувати» (пропускаючи символ) або «замінювати» (використовуючи знак питання у вихідному рядку), з «суворий» є поведінкою за замовчуванням. Може бути бажано вказати альтернативну обробку таких помилок, таку як вставка посилання на символ XML або посилання на сутність HTML у перетворений рядок.

Python тепер має гнучку структуру для додавання різних стратегій обробки. Нові обробники помилок можна додати за допомогою `codecs.register_error()`, а потім кодеки зможуть отримати доступ до обробника помилок за допомогою `codecs.lookup_error()`. Для кодеків, написаних мовою C, додано еквівалентний C API. Обробник помилок отримує необхідну інформацію про стан, таку як рядок, який перетворюється, позиція в рядку, де було виявлено помилку, і цільове кодування. Тоді обробник може викликати виняток або повернути рядок заміни.

За допомогою цього фреймворку було реалізовано два додаткові обробники помилок: «backslashreplace» використовує лапки Python для представлення некодованих символів, а «xmlcharrefreplace» видає посилання на символи XML.

Дивись також

PEP 293 - Помилка кодека при обробці зворотних викликів

  Написав і реалізував Вальтер Дьорвальд.

## PEP 301: Індекс пакетів і метадані для Distutils

Підтримка давно запитуваного каталогу Python вперше з’являється у 2.3.

Серцем каталогу є нова команда Distutils register. Запуск `python setup.py register` збирає метадані, що описують пакунок, наприклад його назву, версію, супроводжуючого, опис тощо, і надсилає їх на центральний сервер каталогу. Отриманий каталог доступний за адресою https://pypi.org.

To make the catalog a bit more useful, a new optional classifiers keyword argument has been added to the Distutils `setup()` function. A list of Trove-style strings can be supplied to help classify the software.

Ось приклад `setup.py` з класифікаторами, написаними для сумісності зі старішими версіями Distutils:

    from distutils import core
    kw = {'name': "Quixote",
          'version': "0.5.1",
          'description': "A highly Pythonic Web application framework",
          # ...
          }

    if (hasattr(core, 'setup_keywords') and
        'classifiers' in core.setup_keywords):
        kw['classifiers'] = \
            ['Topic :: Internet :: WWW/HTTP :: Dynamic Content',
             'Environment :: No Input/Output (Daemon)',
             'Intended Audience :: Developers'],

    core.setup(**kw)

Повний список класифікаторів можна отримати, запустивши `python setup.py register --list-classifiers`.

Дивись також

PEP 301 - Індекс пакета та метадані для Distutils

  Написаний і реалізований Річардом Джонсом.

## PEP 302: нові імпортні гачки

While it’s been possible to write custom import hooks ever since the `ihooks` module was introduced in Python 1.3, no one has ever been really happy with it because writing new import hooks is difficult and messy. There have been various proposed alternatives such as the `imputil` and `iu` modules, but none of them has ever gained much acceptance, and none of them were easily usable from C code.

PEP 302 borrows ideas from its predecessors, especially from Gordon McMillan’s `iu` module. Three new items are added to the `sys` module:

- `sys.path_hooks` - це список викликаних об’єктів; найчастіше це будуть класи. Кожен виклик приймає рядок, що містить шлях, і або повертає об’єкт імпортера, який оброблятиме імпорт із цього шляху, або викликає виняток `ImportError`, якщо він не може обробити цей шлях.

- `sys.path_importer_cache` кешує об’єкти імпортера для кожного шляху, тому `sys.path_hooks` потрібно буде пройти лише один раз для кожного шляху.

- `sys.meta_path` - це список об’єктів імпортера, які будуть проходити перед перевіркою `sys.path`. Спочатку цей список порожній, але код користувача може додавати до нього об’єкти. Додаткові вбудовані та заморожені модулі можуть бути імпортовані об’єктом, доданим до цього списку.

Importer objects must have a single method, `find_module(fullname, path=None)`. fullname will be a module or package name, e.g. `string` or `distutils.core`. `find_module()` must return a loader object that has a single method, `load_module(fullname)`, that creates and returns the corresponding module object.

Таким чином, псевдокод для нової логіки імпорту Python виглядає приблизно так (трохи спрощено; подробиці див. PEP 302):

    for mp in sys.meta_path:
        loader = mp(fullname)
        if loader is not None:
            <module> = loader.load_module(fullname)

    for path in sys.path:
        for hook in sys.path_hooks:
            try:
                importer = hook(path)
            except ImportError:
                # ImportError, so try the other path hooks
                pass
            else:
                loader = importer.find_module(fullname)
                <module> = loader.load_module(fullname)

    # Not found!
    raise ImportError

Дивись також

PEP 302 - Нові хуки імпорту

  Автори: Джаст ван Россум і Пол Мур. Реалізовано Юстом ван Россумом.

## PEP 305: Файли, розділені комами

Файли, розділені комами, — це формат, який часто використовується для експорту даних із баз даних і електронних таблиць. Python 2.3 додає аналізатор для файлів, розділених комами.

Формат, розділений комами, на перший погляд оманливо простий:

    Costs,150,200,3.95

Прочитати рядок і викликати `line.split(',')`: що може бути простіше? Але додайте рядкові дані, які можуть містити коми, і все стане складнішим:

    "Costs",150,200,3.95,"Includes taxes, shipping, and sundry items"

Великий потворний регулярний вираз може проаналізувати це, але використання нового пакета `csv` набагато простіше:

    import csv

    input = open('datafile', 'rb')
    reader = csv.reader(input)
    for line in reader:
        print line

The `reader()` function takes a number of different options. The field separator isn’t limited to the comma and can be changed to any character, and so can the quoting and line-ending characters.

Можна визначати та реєструвати різні діалекти файлів, розділених комами; наразі існує два діалекти, обидва використовуються Microsoft Excel. Окремий клас `csv.writer` генеруватиме файли, розділені комами, із послідовності кортежів або списків, цитуючи рядки, які містять роздільник.

Дивись також

PEP 305 - API файлів CSV

  Написали та реалізували Кевін Алтіс, Дейв Коул, Ендрю Макнамара, Скіп Монтанаро, Кліфф Веллс.

## PEP 307: Поліпшення соління

The `pickle` and `cPickle` modules received some attention during the 2.3 development cycle. In 2.2, new-style classes could be pickled without difficulty, but they weren’t pickled very compactly; PEP 307 quotes a trivial example where a new-style class results in a pickled string three times longer than that for a classic class.

Вихід полягав у винаході нового протоколу маринування. Функція `pickle.dumps()` довгий час підтримувала текстовий або бінарний прапор. У версії 2.3 цей прапорець змінено з логічного значення на ціле: 0 — це старий текстовий формат pickle, 1 — старий двійковий формат, а тепер 2 — це новий формат, специфічний для 2.3. Нову константу, `pickle.HIGHEST_PROTOCOL`, можна використовувати для вибору найбільш модного доступного протоколу.

Unpickling is no longer considered a safe operation. 2.2’s `pickle` provided hooks for trying to prevent unsafe classes from being unpickled (specifically, a `__safe_for_unpickling__` attribute), but none of this code was ever audited and therefore it’s all been ripped out in 2.3. You should not unpickle untrusted data in any version of Python.

To reduce the pickling overhead for new-style classes, a new interface for customizing pickling was added using three special methods: `__getstate__()`, `__setstate__()`, and `__getnewargs__()`. Consult PEP 307 for the full semantics of these methods.

Щоб ще більше стиснути pickles, тепер можна використовувати цілі коди замість довгих рядків для ідентифікації маринованих класів. Python Software Foundation підтримуватиме список стандартизованих кодів; також є ряд кодів для приватного використання. Наразі коди не вказано.

Дивись також

PEP 307 - Розширення протоколу pickle

  Написано та реалізовано Гвідо ван Россумом і Тімом Пітерсом.

## Розширені зрізи

Починаючи з Python 1.4, синтаксис нарізки підтримує додатковий третій аргумент «крок» або «крок». Наприклад, це законний синтаксис Python: `L[1:10:2]`, `L[:-1:1]`, `L[::-1]`. Це було додано до Python на прохання розробників Numerical Python, який широко використовує третій аргумент. Однак вбудовані типи списків, кортежів і послідовностей рядків Python ніколи не підтримували цю функцію, викликаючи `TypeError`, якщо ви спробували її. Майкл Хадсон вніс патч для усунення цього недоліку.

Наприклад, тепер ви можете легко витягти елементи списку, які мають парні індекси:

    >>> L = range(10)
    >>> L[::2]
    [0, 2, 4, 6, 8]

Від’ємні значення також працюють для створення копії того самого списку у зворотному порядку:

    >>> L[::-1]
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Це також працює для кортежів, масивів і рядків:

    >>> s='abcd'
    >>> s[::2]
    'ac'
    >>> s[::-1]
    'dcba'

Якщо у вас є змінна послідовність, наприклад список або масив, ви можете призначити або видалити розширений фрагмент, але є деякі відмінності між призначенням розширеному та звичайному фрагментам. Призначення звичайному фрагменту можна використовувати для зміни довжини послідовності:

    >>> a = range(3)
    >>> a
    [0, 1, 2]
    >>> a[1:3] = [4, 5, 6]
    >>> a
    [0, 4, 5, 6]

Розширені фрагменти не такі гнучкі. Під час призначення розширеному фрагменту список у правій частині оператора має містити таку ж кількість елементів, як і фрагмент, який він замінює:

    >>> a = range(4)
    >>> a
    [0, 1, 2, 3]
    >>> a[::2]
    [0, 2]
    >>> a[::2] = [0, -1]
    >>> a
    [0, 1, -1, 3]
    >>> a[::2] = [0,1,2]
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: attempt to assign sequence of size 3 to extended slice of size 2

Видалення простіше:

    >>> a = range(4)
    >>> a
    [0, 1, 2, 3]
    >>> a[::2]
    [0, 2]
    >>> del a[::2]
    >>> a
    [1, 3]

One can also now pass slice objects to the `__getitem__()` methods of the built-in sequences:

    >>> range(10).__getitem__(slice(0, 5, 2))
    [0, 2, 4]

Або використовуйте об’єкти фрагментів безпосередньо в нижніх індексах:

    >>> range(10)[slice(0, 5, 2)]
    [0, 2, 4]

To simplify implementing sequences that support extended slicing, slice objects now have a method `indices(length)` which, given the length of a sequence, returns a `(start, stop, step)` tuple that can be passed directly to `range()`. `indices()` handles omitted and out-of-bounds indices in a manner consistent with regular slices (and this innocuous phrase hides a welter of confusing details!). The method is intended to be used like this:

    class FakeSeq:
        ...
        def calc_item(self, i):
            ...
        def __getitem__(self, item):
            if isinstance(item, slice):
                indices = item.indices(len(self))
                return FakeSeq([self.calc_item(i) for i in range(*indices)])
            else:
                return self.calc_item(i)

З цього прикладу ви також можете побачити, що вбудований об’єкт `slice` тепер є об’єктом типу для типу зрізу, і більше не є функцією. Це узгоджується з Python 2.2, де `int`, `str` тощо зазнали тих самих змін.

## Інші зміни мови

Ось усі зміни, внесені Python 2.3 до основної мови Python.

- Оператор `yield` тепер завжди є ключовим словом, як описано в розділі PEP 255: Прості генератори цього документа.

- Було додано нову вбудовану функцію `enumerate()`, як описано в розділі PEP 279: enumerate() цього документа.

- Дві нові константи, `True` і `False` було додано разом із вбудованим типом `bool`, як описано в розділі PEP 285: логічний тип цього документа.

- Конструктор типу `int()` тепер повертатиме довге ціле число замість того, щоб викликати `OverflowError`, коли рядок або число з плаваючою комою занадто велике, щоб поміститися в ціле число. Це може призвести до парадоксального результату, що `isinstance(int(expression), int)` є хибним, але це навряд чи викличе проблеми на практиці.

- Вбудовані типи тепер підтримують розширений синтаксис нарізки, як описано в розділі Розширені зрізи цього документа.

- Нова вбудована функція, `sum(iterable, start=0)`, додає числові елементи в ітераційному об’єкті та повертає їхню суму. `sum()` приймає лише числа, тобто ви не можете використовувати його для об’єднання рядків. (Надав Алекс Мартеллі.)

- `list.insert(pos, value)` використовувався для вставки value на початку списку, коли pos було від’ємним. Поведінку тепер змінено для узгодження з індексуванням фрагментів, тому, коли pos дорівнює -1, значення буде вставлено перед останнім елементом і так далі.

- `list.index(value)`, який шукає value у списку та повертає його індекс, тепер приймає додаткові аргументи start і stop, щоб обмежити пошук лише частиною списку.

- У словниках є новий метод, `pop(key[, *default*])`, який повертає значення, що відповідає key, і видаляє цю пару ключ/значення зі словника. Якщо потрібний ключ відсутній у словнику, повертається default, якщо його вказано, і `KeyError`, якщо його немає.

      >>> d = {1:2}
      >>> d
      {1: 2}
      >>> d.pop(4)
      Traceback (most recent call last):
        File "stdin", line 1, in ?
      KeyError: 4
      >>> d.pop(1)
      2
      >>> d.pop(1)
      Traceback (most recent call last):
        File "stdin", line 1, in ?
      KeyError: 'pop(): dictionary is empty'
      >>> d
      {}
      >>>

  Існує також новий метод класу, `dict.fromkeys(iterable, value)`, який створює словник із ключами, взятими з наданого ітератора iterable, і всіма значеннями, встановленими на value, за умовчанням `None` .

  (Патчі надав Раймонд Геттінгер.)

  Крім того, конструктор `dict()` тепер приймає аргументи ключових слів для спрощення створення невеликих словників:

      >>> dict(red=1, blue=2, green=3, black=4)
      {'blue': 2, 'black': 4, 'green': 3, 'red': 1}

  (Надав Джаст ван Россум.)

- Оператор `assert` більше не перевіряє прапорець `__debug__`, тому ви більше не можете вимкнути твердження, призначивши `__debug__`. Запуск Python із перемикачем `-O` усе одно генеруватиме код, який не виконує жодних тверджень.

- Most type objects are now callable, so you can use them to create new objects such as functions, classes, and modules. (This means that the `new` module can be deprecated in a future Python version, because you can now use the type objects available in the `types` module.) For example, you can create a new module object with the following code:

      >>> import types
      >>> m = types.ModuleType('abc','docstring')
      >>> m
      <module 'abc' (built-in)>
      >>> m.__doc__
      'docstring'

- Було додано нове попередження `PendingDeprecationWarning`, щоб вказати на функції, які перебувають у процесі припинення підтримки. За замовчуванням попередження не друкуватиметься. Щоб перевірити використання функцій, які в майбутньому будуть припинені, укажіть `-Walways::PendingDeprecationWarning::` у командному рядку або скористайтеся `warnings.filterwarnings()`.

- Процес припинення винятків на основі рядків, як у `підвищення "Сталася помилка"`, розпочато. Підвищення рядка тепер ініціює `PendingDeprecationWarning`.

- Використання `None` як назви змінної тепер призведе до попередження `SyntaxWarning`. У майбутній версії Python `None` може нарешті стати ключовим словом.

- The `xreadlines()` method of file objects, introduced in Python 2.1, is no longer necessary because files now behave as their own iterator. `xreadlines()` was originally introduced as a faster way to loop over all the lines in a file, but now you can simply write `for line in file_obj`. File objects also have a new read-only `encoding` attribute that gives the encoding used by the file; Unicode strings written to the file will be automatically converted to bytes using the given encoding.

- The method resolution order used by new-style classes has changed, though you’ll only notice the difference if you have a really complicated inheritance hierarchy. Classic classes are unaffected by this change. Python 2.2 originally used a topological sort of a class’s ancestors, but 2.3 now uses the C3 algorithm as described in the paper «A Monotonic Superclass Linearization for Dylan». To understand the motivation for this change, read Michele Simionato’s article «Python 2.3 Method Resolution Order», or read the thread on python-dev starting with the message at https://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele Pedroni first pointed out the problem and also implemented the fix by coding the C3 algorithm.

- Python runs multithreaded programs by switching between threads after executing N bytecodes. The default value for N has been increased from 10 to 100 bytecodes, speeding up single-threaded applications by reducing the switching overhead. Some multithreaded applications may suffer slower response time, but that’s easily fixed by setting the limit back to a lower number using `sys.setcheckinterval(N)`. The limit can be retrieved with the new `sys.getcheckinterval()` function.

- One minor but far-reaching change is that the names of extension types defined by the modules included with Python now contain the module and a `'.'` in front of the type name. For example, in Python 2.2, if you created a socket and printed its `__class__`, you’d get this output:

      >>> s = socket.socket()
      >>> s.__class__
      <type 'socket'>

  У 2.3 ви отримаєте наступне:

      >>> s.__class__
      <type '_socket.socket'>

- One of the noted incompatibilities between old- and new-style classes has been removed: you can now assign to the `__name__` and `__bases__` attributes of new-style classes. There are some restrictions on what can be assigned to `__bases__` along the lines of those relating to assigning to an instance’s `__class__` attribute.

### Зміни рядків

- Оператор `in` тепер працює інакше для рядків. Раніше під час обчислення `X в Y`, де X і Y є рядками, X міг бути лише одним символом. Тепер це змінилося; X може бути рядком будь-якої довжини, і `X в Y` поверне `True`, якщо X є підрядком Y. Якщо X є порожнім рядком, результат завжди буде `True`.

      >>> 'ab' in 'abcd'
      True
      >>> 'ad' in 'abcd'
      False
      >>> '' in 'abcd'
      True

  Note that this doesn’t tell you where the substring starts; if you need that information, use the `find()` string method.

- The `strip()`, `lstrip()`, and `rstrip()` string methods now have an optional argument for specifying the characters to strip. The default is still to remove all whitespace characters:

      >>> '   abc '.strip()
      'abc'
      >>> '><><abc<><><>'.strip('<>')
      'abc'
      >>> '><><abc<><><>\n'.strip('<>')
      'abc<><><>\n'
      >>> u'\u4000\u4001abc\u4000'.strip(u'\u4000')
      u'\u4001abc'
      >>>

  (Запропоновано Саймоном Бруннінгом і реалізовано Вальтером Дорвальдом.)

- The `startswith()` and `endswith()` string methods now accept negative numbers for the start and end parameters.

- Another new string method is `zfill()`, originally a function in the `string` module. `zfill()` pads a numeric string with zeros on the left until it’s the specified width. Note that the `%` operator is still more flexible and powerful than `zfill()`.

      >>> '45'.zfill(4)
      '0045'
      >>> '12345'.zfill(4)
      '12345'
      >>> 'goofy'.zfill(6)
      '0goofy'

  (Надав Вальтер Дьорвальд.)

- A new type object, `basestring`, has been added. Both 8-bit strings and Unicode strings inherit from this type, so `isinstance(obj, basestring)` will return `True` for either kind of string. It’s a completely abstract type, so you can’t create `basestring` instances.

- Внутрішні рядки більше не є безсмертними і тепер збиратимуть сміття у звичайний спосіб, якщо єдине посилання на них міститься у внутрішньому словнику інтернованих рядків. (Реалізовано Ореном Тірошем.)

### Оптимізації

- Створення екземплярів класу нового стилю стало набагато швидшим; тепер вони швидше, ніж класичні заняття!

- The `sort()` method of list objects has been extensively rewritten by Tim Peters, and the implementation is significantly faster.

- Multiplication of large long integers is now much faster thanks to an implementation of Karatsuba multiplication, an algorithm that scales better than the O(n*n) required for the grade-school multiplication algorithm. (Original patch by Christopher A. Craig, and significantly reworked by Tim Peters.)

- Код операції `SET_LINENO` тепер зник. Це може забезпечити невелике збільшення швидкості, залежно від особливостей вашого компілятора. Перегляньте розділ Інші зміни та виправлення для більш детального пояснення. (Вилучено Майклом Хадсоном.)

- `xrange()` objects now have their own iterator, making `for i in xrange(n)` slightly faster than `for i in range(n)`. (Patch by Raymond Hettinger.)

- У різних гарячих точках було зроблено ряд невеликих змін, щоб покращити продуктивність, як-от вбудовування функції або видалення деякого коду. (Реалізовано переважно GvR, але багато людей внесли окремі зміни.)

Кінцевим результатом оптимізації 2.3 є те, що Python 2.3 виконує тест pystone приблизно на 25% швидше, ніж Python 2.2.

## Нові, покращені та застарілі модулі

Як завжди, стандартна бібліотека Python отримала низку вдосконалень і виправлень помилок. Ось неповний список найбільш помітних змін, відсортованих за алфавітом назв модулів. Зверніться до файлу `Misc/NEWS` у дереві вихідних кодів, щоб отримати більш повний список змін, або перегляньте журнали CVS, щоб отримати всі деталі.

- Модуль `array` тепер підтримує масиви символів Unicode з використанням символу формату `'u'`. Масиви також тепер підтримують використання оператора призначення `+=` для додавання вмісту іншого масиву та оператора призначення `*=` для повторення масиву. (Надав Джейсон Орендорф.)

- The `bsddb` module has been replaced by version 4.1.6 of the PyBSDDB package, providing a more complete interface to the transactional features of the BerkeleyDB library.

  The old version of the module has been renamed to `bsddb185` and is no longer built automatically; you’ll have to edit `Modules/Setup` to enable it. Note that the new `bsddb` package is intended to be compatible with the old module, so be sure to file bugs if you discover any incompatibilities. When upgrading to Python 2.3, if the new interpreter is compiled with a new version of the underlying BerkeleyDB library, you will almost certainly have to convert your database files to the new version. You can do this fairly easily with the new scripts `db2pickle.py` and `pickle2db.py` which you will find in the distribution’s `Tools/scripts` directory. If you’ve already been using the PyBSDDB package and importing it as `bsddb3`, you will have to change your `import` statements to import it as `bsddb`.

- Новий модуль `bz2` є інтерфейсом до бібліотеки стиснення даних bz2. bz2-стиснуті дані зазвичай менші за відповідні `zlib`-стиснуті дані. (Надав Густаво Німейєр.)

- У новий модуль `datetime` додано набір стандартних типів дати/часу. Перегляньте наступний розділ для отримання додаткової інформації.

- The Distutils `Extension` class now supports an extra constructor argument named depends for listing additional source files that an extension depends on. This lets Distutils recompile the module if any of the dependency files are modified. For example, if `sampmodule.c` includes the header file `sample.h`, you would create the `Extension` object like this:

      ext = Extension("samp",
                      sources=["sampmodule.c"],
                      depends=["sample.h"])

  Зміна `sample.h` призведе до перекомпіляції модуля. (Надав Джеремі Гілтон.)

- Other minor changes to Distutils: it now checks for the `CC`, `CFLAGS`, `CPP`, `LDFLAGS`, and `CPPFLAGS` environment variables, using them to override the settings in Python’s configuration (contributed by Robert Weber).

- Previously the `doctest` module would only search the docstrings of public methods and functions for test cases, but it now also examines private ones as well. The `DocTestSuite()` function creates a `unittest.TestSuite` object from a set of `doctest` tests.

- Нова функція `gc.get_referents(object)` повертає список усіх об’єктів, на які посилається object.

- The `getopt` module gained a new function, `gnu_getopt()`, that supports the same arguments as the existing `getopt()` function but uses GNU-style scanning mode. The existing `getopt()` stops processing options as soon as a non-option argument is encountered, but in GNU-style mode processing continues, meaning that options and arguments can be mixed. For example:

      >>> getopt.getopt(['-f', 'filename', 'output', '-v'], 'f:v')
      ([('-f', 'filename')], ['output', '-v'])
      >>> getopt.gnu_getopt(['-f', 'filename', 'output', '-v'], 'f:v')
      ([('-f', 'filename'), ('-v', '')], ['output'])

  (Надав Пітер Естранд.)

- Модулі `grp`, `pwd` і `resource` тепер повертають розширені кортежі:

      >>> import grp
      >>> g = grp.getgrnam('amk')
      >>> g.gr_name, g.gr_gid
      ('amk', 500)

- Модуль `gzip` тепер може обробляти файли розміром понад 2 ГіБ.

- The new `heapq` module contains an implementation of a heap queue algorithm. A heap is an array-like data structure that keeps items in a partially sorted order such that, for every index k, `heap[k] <= heap[2*k+1]` and `heap[k] <= heap[2*k+2]`. This makes it quick to remove the smallest item, and inserting a new item while maintaining the heap property is O(lg n). (See https://xlinux.nist.gov/dads//HTML/priorityque.html for more information about the priority queue data structure.)

  The `heapq` module provides `heappush()` and `heappop()` functions for adding and removing items while maintaining the heap property on top of some other mutable Python sequence type. Here’s an example that uses a Python list:

      >>> import heapq
      >>> heap = []
      >>> for item in [3, 7, 5, 11, 1]:
      ...    heapq.heappush(heap, item)
      ...
      >>> heap
      [1, 3, 5, 11, 7]
      >>> heapq.heappop(heap)
      1
      >>> heapq.heappop(heap)
      3
      >>> heap
      [5, 7, 11]

  (Надав Кевін О’Коннор.)

- The IDLE integrated development environment has been updated using the code from the IDLEfork project (http://idlefork.sourceforge.net). The most notable feature is that the code being developed is now executed in a subprocess, meaning that there’s no longer any need for manual `reload()` operations. IDLE’s core code has been incorporated into the standard library as the `idlelib` package.

- Модуль `imaplib` тепер підтримує IMAP через SSL. (Пірс Лаудер і Тіно Ланге.)

- The `itertools` contains a number of useful functions for use with iterators, inspired by various functions provided by the ML and Haskell languages. For example, `itertools.ifilter(predicate, iterator)` returns all elements in the iterator for which the function `predicate()` returns `True`, and `itertools.repeat(obj, N)` returns `obj` N times. There are a number of other functions in the module; see the package’s reference documentation for details. (Contributed by Raymond Hettinger.)

- Дві нові функції в модулі `math`, `degrees(rads)` і `radians(degs)`, конвертують між радіанами та градусами. Інші функції в модулі `math`, такі як `math.sin()` і `math.cos()`, завжди вимагали вхідних значень, виміряних у радіанах. Також до `math.log()` було додано необов’язковий аргумент base, щоб полегшити обчислення логарифмів для основ, відмінних від `e` і `10`. (Надав Реймонд Геттінгер.)

- Several new POSIX functions (`getpgid()`, `killpg()`, `lchown()`, `loadavg()`, `major()`, `makedev()`, `minor()`, and `mknod()`) were added to the `posix` module that underlies the `os` module. (Contributed by Gustavo Niemeyer, Geert Jansen, and Denis S. Otkidach.)

- In the `os` module, the `*stat()` family of functions can now report fractions of a second in a timestamp. Such time stamps are represented as floats, similar to the value returned by `time.time()`.

  During testing, it was found that some applications will break if time stamps are floats. For compatibility, when using the tuple interface of the `stat_result` time stamps will be represented as integers. When using named fields (a feature first introduced in Python 2.2), time stamps are still represented as integers, unless `os.stat_float_times()` is invoked to enable float return values:

      >>> os.stat("/tmp").st_mtime
      1034791200
      >>> os.stat_float_times(True)
      >>> os.stat("/tmp").st_mtime
      1034791200.6335014

  У Python 2.4 значення за замовчуванням зміниться на завжди повертати числа з плаваючою точкою.

  Application developers should enable this feature only if all their libraries work properly when confronted with floating point time stamps, or if they use the tuple API. If used, the feature should be activated on an application level instead of trying to enable it on a per-use basis.

- Модуль `optparse` містить новий синтаксичний аналізатор аргументів командного рядка, який може конвертувати значення параметрів у певний тип Python і автоматично генеруватиме повідомлення про використання. Перегляньте наступний розділ для отримання додаткової інформації.

- The old and never-documented `linuxaudiodev` module has been deprecated, and a new version named `ossaudiodev` has been added. The module was renamed because the OSS sound drivers can be used on platforms other than Linux, and the interface has also been tidied and brought up to date in various ways. (Contributed by Greg Ward and Nicholas FitzRoy-Dale.)

- Новий модуль `platform` містить ряд функцій, які намагаються визначити різні властивості платформи, на якій ви працюєте. Є функції для отримання архітектури, типу ЦП, версії ОС Windows і навіть версії дистрибутива Linux. (Надав Марк-Андре Лембург.)

- The parser objects provided by the `pyexpat` module can now optionally buffer character data, resulting in fewer calls to your character data handler and therefore faster performance. Setting the parser object’s `buffer_text` attribute to `True` will enable buffering.

- The `sample(population, k)` function was added to the `random` module. population is a sequence or `xrange` object containing the elements of a population, and `sample()` chooses k elements from the population without replacing chosen elements. k can be any value up to `len(population)`. For example:

      >>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn']
      >>> random.sample(days, 3)      # Choose 3 elements
      ['St', 'Sn', 'Th']
      >>> random.sample(days, 7)      # Choose 7 elements
      ['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn']
      >>> random.sample(days, 7)      # Choose 7 again
      ['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th']
      >>> random.sample(days, 8)      # Can't choose eight
      Traceback (most recent call last):
        File "<stdin>", line 1, in ?
        File "random.py", line 414, in sample
            raise ValueError, "sample larger than population"
      ValueError: sample larger than population
      >>> random.sample(xrange(1,10000,2), 10)   # Choose ten odd nos. under 10000
      [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]

  Модуль `random` тепер використовує новий алгоритм, Mersenne Twister, реалізований у C. Він швидший і детальніше вивчений, ніж попередній алгоритм.

  (Усі зміни внесено Реймондом Геттінгером.)

- The `readline` module also gained a number of new functions: `get_history_item()`, `get_current_history_length()`, and `redisplay()`.

- The `rexec` and `Bastion` modules have been declared dead, and attempts to import them will fail with a `RuntimeError`. New-style classes provide new ways to break out of the restricted execution environment provided by `rexec`, and no one has interest in fixing them or time to do so. If you have applications using `rexec`, rewrite them to use something else.

  (Sticking with Python 2.2 or 2.1 will not make your applications any safer because there are known bugs in the `rexec` module in those versions. To repeat: if you’re using `rexec`, stop using it immediately.)

- The `rotor` module has been deprecated because the algorithm it uses for encryption is not believed to be secure. If you need encryption, use one of the several AES Python modules that are available separately.

- Модуль `shutil` отримав функцію `move(src, dest)`, яка рекурсивно переміщує файл або каталог до нового розташування.

- Підтримку вдосконаленої обробки сигналів POSIX було додано до `signal`, але потім знову вилучено, оскільки виявилося неможливим забезпечити його надійну роботу на різних платформах.

- Модуль `socket` тепер підтримує тайм-аути. Ви можете викликати метод `settimeout(t)` для об’єкта сокета, щоб встановити час очікування t секунд. Подальші операції з сокетом, які тривають більше t секунд, перериваються та викликають виняток `socket.timeout`.

  Оригінальна реалізація тайм-ауту була створена Тімом О’Меллі. Майкл Гілфікс інтегрував його в модуль Python `socket` і перевірив його через довгий огляд. Після перевірки коду Гвідо ван Россум переписав його частини. (Це хороший приклад процесу спільної розробки в дії.)

- У Windows модуль `socket` тепер поставляється з підтримкою Secure Sockets Layer (SSL).

- The value of the C `PYTHON_API_VERSION` macro is now exposed at the Python level as `sys.api_version`. The current exception can be cleared by calling the new `sys.exc_clear()` function.

- Новий модуль `tarfile` дозволяє читати та записувати в архівні файли у форматі tar. (Надав Ларс Густебель.)

- The new `textwrap` module contains functions for wrapping strings containing paragraphs of text. The `wrap(text, width)` function takes a string and returns a list containing the text split into lines of no more than the chosen width. The `fill(text, width)` function returns a single string, reformatted to fit into lines no longer than the chosen width. (As you can guess, `fill()` is built on top of `wrap()`. For example:

      >>> import textwrap
      >>> paragraph = "Not a whit, we defy augury: ... more text ..."
      >>> textwrap.wrap(paragraph, 60)
      ["Not a whit, we defy augury: there's a special providence in",
       "the fall of a sparrow. If it be now, 'tis not to come; if it",
       ...]
      >>> print textwrap.fill(paragraph, 35)
      Not a whit, we defy augury: there's
      a special providence in the fall of
      a sparrow. If it be now, 'tis not
      to come; if it be not to come, it
      will be now; if it be not now, yet
      it will come: the readiness is all.
      >>>

  The module also contains a `TextWrapper` class that actually implements the text wrapping strategy. Both the `TextWrapper` class and the `wrap()` and `fill()` functions support a number of additional keyword arguments for fine-tuning the formatting; consult the module’s documentation for details. (Contributed by Greg Ward.)

- The `thread` and `threading` modules now have companion modules, `dummy_thread` and `dummy_threading`, that provide a do-nothing implementation of the `thread` module’s interface for platforms where threads are not supported. The intention is to simplify thread-aware modules (ones that don’t rely on threads to run) by putting the following code at the top:

      try:
          import threading as _threading
      except ImportError:
          import dummy_threading as _threading

  In this example, `_threading` is used as the module name to make it clear that the module being used is not necessarily the actual `threading` module. Code can call functions and use classes in `_threading` whether or not threads are supported, avoiding an `if` statement and making the code slightly clearer. This module will not magically make multithreaded code run without threads; code that waits for another thread to return or to do something will simply hang forever.

- The `time` module’s `strptime()` function has long been an annoyance because it uses the platform C library’s `strptime()` implementation, and different platforms sometimes have odd bugs. Brett Cannon contributed a portable implementation that’s written in pure Python and should behave identically on all platforms.

- The new `timeit` module helps measure how long snippets of Python code take to execute. The `timeit.py` file can be run directly from the command line, or the module’s `Timer` class can be imported and used directly. Here’s a short example that figures out whether it’s faster to convert an 8-bit string to Unicode by appending an empty Unicode string to it or by using the `unicode()` function:

      import timeit

      timer1 = timeit.Timer('unicode("abc")')
      timer2 = timeit.Timer('"abc" + u""')

      # Run three trials
      print timer1.repeat(repeat=3, number=100000)
      print timer2.repeat(repeat=3, number=100000)

      # On my laptop this outputs:
      # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869]
      # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]

- The `Tix` module has received various bug fixes and updates for the current version of the Tix package.

- The `Tkinter` module now works with a thread-enabled version of Tcl. Tcl’s threading model requires that widgets only be accessed from the thread in which they’re created; accesses from another thread can cause Tcl to panic. For certain Tcl interfaces, `Tkinter` will now automatically avoid this when a widget is accessed from a different thread by marshalling a command, passing it to the correct thread, and waiting for the results. Other interfaces can’t be handled automatically but `Tkinter` will now raise an exception on such an access so that you can at least find out about the problem. See https://mail.python.org/pipermail/python-dev/2002-December/031107.html for a more detailed explanation of this change. (Implemented by Martin von Löwis.)

- Calling Tcl methods through `_tkinter` no longer returns only strings. Instead, if Tcl returns other objects those objects are converted to their Python equivalent, if one exists, or wrapped with a `_tkinter.Tcl_Obj` object if no Python equivalent exists. This behavior can be controlled through the `wantobjects()` method of `tkapp` objects.

  When using `_tkinter` through the `Tkinter` module (as most Tkinter applications will), this feature is always activated. It should not cause compatibility problems, since Tkinter would always convert string results to Python types where possible.

  If any incompatibilities are found, the old behavior can be restored by setting the `wantobjects` variable in the `Tkinter` module to false before creating the first `tkapp` object.

      import Tkinter
      Tkinter.wantobjects = 0

  Будь-яку поломку, спричинену цією зміною, слід повідомити як помилку.

- The `UserDict` module has a new `DictMixin` class which defines all dictionary methods for classes that already have a minimum mapping interface. This greatly simplifies writing classes that need to be substitutable for dictionaries, such as the classes in the `shelve` module.

  Adding the mix-in as a superclass provides the full dictionary interface whenever the class defines `__getitem__()`, `__setitem__()`, `__delitem__()`, and `keys()`. For example:

      >>> import UserDict
      >>> class SeqDict(UserDict.DictMixin):
      ...     """Dictionary lookalike implemented with lists."""
      ...     def __init__(self):
      ...         self.keylist = []
      ...         self.valuelist = []
      ...     def __getitem__(self, key):
      ...         try:
      ...             i = self.keylist.index(key)
      ...         except ValueError:
      ...             raise KeyError
      ...         return self.valuelist[i]
      ...     def __setitem__(self, key, value):
      ...         try:
      ...             i = self.keylist.index(key)
      ...             self.valuelist[i] = value
      ...         except ValueError:
      ...             self.keylist.append(key)
      ...             self.valuelist.append(value)
      ...     def __delitem__(self, key):
      ...         try:
      ...             i = self.keylist.index(key)
      ...         except ValueError:
      ...             raise KeyError
      ...         self.keylist.pop(i)
      ...         self.valuelist.pop(i)
      ...     def keys(self):
      ...         return list(self.keylist)
      ...
      >>> s = SeqDict()
      >>> dir(s)      # See that other dictionary methods are implemented
      ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__',
       '__init__', '__iter__', '__len__', '__module__', '__repr__',
       '__setitem__', 'clear', 'get', 'has_key', 'items', 'iteritems',
       'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem',
       'setdefault', 'update', 'valuelist', 'values']

  (Надав Реймонд Геттінгер.)

- The DOM implementation in `xml.dom.minidom` can now generate XML output in a particular encoding by providing an optional encoding argument to the `toxml()` and `toprettyxml()` methods of DOM nodes.

- The `xmlrpclib` module now supports an XML-RPC extension for handling nil data values such as Python’s `None`. Nil values are always supported on unmarshalling an XML-RPC response. To generate requests containing `None`, you must supply a true value for the allow_none parameter when creating a `Marshaller` instance.

- The new `DocXMLRPCServer` module allows writing self-documenting XML-RPC servers. Run it in demo mode (as a program) to see it in action. Pointing the web browser to the RPC server produces pydoc-style documentation; pointing xmlrpclib to the server allows invoking the actual methods. (Contributed by Brian Quinlan.)

- Додано підтримку інтернаціоналізованих доменних імен (RFC 3454, 3490, 3491 і 3492). Кодування «idna» можна використовувати для перетворення між доменним іменем Unicode і ASCII-сумісним кодуванням (ACE) цього імені.

      >{}>{}> u"www.Alliancefrançaise.nu".encode("idna")
      'www.xn--alliancefranaise-npb.nu'

  The `socket` module has also been extended to transparently convert Unicode hostnames to the ACE version before passing them to the C library. Modules that deal with hostnames such as `httplib` and `ftplib`) also support Unicode host names; `httplib` also sends HTTP `Host` headers using the ACE version of the domain name. `urllib` supports Unicode URLs with non-ASCII host names as long as the `path` part of the URL is ASCII only.

  Для впровадження цієї зміни було додано модуль `stringprep`, інструмент `mkstringprep` і кодування `punycode`.

### Тип дати/часу

Типи дати та часу, придатні для вираження позначок часу, були додані як модуль `datetime`. Типи не підтримують різні календарі чи багато модних функцій і лише дотримуються основ представлення часу.

The three primary types are: `date`, representing a day, month, and year; `time`, consisting of hour, minute, and second; and `datetime`, which contains all the attributes of both `date` and `time`. There’s also a `timedelta` class representing differences between two points in time, and time zone logic is implemented by classes inheriting from the abstract `tzinfo` class.

You can create instances of `date` and `time` by either supplying keyword arguments to the appropriate constructor, e.g. `datetime.date(year=1972, month=10, day=15)`, or by using one of a number of class methods. For example, the `date.today()` class method returns the current local date.

Після створення екземпляри класів дати/часу залишаються незмінними. Існує кілька методів створення форматованих рядків з об’єктів:

    >>> import datetime
    >>> now = datetime.datetime.now()
    >>> now.isoformat()
    '2002-12-30T21:27:03.994956'
    >>> now.ctime()  # Only available on date, datetime
    'Mon Dec 30 21:27:03 2002'
    >>> now.strftime('%Y %d %b')
    '2002 30 Dec'

The `replace()` method allows modifying one or more fields of a `date` or `datetime` instance, returning a new instance:

    >>> d = datetime.datetime.now()
    >>> d
    datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)
    >>> d.replace(year=2001, hour = 12)
    datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)
    >>>

Instances can be compared, hashed, and converted to strings (the result is the same as that of `isoformat()`). `date` and `datetime` instances can be subtracted from each other, and added to `timedelta` instances. The largest missing feature is that there’s no standard library support for parsing strings and getting back a `date` or `datetime`.

Для отримання додаткової інформації зверніться до довідкової документації модуля. (Надав Тім Пітерс.)

### Модуль optparse

Модуль `getopt` забезпечує простий аналіз аргументів командного рядка. Новий модуль `optparse` (початкова назва Optik) забезпечує більш детальний аналіз командного рядка, який відповідає умовам Unix, автоматично створює вихід для `--help` і може виконувати різні дії для різних параметрів .

You start by creating an instance of `OptionParser` and telling it what your program’s options are.

    import sys
    from optparse import OptionParser

    op = OptionParser()
    op.add_option('-i', '--input',
                  action='store', type='string', dest='input',
                  help='set input filename')
    op.add_option('-l', '--length',
                  action='store', type='int', dest='length',
                  help='set maximum length of output')

Parsing a command line is then done by calling the `parse_args()` method.

    options, args = op.parse_args(sys.argv[1:])
    print options
    print args

Це повертає об’єкт, що містить усі значення параметрів, і список рядків, що містять решту аргументів.

Виклик сценарію з різними аргументами тепер працює так, як ви очікували. Зауважте, що аргумент довжини автоматично перетворюється на ціле число.

    $ ./python opt.py -i data arg1
    <Values at 0x400cad4c: {'input': 'data', 'length': None}>
    ['arg1']
    $ ./python opt.py --input=data --length=4
    <Values at 0x400cad2c: {'input': 'data', 'length': 4}>
    []
    $

Довідкове повідомлення генерується для вас автоматично:

    $ ./python opt.py --help
    usage: opt.py [options]

    options:
      -h, --help            show this help message and exit
      -iINPUT, --input=INPUT
                            set input filename
      -lLENGTH, --length=LENGTH
                            set maximum length of output
    $

Додаткову інформацію дивіться в документації модуля.

Optik був написаний Грегом Уордом із пропозиціями читачів Getopt SIG.

## Pymalloc: спеціалізований розподільник об’єктів

Pymalloc, спеціалізований розподільник об’єктів, написаний Володимиром Марангозовим, був функцією, доданою до Python 2.1. Pymalloc має бути швидшим за системний `malloc()` і мати менше витрат пам’яті для шаблонів розподілу, типових для програм Python. Розподільник використовує функцію C `malloc()`, щоб отримати великі пули пам’яті, а потім виконує менші запити пам’яті з цих пулів.

У версіях 2.1 і 2.2 pymalloc був експериментальною функцією і не був увімкнений за замовчуванням; ви повинні були явно ввімкнути його під час компіляції Python, надавши опцію `--with-pymalloc` сценарію configure. У версії 2.3 pymalloc отримав додаткові вдосконалення, і тепер він увімкнено за замовчуванням; вам доведеться вказати `--without-pymalloc`, щоб вимкнути його.

Ця зміна прозора для коду, написаного на Python; однак pymalloc може виявити помилки в розширеннях C. Автори модулів розширення C повинні протестувати свій код із увімкненим pymalloc, оскільки деякий неправильний код може спричинити дамп ядра під час виконання.

Є одна особливо поширена помилка, яка викликає проблеми. В API C Python є кілька функцій розподілу пам’яті, які раніше були лише псевдонімами `malloc()` і `free()` бібліотеки C, тобто якщо ви випадково викликали невідповідні функції, помилка не було б помітно. Коли розподільник об’єктів увімкнено, ці функції більше не є псевдонімами `malloc()` і `free()`, і виклик неправильної функції для звільнення пам’яті може призвести до створення дампа ядра. Наприклад, якщо пам’ять було виділено за допомогою `PyObject_Malloc()`, її потрібно звільнити за допомогою `PyObject_Free()`, а не `free()`. Кілька модулів, що входять до складу Python, вийшли з ладу, і їх потрібно було виправити; безсумнівно, є інші сторонні модулі, які матимуть таку саму проблему.

У рамках цієї зміни незрозумілі кілька інтерфейсів для розподілу пам’яті були об’єднані у дві сімейства API. Пам’яттю, виділеною для одного сімейства, не можна маніпулювати функціями з іншого сімейства. Існує одне сімейство для розподілу фрагментів пам’яті та інше сімейство функцій спеціально для розподілу об’єктів Python.

- Щоб виділити та звільнити нерозрізнену частину пам’яті, використовуйте сімейство «необробленої пам’яті»: `PyMem_Malloc()`, `PyMem_Realloc()` і `PyMem_Free()`.

- Сімейство «об’єктної пам’яті» є інтерфейсом до описаного вище засобу pymalloc і спрямоване на велику кількість «маленьких» розподілів: `PyObject_Malloc()`, `PyObject_Realloc()` і `PyObject_Free()`.

- To allocate and free Python objects, use the «object» family `PyObject_New()`, `PyObject_NewVar()`, and `PyObject_Del()`.

Завдяки великій роботі Тіма Пітерса, pymalloc у версії 2.3 також надає функції налагодження для виявлення перезапису пам’яті та подвійного звільнення в обох модулях розширення та в самому інтерпретаторі. Щоб увімкнути цю підтримку, скомпілюйте версію інтерпретатора Python для налагодження, запустивши configure з `--with-pydebug`.

Щоб допомогти розробникам розширень, файл заголовка `Misc/pymemcompat.h` поширюється разом із джерелом для Python 2.3, який дозволяє розширенням Python використовувати інтерфейси 2.3 для розподілу пам’яті під час компіляції з будь-якою версією Python, починаючи з 1.5.2. Ви повинні скопіювати файл із вихідного коду Python і об’єднати його з джерелом вашого розширення.

Дивись також

https://hg.python.org/cpython/file/default/Objects/obmalloc.c

  Щоб отримати повну інформацію про реалізацію pymalloc, перегляньте коментарі у верхній частині файлу `Objects/obmalloc.c` у вихідному коді Python. Наведене вище посилання вказує на файл у браузері python.org SVN.

## Зміни збірки та C API

Зміни в процесі збирання Python і в API C включають:

- Реалізація виявлення циклу, яка використовується для збирання сміття, виявилася стабільною, тому тепер вона стала обов’язковою. Ви більше не можете скомпілювати Python без нього, а перемикач `--with-cycle-gc` на configure видалено.

- Python тепер можна опціонально створити як спільну бібліотеку (`libpython2.3.so`), вказавши `--enable-shared` під час виконання сценарію configure Python. (Надав Ондрей Палковський.)

- The `DL_EXPORT` and `DL_IMPORT` macros are now deprecated. Initialization functions for Python extension modules should now be declared using the new macro `PyMODINIT_FUNC`, while the Python core will generally use the `PyAPI_FUNC` and `PyAPI_DATA` macros.

- Інтерпретатор може бути скомпільований без будь-яких рядків документації для вбудованих функцій і модулів, надаючи `--without-doc-strings` до сценарію configure. Це робить виконуваний файл Python приблизно на 10% меншим, але також означатиме, що ви не зможете отримати допомогу для вбудованих компонентів Python. (Надав Густаво Німейєр.)

- The `PyArg_NoArgs()` macro is now deprecated, and code that uses it should be changed. For Python 2.2 and later, the method definition table can specify the `METH_NOARGS` flag, signalling that there are no arguments, and the argument checking can then be removed. If compatibility with pre-2.2 versions of Python is important, the code could use `PyArg_ParseTuple(args, "")` instead, but this will be slower than using `METH_NOARGS`.

- `PyArg_ParseTuple()` accepts new format characters for various sizes of unsigned integers: `B` for `unsigned char`, `H` for `unsigned short int`, `I` for `unsigned int`, and `K` for `unsigned long long`.

- Нову функцію `PyObject_DelItemString(mapping, char *key)` було додано як скорочення для `PyObject_DelItem(mapping, PyString_New(key))`.

- Файлові об’єкти тепер керують своїм внутрішнім рядковим буфером по-іншому, збільшуючи його експоненціально за потреби. Це призводить до значного прискорення тестів у `Lib/test/test_bufio.py` (з 57 секунд до 1,7 секунд, згідно з одним вимірюванням).

- It’s now possible to define class and static methods for a C extension type by setting either the `METH_CLASS` or `METH_STATIC` flags in a method’s `PyMethodDef` structure.

- Python тепер містить копію вихідного коду синтаксичного аналізатора Expat XML, усуваючи будь-яку залежність від версії системи або локальної інсталяції Expat.

- If you dynamically allocate type objects in your extension, you should be aware of a change in the rules relating to the `__module__` and `__name__` attributes. In summary, you will want to ensure the type’s dictionary contains a `'__module__'` key; making the module name the part of the type name leading up to the final period will no longer have the desired effect. For more detail, read the API reference documentation or the source.

### Зміни, що стосуються порту

Support for a port to IBM’s OS/2 using the EMX runtime environment was merged into the main Python source tree. EMX is a POSIX emulation layer over the OS/2 system APIs. The Python port for EMX tries to support all the POSIX-like capability exposed by the EMX runtime, and mostly succeeds; `fork()` and `fcntl()` are restricted by the limitations of the underlying emulation layer. The standard OS/2 port, which uses IBM’s Visual Age compiler, also gained support for case-sensitive import semantics as part of the integration of the EMX port into CVS. (Contributed by Andrew MacIntyre.)

У MacOS більшість модулів панелі інструментів були слабко зв’язані, щоб покращити зворотну сумісність. Це означає, що модулі більше не будуть завантажуватися, якщо в поточній версії ОС відсутня одна процедура. Натомість виклик відсутньої підпрограми призведе до виключення. (Надав Джек Янсен.)

Файли специфікацій RPM, знайдені в каталозі `Misc/RPM/` вихідного коду Python, було оновлено до версії 2.3. (Надав Шон Райфшнайдер.)

Інші нові платформи, які зараз підтримуються Python, включають AtheOS (http://www.atheos.cx/), GNU/Hurd і OpenVMS.

## Інші зміни та виправлення

Як завжди, була купа інших покращень і виправлень помилок, розкиданих по дереву вихідних кодів. Пошук у журналах змін CVS виявив, що між Python 2.2 і 2.3 було застосовано 523 виправлення та 514 виправлених помилок. Обидві цифри, ймовірно, занижені.

Деякі з найбільш помітних змін:

- Якщо встановлено змінну середовища `PYTHONINSPECT`, інтерпретатор Python увійде в інтерактивну підказку після запуску програми Python, як якщо б Python було викликано з параметром `-i`. Змінну середовища можна встановити перед запуском інтерпретатора Python або її можна встановити програмою Python як частину її виконання.

- Сценарій `regrtest.py` тепер надає спосіб дозволити «всі ресурси, крім foo». Ім’я ресурсу, передане параметру `-u`, тепер може мати перед префіксом дефіс (`'-'`), що означає «видалити цей ресурс». Наприклад, параметр «`-uall,-bsddb`» можна використовувати, щоб увімкнути використання всіх ресурсів, крім `bsddb`.

- Інструменти, які використовуються для створення документації, тепер працюють як під Cygwin, так і під Unix.

- Код операції `SET_LINENO` видалено. У давнину цей код операції був потрібний для створення номерів рядків у відстеженнях і підтримки функцій відстеження (наприклад, для `pdb`). Починаючи з Python 1.5, номери рядків у трасуваннях обчислюються за допомогою іншого механізму, який працює з «python -O». Для Python 2.3 Майкл Хадсон реалізував подібну схему, щоб визначити, коли викликати функцію трасування, повністю усунувши потребу в `SET_LINENO`.

  Було б важко виявити будь-яку результуючу відмінність від коду Python, окрім невеликого прискорення, коли Python запускається без `-O`.

  C extensions that access the `f_lineno` field of frame objects should instead call `PyCode_Addr2Line(f->f_code, f->f_lasti)`. This will have the added effect of making the code work as desired under «python -O» in earlier versions of Python.

  A nifty new feature is that trace functions can now assign to the `f_lineno` attribute of frame objects, changing the line that will be executed next. A `jump` command has been added to the `pdb` debugger taking advantage of this new feature. (Implemented by Richie Hindle.)

## Перенесення на Python 2.3

У цьому розділі перераховано описані раніше зміни, які можуть потребувати змін у вашому коді:

- `yield` тепер завжди є ключовим словом; якщо воно використовується як ім’я змінної у вашому коді, потрібно вибрати інше ім’я.

- Для рядків X і Y «X в Y» тепер працює, якщо X містить більше одного символу.

- Конструктор типу `int()` тепер повертатиме довге ціле число замість того, щоб викликати `OverflowError`, коли рядок або число з плаваючою комою занадто велике, щоб поміститися в ціле число.

- Якщо у вас є рядки Unicode, які містять 8-бітові символи, ви повинні оголосити кодування файлу (UTF-8, Latin-1 або інше), додавши коментар у верхній частині файлу. Перегляньте розділ PEP 263: Кодування вихідного коду для отримання додаткової інформації.

- Calling Tcl methods through `_tkinter` no longer returns only strings. Instead, if Tcl returns other objects those objects are converted to their Python equivalent, if one exists, or wrapped with a `_tkinter.Tcl_Obj` object if no Python equivalent exists.

- Великі вісімкові та шістнадцяткові літерали, такі як `0xffffffff`, тепер викликають `FutureWarning`. Наразі вони зберігаються як 32-розрядні числа та отримують від’ємне значення, але в Python 2.4 вони стануть додатними довгими цілими числами.

  Є кілька способів виправити це попередження. Якщо вам справді потрібне позитивне число, просто додайте `L` до кінця літералу. Якщо ви намагаєтеся отримати 32-розрядне ціле число з установленими молодшими бітами і раніше використовували такий вираз, як `~(1 << 31)`, ймовірно, найзрозуміліше почати з усіма встановленими бітами та очистити потрібний верхній біти. Наприклад, щоб очистити лише верхній біт (біт 31), ви можете написати `0xffffffffL &~(1L<<31)`.

- Ви більше не можете вимкнути твердження, призначивши `__debug__`.

- The Distutils `setup()` function has gained various new keyword arguments such as depends. Old versions of the Distutils will abort if passed unknown keywords. A solution is to check for the presence of the new `get_distutil_options()` function in your `setup.py` and only uses the new keywords with a version of the Distutils that supports them:

      from distutils import core

      kw = {'sources': 'foo.c', ...}
      if hasattr(core, 'get_distutil_options'):
          kw['depends'] = ['foo.h']
      ext = Extension(**kw)

- Використання `None` як назви змінної тепер призведе до попередження `SyntaxWarning`.

- Назви типів розширень, визначені модулями, що входять до Python, тепер містять модуль і `'.'` перед назвою типу.

## Подяки

Автор хотів би подякувати наступним людям за пропозиції, виправлення та допомогу з різними чернетками цієї статті: Джефф Бауер, Саймон Бруннінг, Бретт Кеннон, Майкл Чермсайд, Ендрю Далк, Скотт Девід Деніелс, Фред Л. Дрейк молодший, Девід Фрейзер, Келлі Гербер, Реймонд Геттінгер, Майкл Хадсон, Кріс Ламберт, Детлеф Ланнерт, Мартін фон Левіс, Ендрю Макінтайр, Лало Мартінс, Чад Нетцер, Густаво Німейєр, Ніл Норвіц, Ханс Новак, Кріс Ріді, Франческо Ріккарді, Віней Саджип, Ніл Шеменауер, Роман Сузі, Джейсон Тішлер, Юст ван Россум.