Подтвердить что ты не робот

Не трогайте мой shebang

Одна вещь, которую я ненавижу distutils (я думаю он злой, кто это делает) заключается в том, что он меняет линию shebang. Другими словами, более рациональные и экологические варны приняли решение о писании

#!/usr/bin/env python

магически преобразуется в

#!/whatever/absolute/path/is/my/python

Это также видно с помощью grok: я использовал grokproject в virtualenv для запуска моего проекта, но теперь я больше не могу перемещать каталог разработки, потому что он устанавливает абсолютные пути в директиве shebang.

Причина, по которой я задаю это, двоякая.

  • Я хочу переместить его, потому что я начал развиваться в одном каталоге (Experiments), и теперь я хочу переместить его в правильный путь, но я не мог этого сделать. Поэтому я создал новый virtualenv и grokproject и скопировал мои файлы. Это устраняет проблему, но оставляет мое любопытство для более рационального решения неудовлетворенным. В частности, если ссылка на виртуальный интерпретатор python была относительной, проблема не была бы в первую очередь. Вы знаете макет виртуального, и вы можете легко обращаться к виртуальному python.
  • Вторая причина заключается в том, что я хотел бы иметь возможность scp virtualenv на другой компьютер и запускать его там без проблем. Это невозможно, если у вас есть жестко заданные пути.
4b9b3361

Ответ 1

Конечно, вы можете перемещать каталог разработки. Distutils изменяет пути к питону, с которым вы должны работать, когда запускаете его. Он запускается в Grok при запуске сборки. Переместите и перезапустите бутстрап и сборку. Готово!

Distutils изменяет путь к Python, который вы используете для запуска distutils. Если это не так, тогда вы можете установить библиотеку в одной версии python, но при попытке запустить script она завершится неудачно, потому что она будет работать с другой версией python, у которой не было библиотеки.

Это не безумие, это на самом деле единственный разумный способ сделать это.

Обновление: Если вы знаете, что делаете, вы можете сделать это:

/path/to/install/python setup.py build -e "/the/path/you/want/python" install

Сначала убедитесь, что вы очистите каталог сборки.:)

Ответ 2

Distutils автоматически заменит shebang на местоположение двоичного кода Python, который использовался для выполнения setup.py. Чтобы отменить это поведение, у вас есть два варианта:

Вариант 1: вручную

Вы можете передать флаг - executable =/path/to/my/python в setup.py. Аргументы принимаются.

Пример:

% python setup.py build --executable=/opt/local/bin/python -d

Вариант 2: автоматически

Другой вариант - добавить строку в setup.cfg. Если вы не используете setup.cfg, создайте его в том же каталоге, что и setup.py. Setup.py ищет это при запуске. Любые параметры, указанные здесь, все еще могут быть переопределены флагами в командной строке.

% cat setup.cfg 
[build]
executable = /opt/local/bin/python -d

Ответ 3

У меня нет решения вашей проблемы, но я вижу некоторое обоснование текущего поведения distutils.

#!/usr/bin/env python выполняет стандартную версию Python по умолчанию. Это нормально, если ваш код совместим с указанной версией. Когда версия по умолчанию обновляется (от 2.5 до 3, скажем), ваш код или другой код Python, ссылки на /usr/bin/env могут перестать работать, хотя старая версия Python все еще установлена. По этой причине имеет смысл "жестко кодировать" путь к соответствующему интерпретатору python.

Изменить: вы правы в утверждении, что указание python2.4 или аналогичное решение решает эту проблему.

Изменить 2: все не так ясно, когда присутствуют несколько установок одной и той же версии Python, поскольку Ned Deily указывает на комментарии ниже.

Ответ 4

В одной из последних версий distutils существует флаг - no-autoreq, который работал у меня:

--no-autoreq         do not automatically calculate dependencies

В моем случае я создавал RPM файлы с исполняемым файлом python2.4 на сервере с установками 2.4 и 2.6. bdist просто оставил shebangs, как они были, после запуска:

python setup.py bdist_rpm --no-autoreq

В случае, если вы обрабатываете файлы spec, вы можете использовать решение, описанное в fooobar.com/questions/242256/..., добавив:

AutoReq: no

Ответ 5

была та же проблема. попытался найти способ предотвратить трогание по умолчанию. вот решение. по существу мы переопределяем стандартную процедуру копирования script (build_scripts).

в setup.py add

from distutils.command.build_scripts import build_scripts

# don't touch my shebang
class BSCommand (build_scripts):
    def run(self):
        """
        Copy, chmod each script listed in 'self.scripts'
        essentially this is the stripped 
         distutils.command.build_scripts.copy_scripts()
        routine
        """
        from stat import ST_MODE
        from distutils.dep_util import newer
        from distutils import log

        self.mkpath(self.build_dir)
        outfiles = []
        for script in self.scripts:
            outfile = os.path.join(self.build_dir, os.path.basename(script))
            outfiles.append(outfile)

            if not self.force and not newer(script, outfile):
                log.debug("not copying %s (up-to-date)", script)
                continue

            log.info("copying and NOT adjusting %s -> %s", script,
                         self.build_dir)
            self.copy_file(script, outfile)

        if os.name == 'posix':
            for file in outfiles:
                if self.dry_run:
                    log.info("changing mode of %s", file)
                else:
                    oldmode = os.stat(file)[ST_MODE] & 0o7777
                    newmode = (oldmode | 0o555) & 0o7777
                    if newmode != oldmode:
                        log.info("changing mode of %s from %o to %o",
                                 file, oldmode, newmode)
                        os.chmod(file, newmode)

setup(name="name",
      version=version_string,
      description="desc",
      ...
      test_suite='testing',
      cmdclass={'build_scripts': BSCommand},
      )

.. ede/duply.net