Я подготовил новую сборку rpm-build-python. 0.30-alt1 - python.req.py: + fixed a bug in "import" clause analysis, due to which only the first dependency of multiple arguments was produced; i.e. Old result: 'import os, re' -> Requires: python2.4(os) New result: 'import os, re' -> Requires: python2.4(os), python2.4(re) + made it fail on import errors (also python.prov.py) + made it print stderr diagnostics when the dependency is being ignored + disabled .py suffix check, for the sake of plain python scripts - added dependency on python-base, so that python.req.py and python.prov.py always work (also explained this change in policy/5-Python_FAQ.txt) - added buildreq skiplist and placed LC_ALL=C as needed in order to avoid dumb dependency on encoding modules when e.g. evaluating %%__python_version - added new files, for possible use with future rpm-build releases: + python.req (python.prov) - wrapper for python.req.py (resp. python.prov.py) + python.req.files (.prov.files) - will select python files for req/prov + /etc/rpm/macros.d/python.env - piece of rpm-build scriplets' preamble + also placed rpm-build python macros to /etc/rpm/macros.d/python $ git-diff origin.. |iconv -f utf8 diff --git a/.exrc b/.exrc new file mode 100644 index 0000000..1cf99a9 --- /dev/null +++ b/.exrc @@ -0,0 +1 @@ +set ts=8 sts=4 sw=4 et diff --git a/rpm-build-python.spec b/rpm-build-python.spec index ee5c39d..4c746d9 100644 --- a/rpm-build-python.spec +++ b/rpm-build-python.spec @@ -1,6 +1,6 @@ Name: rpm-build-python -Version: 0.29 -Release: alt5 +Version: 0.30 +Release: alt1 # redefine python_libdir for 0.29.alt2 is buggy %define python_libdir %_target_libdir/python%__python_version @@ -14,6 +14,7 @@ BuildArch: noarch Packager: Python Development Team Requires: rpm-build >= 0:4.0.4-alt39 +Requires: python-base >= 2.4.4-alt8 BuildRequires: python, rpm-build >= 0:4.0.4-alt39 AutoReqProv: yes, nopython @@ -37,9 +38,15 @@ subst 's/@PYTHON_VERSION@/%__python_version/g' python %install install -pD -m644 python %buildroot%_sysconfdir/rpm/macros.d/python -install -pD -m755 python.prov.py %buildroot%_target_libdir/rpm/python.prov.py -install -pD -m755 python.req.py %buildroot%_target_libdir/rpm/python.req.py -install -pD -m755 python.compileall.py %buildroot%_target_libdir/rpm/python.compileall.py +install -pD -m644 python.env %buildroot%_sysconfdir/rpm/macros.d/python.env +install -pD -m644 python.buildreq %buildroot%_sysconfdir/buildreqs/files/ignore.d/%name +install -pD -m755 python.prov %buildroot%_rpmlibdir/python.prov +install -pD -m755 python.prov.py %buildroot%_rpmlibdir/python.prov.py +install -pD -m755 python.prov.files %buildroot%_rpmlibdir/python.prov.files +install -pD -m755 python.req %buildroot%_rpmlibdir/python.req +install -pD -m755 python.req.py %buildroot%_rpmlibdir/python.req.py +install -pD -m755 python.req.files %buildroot%_rpmlibdir/python.req.files +install -pD -m755 python.compileall.py %buildroot%_rpmlibdir/python.compileall.py install -pd -m755 %buildroot%python_tooldir/rpm-build install -pD -m644 bdist_altrpm.py %buildroot%_libdir/python%__python_version/distutils/command/bdist_altrpm.py install -pD -m755 tools/*py %buildroot%python_tooldir/rpm-build @@ -55,9 +62,15 @@ unset RPM_PYTHON %files %_sysconfdir/rpm/macros.d/python -%_target_libdir/rpm/python.compileall.py -%_target_libdir/rpm/python.req.py -%_target_libdir/rpm/python.prov.py +%_sysconfdir/rpm/macros.d/python.env +%_sysconfdir/buildreqs/files/ignore.d/%name +%_rpmlibdir/python.compileall.py +%_rpmlibdir/python.req +%_rpmlibdir/python.req.py +%_rpmlibdir/python.req.files +%_rpmlibdir/python.prov +%_rpmlibdir/python.prov.py +%_rpmlibdir/python.prov.files %_libdir/python%__python_version/distutils/command/bdist_altrpm.py %doc python-module-SAMPLE.spec policy notes doc @@ -66,6 +79,25 @@ unset RPM_PYTHON %python_tooldir/rpm-build %changelog +* Wed Mar 21 2007 Alexey Tourbin 0.30-alt1 +- python.req.py: + + fixed a bug in "import" clause analysis, due to which only + the first dependency of multiple arguments was produced; i.e. + Old result: 'import os, re' -> Requires: python2.4(os) + New result: 'import os, re' -> Requires: python2.4(os), python2.4(re) + + made it fail on import errors (also python.prov.py) + + made it print stderr diagnostics when the dependency is being ignored + + disabled .py suffix check, for the sake of plain python scripts +- added dependency on python-base, so that python.req.py and python.prov.py + always work (also explained this change in policy/5-Python_FAQ.txt) +- added buildreq skiplist and placed LC_ALL=C as needed in order to avoid + dumb dependency on encoding modules when e.g. evaluating %%__python_version +- added new files, for possible use with future rpm-build releases: + + python.req (python.prov) - wrapper for python.req.py (resp. python.prov.py) + + python.req.files (.prov.files) - will select python files for req/prov + + /etc/rpm/macros.d/python.env - piece of rpm-build scriplets' preamble + + also placed rpm-build python macros to /etc/rpm/macros.d/python + * Sat Jan 13 2007 Fr. Br. George 0.29-alt5 - (avm@) Search for .pth files in lib64, too - Minor policy fix diff --git a/rpm-build-python/policy/5-Python_FAQ.txt b/rpm-build-python/policy/5-Python_FAQ.txt index 27afd3d..591b4f5 100644 --- a/rpm-build-python/policy/5-Python_FAQ.txt +++ b/rpm-build-python/policy/5-Python_FAQ.txt @@ -306,7 +306,12 @@ регулярного обновление перла для сборочной среды, который мне на хрен не нужен - я не нем не пишу так давно, что даже его забыл. - + + Замечание [Алексей Турбин, 2007-03-18]: вообще-то в базовой + сборочной среде присутствует только пакет perl-base, в развернутом + виде занимающий 3.5M. Кроме того, зависимость на perl-base + присутствует в пакете basesystem. + И, понимая то, что такие тендеции нарастают, я с ужасом думаю о сборочной среде содержащей все, от перла до tcl и от фортрана до ады. Я считаю правильным другой путь и им воспользовался. @@ -319,7 +324,23 @@ 2. В отсутствие каких-либо компонент python, необходимых для работы, скрипты из пакета rpm-build-python завершаются коррекно, но ничего не делают. - + + Замечание [Алексей Турбин, 2007-03-18]: второй подход чреват + неприятными последствиями. Поиск питоновских зависимостей + становится чувствительным к [ -x /usr/bin/python ] и наличию + необходимых модулей. Можно даже представить себе ситуацию, + когда вследствие этого отключается поиск provides, а это уже + чревато unmet'ами в репозитарии. В целом второй подход слишком + ненадежен, тогда как первый подход, действительно, требует внесения + лишних пакетов в базовую сборочную среду. Я предлагаю следующее + решение: нарастить python-base модулями, достаточными для работы + python.req.py и python.prov.py (на самом деле не хватает всего трех + файлов - parser.so, token.py и symbol.py); и добавить зависимость + на такой python-base в rpm-build-python. Наличие python-base + в базовой сборочной среде не должно никого сильно расстроить, + поскольку python-base в развернутом виде занимает чуть больше 2M. + Зато rpm-build-python будет работать надежно. + Собственно исправление ошибки свелось к обеспечению выполнения условия-2. Я это проверил, на паре пакетов - они действительно раньше падали при сборке, тогда как теперь не падают. diff --git a/rpm-build-python/python b/rpm-build-python/python index 81db52c..af9a622 100644 --- a/rpm-build-python/python +++ b/rpm-build-python/python @@ -2,8 +2,25 @@ # -*- coding: utf-8 -*- # Override __python_version macro provided by rpm-build -%__python_version %(%__python -c 'import sys; print "%%u.%%u" %% sys.version_info[0:2]' 2>/dev/null || echo @PYTHON_VERSION@) - +%__python_version %(LC_ALL=C %__python -c 'import sys; print "%%u.%%u" %% sys.version_info[0:2]' 2>/dev/null || echo @PYTHON_VERSION@) + +%_python_lib_path "" +%_python_req_method slight +%_python_req_skip "" +%_python_compile_method ALL +%_python_compile_exclude /usr/share/doc +%_python_compile_include /usr/%_lib +%_python_compile_deep 20 +%_python_compile_skip_x 1 +%_python_compile_clean 1 + +%set_python_req_method() %global _python_req_method %1 +%set_python_compile_method() %global _python_compile_method %1 + +%add_python_req_skip() %global _python_req_skip %_python_req_skip %* +%add_python_lib_path() %global _python_lib_path %_python_lib_path %* +%add_python_compile_exclude() %global _python_compile_exclude %_python_compile_exclude %* +%add_python_compile_include() %global _python_compile_include %_python_compile_include %* # _check_python_version_internal <версия_с_точкой> <версия_без_точки> # diff --git a/rpm-build-python/python.buildreq b/rpm-build-python/python.buildreq new file mode 100644 index 0000000..4e323a7 --- /dev/null +++ b/rpm-build-python/python.buildreq @@ -0,0 +1,3 @@ +^/usr/.*/python.*/encodings/__init__\.py +^/usr/.*/python.*/encodings/aliases\.py +^/usr/.*/python.*/encodings/ascii\.py diff --git a/rpm-build-python/python.env b/rpm-build-python/python.env new file mode 100644 index 0000000..a046544 --- /dev/null +++ b/rpm-build-python/python.env @@ -0,0 +1,12 @@ +%{?_python_lib_path:export RPM_PYTHON_LIB_PATH="%_python_lib_path"} +%{?_python_module_declared:export RPM_PYTHON_MODULE_DECLARED="%_python_module_declared"} +%{?_python_req_hier:export RPM_PYTHON_REQ_HIER="%_python_req_hier"} +%{?_python_req_method:export RPM_PYTHON_REQ_METHOD="%_python_req_method"} +%{?_python_req_skip:export RPM_PYTHON_REQ_SKIP="%_python_req_skip"} +%{?_python_compile_method:export RPM_PYTHON_COMPILE_METHOD="%_python_compile_method"} +%{?_python_compile_exclude:export RPM_PYTHON_COMPILE_EXCLUDE="%_python_compile_exclude"} +%{?_python_compile_include:export RPM_PYTHON_COMPILE_INCLUDE="%_python_compile_include"} +%{?_python_compile_deep:export RPM_PYTHON_COMPILE_DEEP="%_python_compile_deep"} +%{?_python_compile_skip_x:export RPM_PYTHON_COMPILE_SKIP_X="%_python_compile_skip_x"} +%{?_python_compile_clean:export RPM_PYTHON_COMPILE_CLEAN="%_python_compile_clean"} +%{?__python:export RPM_PYTHON="%__python"} diff --git a/rpm-build-python/python.prov b/rpm-build-python/python.prov new file mode 100755 index 0000000..309a1fd --- /dev/null +++ b/rpm-build-python/python.prov @@ -0,0 +1,2 @@ +#!/bin/sh +LC_ALL=C exec "${RPM_PYTHON:-python}" "$0".py ${1+"$@"} diff --git a/rpm-build-python/python.prov.files b/rpm-build-python/python.prov.files new file mode 100755 index 0000000..96db153 --- /dev/null +++ b/rpm-build-python/python.prov.files @@ -0,0 +1,11 @@ +#!/bin/sh -efu +while IFS=$'\t' read -r f t; do + case "$f" in + *.py|*.pyo|*.pyc|*.pth) + echo "$f" + continue ;; + ${RPM_BUILD_ROOT-}*/python*/*.so) + echo "$f" + continue ;; + esac +done diff --git a/rpm-build-python/python.prov.py b/rpm-build-python/python.prov.py index 049506b..23dd79e 100755 --- a/rpm-build-python/python.prov.py +++ b/rpm-build-python/python.prov.py @@ -52,7 +52,7 @@ def paths_from_pthfiles(prefix, buildroot, filenames): try : import sys, os except : - pass + raise else : prefix = "python%u.%u" % sys.version_info[0:2] diff --git a/rpm-build-python/python.req b/rpm-build-python/python.req new file mode 100755 index 0000000..309a1fd --- /dev/null +++ b/rpm-build-python/python.req @@ -0,0 +1,2 @@ +#!/bin/sh +LC_ALL=C exec "${RPM_PYTHON:-python}" "$0".py ${1+"$@"} diff --git a/rpm-build-python/python.req.files b/rpm-build-python/python.req.files new file mode 100755 index 0000000..bbbb4a6 --- /dev/null +++ b/rpm-build-python/python.req.files @@ -0,0 +1,15 @@ +#!/bin/sh -efu +while IFS=$'\t' read -r f t; do + case "$t" in + *"python script text"*) + echo "$f" + continue ;; + *"symbolic link to "*) + continue ;; + esac + case "$f" in + *.py) + echo "$f" + continue ;; + esac +done diff --git a/rpm-build-python/python.req.py b/rpm-build-python/python.req.py index c0ace61..43682d0 100755 --- a/rpm-build-python/python.req.py +++ b/rpm-build-python/python.req.py @@ -36,7 +36,7 @@ try : import sys, os import parser, symbol, token, types except : - pass + raise else : def _(s) : return s prefix = "python%u.%u" % sys.version_info[0:2] @@ -50,38 +50,51 @@ else : if sys.version_info[0:2] < (2,4) : def pro(x) : return x + def namelist(import_node) : + return [x for x in import_node[2:] if x[0] != 12 ] else : def pro(x) : return x[1] - + def namelist(import_node) : + return [x for x in import_node[2][1:] if x[0] != 12 ] + ignore = dict([ (x,1) for x in list(os.getenv('RPM_PYTHON_REQ_SKIP',"").split()) + list(sys.builtin_module_names)]).has_key REQ=os.getenv('RPM_PYTHON_REQ_METHOD','relaxed') IS_HIER = os.getenv('RPM_PYTHON_REQ_HIER',None) + src = None def match(tree,deep=0) : if tree[0] not in symbol_skip : deep += 1 for node in tree : if type(node) in [types.ListType, types.TupleType] : if node[0] == symbol.import_stmt : - if REQ not in ['slight','relaxed'] or deep == 4 : - node = pro(node) - if node[1][1] == 'import' : - for name in [x for x in node[2:] if x[0] != 12 ] : - name = pro(name) - - if IS_HIER is None : - yield name[1][1][1] - else : - yield ".".join( [ i for t,i in name[1][1:] if t==1 ]) - elif node[1][1] == 'from' : + line = 0 + deps = [] + node = pro(node) + if node[1][1] == 'import' : + line = node[1][2] + for name in namelist(node) : if IS_HIER is None : - yield node[2][1][1] + deps.append(name[1][1][1]) else : - yield ".".join( [ i for t,i in node[2][1:] if t==1 ]) - + deps.append(".".join( [ i for t,i in name[1][1:] if t==1 ])) + elif node[1][1] == 'from' : + line = node[1][2] + if IS_HIER is None : + deps.append(node[2][1][1]) + else : + deps.append(".".join( [ i for t,i in node[2][1:] if t==1 ])) + + if REQ not in ['slight','relaxed'] or deep == 4 : + for dep in deps : + yield dep + else : + for dep in deps: + print >> sys.stderr, "%s: %s: line=%d IGNORE module=%s" % (sys.argv[0], src, line, dep) + for item in match(node,deep) : yield item @@ -115,9 +128,9 @@ else : # print "\t",req for src in files : - if '.py' == os.path.splitext(os.path.basename(src))[1] : + #if '.py' == os.path.splitext(os.path.basename(src))[1] : try : - lis = parser.suite(open(src).read().replace("\r\n","\n")).tolist() + lis = parser.suite(open(src).read().replace("\r\n","\n")).tolist(line_info=1) except SyntaxError,msg : continue except :