Рабочий процесс для поддержки разных версий кодовой базы для разных версий Python - PullRequest
4 голосов
/ 10 октября 2009

Я разрабатываю приложение с открытым исходным кодом под названием GarlicSim .

До сих пор я разрабатывал его только для Python 2.6. Кажется, не работает на любой другой версии.

Я решил, что важно выпускать его версии, которые будут поддерживать другие версии Python. Я думаю, что сделаю версию для 2.5, 3.1 и, возможно, 2.4.

Итак, у меня есть несколько вопросов:

  1. Что было бы хорошим способом организовать структуру папок моего репо, включающую эти разные версии?
  2. Что было бы хорошим способом «объединить» изменения, которые я делаю в одной версии кода, с другими версиями? Я знаю, как выполнять слияния в моем SCM (это git), но это папки, которые находятся в одном репо, и я хочу объединить их. Конечно, есть возможность иметь репо для каждой версии, но я думаю, что это не очень хорошая идея.

У кого-нибудь есть предложения?

Ответы [ 4 ]

3 голосов
/ 10 октября 2009

Вам нужны отдельные ветки для отдельных версий только в редких случаях. Вы упоминаете контекстные менеджеры, и они великолепны, и было бы отстойно не использовать их, и вы правы. Но для Python 2.4 вам не придется их использовать. Так что это будет отстой. Поэтому, если вы хотите поддерживать Python 2.4, вам придется написать версию без менеджеров контекста. Но этот будет работать и под Python 2.6, поэтому нет смысла иметь там отдельные версии.

Что касается Python 3, то для отдельной ветки есть решение, но, как правило, не самое лучшее. Для поддержки Python 3 есть нечто под названием 2to3, которое преобразует ваш код Python 2 в код Python 3. Он не идеален, поэтому довольно часто вам придется модифицировать код Python 2, чтобы генерировать красивый код Python 3, но в любом случае код Python 2 имеет тенденцию становиться лучше.

С помощью Distribute (поддерживаемый ветвь setuptools) вы можете автоматически вести этот диалог во время установки. Таким образом, вам не нужно иметь отдельную ветку даже для Python 3. См. http://bitbucket.org/tarek/distribute/src/tip/docs/python3.txt для документации по этому вопросу.

Как пишет Пол Макгуайр, даже возможно поддерживать Python 3 и Python 2 с одним и тем же кодом без использования 2to3, но я бы не рекомендовал это делать, если вы хотите поддерживать что-то еще, кроме 2.6 и 3.x. Вы получаете слишком много этих уродливых специальных хаков. С 2.6 достаточно прямой совместимости с Python 3, чтобы можно было писать прилично выглядящий код и поддерживать как Python 2.6 и 3.x, но не Python 2.5 и 3.x.

1 голос
/ 10 октября 2009

Если ваш код не слишком зависит от производительности во время выполнения в обработчиках исключений, вы можете даже обойтись без отдельной ветки для Py3. Мне удалось сохранить одну версию pyparsing для всех моих версий Py2.x, хотя мне пришлось придерживаться подхода «наименьшего общего знаменателя», что означает, что я должен отказаться от использования некоторых конструкций, таких как выражения генератора, и Ваша точка зрения, контекстные менеджеры. Вместо наборов я использую dicts, и все мои выражения генератора переносятся в списки, поэтому они по-прежнему будут работать, возвращаясь к Python 2.3. У меня есть блок в верхней части моего кода, который решает ряд проблем 2х3 (предоставлен пользователем с разбором Робертом Кларком):

_PY3K = sys.version_info[0] > 2
if _PY3K:
    _MAX_INT = sys.maxsize
    basestring = str
    unichr = chr
    unicode = str
    _str2dict = set
    alphas = string.ascii_lowercase + string.ascii_uppercase
else:
    _MAX_INT = sys.maxint
    range = xrange
    def _str2dict(strg):
        return dict( [(c,0) for c in strg] )
    alphas = string.lowercase + string.uppercase

Самая большая трудность, с которой я столкнулся, заключалась в несовместимом синтаксисе для перехвата исключений, который был представлен в Py3 и заменен на

except exceptiontype,varname:

до

except exceptionType as varname:

Конечно, если вам действительно не нужна переменная исключения, вы можете просто написать:

except exceptionType:

и это будет работать на Py2 или Py3. Но если вам нужно получить доступ к исключению, вы все равно можете придумать кросс-совместимый синтаксис:

except exceptionType:
    exceptionvar = sys.exc_info()[1]

Это незначительное наказание во время выполнения, что делает его непригодным для использования в некоторых местах при разборе, поэтому мне все еще приходится поддерживать отдельные версии Py2 и Py3. Для слияния исходного кода я использую утилиту WinMerge , которая мне очень подходит для синхронизации каталогов исходного кода.

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

1 голос
/ 10 октября 2009

Я бы попытался сохранить одну ветку, чтобы охватить весь питон 2.4-2.6

Различия не так велики, в конце концов, если вам нужно написать кучу дополнительного кода для 2.4, чтобы сделать что-то, что легко в 2.6, вам будет меньше работать в долгосрочной перспективе, чтобы использовать версию 2.4 2,5 и 2,6

В Python 3 должна быть другая ветвь, вы все равно должны стараться сохранить как можно больше общего кода.

0 голосов
/ 10 октября 2009

В конце концов я решил иметь 4 разных форка для своего проекта, для 2.4, 2.5, 2.6 и 3.1. Мой главный приоритет - 2.6, и я не хочу ставить под угрозу элегантность этого кода ради 2.4. Так что уродливые хаки совместимости будут на более низких версиях, а не на более высоких версиях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...