Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
PKy?Z[]fg88 dist_fallbacknuW+Asetuptools python-pkg-resources AddOns python-peak.util AutoDockTools autodocktools Babel python-pybabel BitTornado bittornado BitTorrent bittorrent Bitten trac-bitten Bugs_Everywhere bugs-everywhere BytecodeAssembler python-peak.util BzrPipeline bzr-pipeline BzrTools bzrtools CedarBackup2 cedar-backup2 CherryPy python-cherrypy3 Codeville codeville Cython cython DITrack ditrack DebTorrent debtorrent DejaVu mgltools-dejavu Djapian python-django-djapian Djblets python-django-djblets Dosage dosage DouF00 douf00 Editra editra Eikazo eikazo Extremes python-peak.util Fabric fabric Fnorb fnorb GGZChess python-ggz GGZCore python-ggz GGZDMod python-ggz GGZMod python-ggz GNS3 gns3 Gallery_Uploader gallery-uploader GaussSum gausssum GeoIP_Python python-geoip HarvestMan harvestman HijriApplet python-hijra ISO8583_Module python-iso8583 Ibid ibid JCC jcc Loom bzr-loom Magic_file_extensions python-magic Mayavi mayavi2 Mirage mirage Mnemosyne mnemosyne Model_Builder model-builder MolKit mgltools-molkit MySQL_python python-mysqldb Nautilus_scripts_manager nautilus-scripts-manager NetworkEditor mgltools-networkeditor Nulog nulog PEAK_Rules python-peak.rules PIDA pida Photon photon Pmv mgltools-pmv Pootle pootle Postr postr PreludeEasy python-prelude PsychoPy psychopy PubTal pubtal Pwman3 pwman3 PyAIML python-aiml PyAutoDock mgltools-pyautodock PyBabel mgltools-pybabel PyBluez python-bluez PyChecker pychecker PyCoCuMa pycocuma PyMetrics pymetrics PyOpenAL python-openal PyOpenGL python-opengl PyProtocols python-protocols PyRoom pyroom PySFML python-sfml PyWebDAV python-webdav PyYAML python-yaml Pyjamas pyjamas-pyjs Pymacs pymacs Pympd pympd Pyste libboost-python1.42-dev PythonDaap python-daap QuantLib_Python quantlib-python Quixote python-quixote1 RSVGSDL python-ggz SSSDConfig python-sss ScientificPython python-scientific Skype4Py python-skype Sonata sonata South python-django-south SpreadModule python-spread Support mgltools-support SymbolType python-peak.util Symbolic python-swiginac The_FreeSmartphone_Framework_Daemon fso-frameworkd TileCache tilecache Trac trac TracAccountManager trac-accountmanager TracAuthOpenId trac-authopenid TracBzr trac-bzr TracCustomFieldAdmin trac-customfieldadmin TracDateField trac-datefieldplugin TracGit trac-git TracMasterTickets trac-mastertickets TracMercurial trac-mercurial TracSpamFilter trac-spamfilter TracWikiPrintPlugin trac-wikiprint TracWikiRename trac-wikirename TracWysiwyg trac-wysiwyg TracXMLRPC trac-xmlrpc Turtle_Art turtleart TwistedSNMP python-twisted-snmp UTpackages mgltools-utpackages UTpackages.UTblur mgltools-utpackages UTpackages.UTisocontour mgltools-utpackages UTpackages.UTmesh mgltools-utpackages UTpackages.UTmolderivatives mgltools-utpackages UTpackages.UTsdf mgltools-utpackages UTpackages.UTvolrend mgltools-utpackages ViewerFramework mgltools-viewerframework Vision mgltools-vision Volume mgltools-volume WikiTableMacro trac-wikitablemacro ZODB3 python-zodb adesklets adesklets adns_python python-adns agtl agtl apache_libcloud python-libcloud apt_offline apt-offline apt_p2p apt-p2p apt_xapian_index apt-xapian-index aptoncd aptoncd arandr arandr archivemail archivemail archmage archmage arcjobtool arcjobtool arista arista astk astk atheist atheist autokey autokey-common bhtree mgltools-bhtree bicyclerepair bicyclerepair bitbake bitbake bley bley bpython bpython buildbot buildbot burn burn bzr bzr bzr_builddeb bzr-builddeb bzr_cia cia-clients bzr_cvsps_import bzr-cvsps-import bzr_dbus bzr-dbus bzr_email bzr-email bzr_etckeeper etckeeper bzr_git bzr-git bzr_grep bzr-grep bzr_gtk bzr-gtk bzr_hg bzr-hg bzr_pqm bzr-pqm bzr_rewrite bzr-rebase bzr_search bzr-search bzr_stats bzr-stats bzr_svn bzr-svn bzr_upload bzr-upload bzr_xmloutput bzr-xmloutput cappuccino cappuccino cfget cfget cm config-manager cnetworkmanager cnetworkmanager cvs2svn cvs2svn cwm python-swap cx_bsdiff python-bsdiff d_feet d-feet dctrl2xml dctrl2xml debpartial_mirror debpartial-mirror deluge deluge-common dissy dissy djagios djagios django_ajax_selects django-ajax-selects django_openid_auth python-django-auth-openid dot2tex dot2tex dtrx dtrx duplicity duplicity dynagen dynagen eLyXer elyxer ears ears editmoin editmoin elisa python-moovida elisa_plugin_amazon moovida-plugins-bad elisa_plugin_amp moovida-plugins-bad elisa_plugin_avahi moovida-plugins-bad elisa_plugin_base moovida-plugins-good elisa_plugin_coherence moovida-plugins-bad elisa_plugin_daap moovida-plugins-bad elisa_plugin_database moovida-plugins-bad elisa_plugin_discogs moovida-plugins-bad elisa_plugin_dvd moovida-plugins-bad elisa_plugin_elisa_updater moovida-plugins-bad elisa_plugin_filtered_shares moovida-plugins-bad elisa_plugin_flickr moovida-plugins-ugly elisa_plugin_gnome moovida-plugins-good elisa_plugin_gstreamer moovida-plugins-bad elisa_plugin_hal moovida-plugins-good elisa_plugin_http_client moovida-plugins-bad elisa_plugin_ipod moovida-plugins-bad elisa_plugin_lastfm moovida-plugins-bad elisa_plugin_lirc moovida-plugins-ugly elisa_plugin_osso moovida-plugins-bad elisa_plugin_pigment moovida-plugins-bad elisa_plugin_poblesec moovida-plugins-bad elisa_plugin_rss moovida-plugins-bad elisa_plugin_search moovida-plugins-bad elisa_plugin_shoutcast moovida-plugins-ugly elisa_plugin_smbwin32 moovida-plugins-bad elisa_plugin_themoviedb moovida-plugins-bad elisa_plugin_thetvdb moovida-plugins-bad elisa_plugin_winremote moovida-plugins-bad elisa_plugin_winscreensaver moovida-plugins-good elisa_plugin_wmd moovida-plugins-bad elisa_plugin_youtube moovida-plugins-ugly epigrass epigrass euca2ools euca2ools explorer bzr-explorer fastimport bzr-fastimport flashbake flashbake flickrfs flickrfs fontypython fontypython funkload funkload fuse_python python-fuse fusil fusil fusion_icon fusion-icon fuss_launcher fuss-launcher galternatives galternatives gaphor gaphor gastablesgui gastables gdevilspie gdevilspie gdmodule python-gd geomutils mgltools-geomutils geximon geximon git_build_package git-buildpackage github_cli github-cli gitosis gitosis giws giws gjots2 gjots2 gle mgltools-gle gmobilemedia gmobilemedia gnome_activity_journal gnome-activity-journal gnome_app_install gnome-codec-install gnuplot_py python-gnuplot go2 go2 googlecl googlecl gozerbot gozerbot gpodder gpodder gpxviewer gpxviewer gracie gracie graphviz trac-graphviz groundcontrol groundcontrol gunicorn gunicorn gvb gvb gwibber gwibber gwrite gwrite gyp gyp hellanzb hellanzb hgsvn hgsvn hgview hgview hotwire hotwire ibus_tegaki ibus-tegaki icalview trac-icalviewplugin include_server distcc-pump indywiki indywiki iotop iotop ipython ipython jack jack keymapper keymapper lastfmsubmitd lastfmsubmitd lazygal lazygal libftdi python-ftdi libtpclient_py python-tp-client libtpproto_py python-tp-netlib live_magic live-magic llnl_babel python-sidl llnl_babel_sidl_sidlx python-sidl loggerhead loggerhead londonlaw londonlaw lottanzb lottanzb lptools lptools lshell lshell lucene pylucene ludev_t ludevit lybniz lybniz mecab_python python-mecab megahal megahal mercurial mercurial-common mglutil mgltools-mglutil mic mic2 mimms mimms mingc python-ming mini_dinstall mini-dinstall miro miro mod_python libapache2-mod-python moin python-moinmoin moosic moosic mpDris mpdris museek_python_bindings python-museek musiclibrarian musiclibrarian namebench namebench neso tryton-neso netsnmp_python libsnmp-python nfoview nfoview nglister nglister obMenu obmenu ocrfeeder ocrfeeder offlineimap offlineimap ooolib_python python-ooolib openbmap_logger openbmap-logger openerp_client openerp-client openerp_server openerp-server opengltk mgltools-opengltk openoffice_python python-openoffice openshot openshot osc osc ows ows pYsearch python-yahoo pdfposter pdfposter pdfshuffler pdfshuffler pep8 pep8 photo_uploader photo-uploader picard picard pkpgcounter pkpgcounter pondus pondus prelude_correlator prelude-correlator prelude_notify prelude-notify prewikka prewikka prioritized_methods python-peak.rules prover9_mace4 prover9-mace4 pssh pssh pyExcelerator python-excelerator pyPgSQL python-pgsql py_Asterisk python-asterisk py_pypcap python-pypcap py_rrdtool python-rrdtool py_sendfile python-sendfile pyalsaaudio python-alsaaudio pybackpack pybackpack pybridge pybridge pybtex pybtex pybugz bugz pychess pychess pychm python-chm pyclamav python-clamav pycrypto python-crypto pydicom python-dicom pydkim python-dkim pydns python-dns pyelemental python-elemental pyenchant python-enchant pyfacebook python-facebook pyflakes pyflakes pygdchart python-gdchart2 pyglf mgltools-pyglf pygopherd pygopherd pygpgme python-pyme pygpiv python-gpiv pyliblo python-liblo pyliblzma python-lzma pylibpcap python-libpcap pylibssh2 python-libssh2 pylint pylint pymilter python-milter pymol pymol pymucipher python-museek pymvpa python-mvpa pyneighborhood pyneighborhood pynids python-nids pynifti python-nifti pyofa python-musicdns pyogg python-ogg pyparallel python-parallel pyqonsole pyqonsole pyremctl python-remctl pyrit pyrit pyrite_publisher pyrite-publisher pysane python-imaging-sane pyscrabble pyscrabble-common pyserial python-serial pysnmp python-pysnmp2 pysparse python-sparse pyspi python-at-spi pysqlite python-pysqlite1.1 pystatgrab python-statgrab pysubnettree python-subnettree pytagsfs pytagsfs pytcpwrap python-tcpwrap python2_biggles python-pybiggles python_djvulibre python-djvu python_e_dbus python-edbus python_graph_core python-pygraph python_graph_dot python-pygraph python_libdrizzle python-drizzle python_libgearman python-gearman.libgearman python_libpisock python-pisock python_memcached python-memcache python_policyd_spf postfix-policyd-spf-python python_yapps yapps2 pytrainer pytrainer pytz python-tz pyweblib python-weblib pyxdg python-xdg pyzor pyzor qbzr qbzr qmtest qmtest quodlibet exfalso rabbitvcs rabbitvcs-core radiotray radiotray rawdog rawdog rdiff_backup rdiff-backup rebuildd rebuildd recaptcha_client python-recaptcha relational_gui relational relational_readline relational-cli remuco remuco-base renpy_module python-renpy repoze.what.plugins.sql python-repoze.what-plugins repoze.what.plugins.xml python-repoze.what-plugins repoze.what_pylons python-repoze.what-plugins repoze.what_quickstart python-repoze.what-plugins repoze.who.plugins.ldap python-repoze.who-plugins repoze.who.plugins.openid python-repoze.who-plugins repoze.who.plugins.sa python-repoze.who-plugins repoze.who_friendlyform python-repoze.who-plugins repoze.who_testutil python-repoze.who-plugins roundup roundup rst2pdf rst2pdf sapgui_package sapgui-package scanerrlog scanerrlog scenario mgltools-scenario scikits.learn python-scikits-learn screenlets screenlets series60_remote series60-remote sessioninstaller sessioninstaller sff mgltools-sff sixpack sixpack smart python-smartpm smart_notifier smart-notifier snimpy snimpy spambayes spambayes spectacle spectacle specto specto speechd_config python-speechd spyder spyder sqlalchemy_migrate python-migrate startupmanager startupmanager stgit stgit supervisor supervisor supybot supybot svnmailer svnmailer symserv mgltools-symserv synce_kpm synce-kpm synce_sync_engine synce-sync-engine tailor tailor tegaki_pygtk python-tegaki-gtk tegaki_python python-tegaki tegaki_tools python-tegakitools tegaki_train tegaki-train tepache tepache tgext.crud python-tgext.admin tortoisehg tortoisehg translate_toolkit translate-toolkit tritium tritium tryton tryton-client trytond tryton-server trytond_account tryton-modules-account trytond_account_be tryton-modules-account-be trytond_account_de_skr03 tryton-modules-account-de-skr03 trytond_account_invoice tryton-modules-account-invoice trytond_account_invoice_history tryton-modules-account-invoice-history trytond_account_invoice_line_standalone tryton-modules-account-invoice-line-standalone trytond_account_product tryton-modules-account-product trytond_account_statement tryton-modules-account-statement trytond_analytic_account tryton-modules-analytic-account trytond_analytic_invoice tryton-modules-analytic-invoice trytond_analytic_purchase tryton-modules-analytic-purchase trytond_analytic_sale tryton-modules-analytic-sale trytond_calendar tryton-modules-calendar trytond_calendar_classification tryton-modules-calendar-classification trytond_calendar_scheduling tryton-modules-calendar-scheduling trytond_calendar_todo tryton-modules-calendar-todo trytond_company tryton-modules-company trytond_company_work_time tryton-modules-company-work-time trytond_country tryton-modules-country trytond_currency tryton-modules-currency trytond_dashboard tryton-modules-dashboard trytond_google_maps tryton-modules-google-maps trytond_google_translate tryton-modules-google-translate trytond_ldap_authentication tryton-modules-ldap-authentication trytond_ldap_connection tryton-modules-ldap-connection trytond_party tryton-modules-party trytond_party_siret tryton-modules-party-siret trytond_party_vcarddav tryton-modules-party-vcarddav trytond_product tryton-modules-product trytond_product_cost_fifo tryton-modules-product-cost-fifo trytond_product_cost_history tryton-modules-product-cost-history trytond_product_price_list tryton-modules-product-price-list trytond_project tryton-modules-project trytond_project_plan tryton-modules-project-plan trytond_project_revenue tryton-modules-project-revenue trytond_purchase tryton-modules-purchase trytond_purchase_invoice_line_standalone tryton-modules-purchase-invoice-line-standalone trytond_sale tryton-modules-sale trytond_sale_price_list tryton-modules-sale-price-list trytond_stock tryton-modules-stock trytond_stock_forecast tryton-modules-stock-forecast trytond_stock_inventory_location tryton-modules-stock-inventory-location trytond_stock_location_sequence tryton-modules-stock-location-sequence trytond_stock_product_location tryton-modules-stock-product-location trytond_stock_supply tryton-modules-stock-supply trytond_stock_supply_day tryton-modules-stock-supply-day trytond_timesheet tryton-modules-timesheet ttb ttb tw.forms python-toscawidgets ubuntu_dev_tools ubuntu-dev-tools ufw ufw unattended_upgrades unattended-upgrades urlscan urlscan vboxapi virtualbox-ose vcs_load_dirs load-dirs-common virtaal virtaal virtinst virtinst virtualenvwrapper virtualenvwrapper wammu wammu web.py python-webpy wikipediafs wikipediafs winpdb winpdb wxPython_common python-wxgtk2.6 xgflib xgridfit xmldiff xmldiff xmms2tray xmms2tray xxdiff_scripts xxdiff-scripts yagtd yagtd yokadi yokadi yum_metadata_parser python-sqlitecachec zenmap zenmap zeroinstall_injector zeroinstall-injector zhone zhone-illume-glue zim zim zinnia_python python-zinnia PKy?Z[+  python.mknuW+A# some macros useful for packaging python packages # to include it unconditionally: # include /usr/share/python/python.mk # # to include it conditionally, and have the packaging working with earlier releases # and backports: # -include /usr/share/python/python.mk # ifeq (,$(py_sitename)) # py_sitename = site-packages # py_libdir = /usr/lib/python$(subst python,,$(1))/site-packages # py_sitename_sh = $(py_sitename) # py_libdir_sh = $(py_libdir) # endif # py_sitename: name of the site-packages/dist-packages directory depending # on the python version. Call as: $(call py_sitename, ). # Don't use this in shell snippets inside loops. py_sitename = $(if $(filter $(subst python,,$(1)), 2.3 2.4 2.5),site,dist)-packages # py_libdir: absolute path to the default python library for third party # stuff. Call as: $(call py_libdir, ). # Don't use this in shell snippets inside loops. py_libdir = /usr/lib/python$(strip $(if $(findstring 3.,$(subst python,,$(1))),3,$(subst python,,$(1))))/$(py_sitename) # py_pkgname: package name corresponding to the python version. # Call as: $(call py_pkgname, , ). py_pkgname = $(if $(findstring 3.,$(2)),$(subst python-,python3-,$(1)),$(1)) # The same macros for use inside loops in shell snippets py_sitename_sh = $$(basename $$(_py_=$(strip $(1)); python$${_py_\#python*} -c 'from distutils import sysconfig; print(sysconfig.get_python_lib())')) py_libdir_sh = $$(_py_=$(strip $(1)); python$${_py_\#python*} -c 'from distutils import sysconfig; print(sysconfig.get_python_lib())') # Arguments to pass to setup.py install py_setup_install_args = --install-layout=deb PKy?Z[?debpython/option.pycnuW+A Oc@sgddkZddkZddklZddklZdZdZdeifdYZdS(iN(tcopy(t parse_vrangecCs;yt|SWn&tj otid|nXdS(Nsversion range is invalid: %s(Rt ValueErrortoptparsetOptionValueError(toptiontopttvalue((s%/usr/share/python/debpython/option.pytparse_version_rangescCs0yti|}WntidnX|S(Nsregular expression is not valid(tretcompileRR(RRRtpattern((s%/usr/share/python/debpython/option.pytcompile_regexpr#s tOptioncBs>eZeiidZeeiiZeeds    PKy?Z[mdebpython/depends.pynuW+A# -*- coding: UTF-8 -*- # Copyright © 2010 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import logging from debpython.pydist import parse_pydep, guess_dependency from debpython.version import SUPPORTED, DEFAULT, debsorted, vrepr, vrange_str # minimum version required for pycompile/pyclean MINPYCDEP = 'python (>= 2.6.6-3+squeeze3~)' log = logging.getLogger(__name__) class Dependencies(object): """Store relations (dependencies, etc.) between packages.""" def __init__(self, package, use_breaks=False): self.package = package self.use_breaks = use_breaks self.depends = [] self.recommends = [] self.suggests = [] self.enhances = [] self.breaks = [] self.rtscripts = [] def export_to(self, dh): """Fill in debhelper's substvars.""" for i in self.depends: dh.addsubstvar(self.package, 'python:Depends', i) for i in self.recommends: dh.addsubstvar(self.package, 'python:Recommends', i) for i in self.suggests: dh.addsubstvar(self.package, 'python:Suggests', i) for i in self.enhances: dh.addsubstvar(self.package, 'python:Enhances', i) for i in self.breaks: dh.addsubstvar(self.package, 'python:Breaks', i) for i in self.rtscripts: dh.add_rtupdate(self.package, i) def __str__(self): return "D=%s; R=%s; S=%s; E=%s, B=%s; RT=%s" % (self.depends, \ self.recommends, self.suggests, self.enhances, \ self.breaks, self.rtscripts) def depend(self, value): if value and value not in self.depends: self.depends.append(value) def recommend(self, value): if value and value not in self.recommends: self.recommends.append(value) def suggest(self, value): if value and value not in self.suggests: self.suggests.append(value) def enhance(self, value): if value and value not in self.enhances: self.enhances.append(value) def break_(self, value): if value and value not in self.breaks: self.breaks.append(value) def rtscript(self, value): if value not in self.rtscripts: self.rtscripts.append(value) def parse(self, stats, options): log.debug('generating dependencies for package %s', self.package) pub_vers = sorted(stats['public_vers'].union(stats['public_ext'])) if pub_vers: dbgpkg = self.package.endswith('-dbg') tpl = 'python-dbg' if dbgpkg else 'python' supported = sorted(SUPPORTED) min_supp = supported[0] max_supp = supported[-1] minv = pub_vers[0] maxv = pub_vers[-1] if dbgpkg: tpl2 = 'python%d.%d-dbg' else: tpl2 = 'python%d.%d' self.depend(' | '.join(tpl2 % i for i in debsorted(pub_vers))) # additional Breaks/Depends to block python package transitions if self.use_breaks: if minv <= min_supp: self.break_("%s (<< %d.%d)" % \ (tpl, minv[0], minv[1])) if maxv >= max_supp: self.break_("%s (>= %d.%d)" % \ (tpl, maxv[0], maxv[1] + 1)) else: if minv <= DEFAULT: self.depend("%s (>= %d.%d)" % \ (tpl, minv[0], minv[1])) if maxv >= DEFAULT: self.depend("%s (<< %d.%d)" % \ (tpl, maxv[0], maxv[1] + 1)) # make sure pycompile binary is available if stats['compile']: self.depend(MINPYCDEP) for interpreter, version in stats['shebangs']: self.depend(interpreter) for private_dir, details in stats['private_dirs'].iteritems(): versions = list(v for i, v in details.get('shebangs', []) if v) if len(versions) > 1: log.error('more than one Python dependency from shebangs' '(%s shebang versions: %s)', private_dir, versions) exit(13) elif len(versions) == 1: # one hardcoded version self.depend("python%d.%d" % versions[0]) # TODO: if versions[0] not in requested_versions: FTBFS elif details.get('compile', False): # no hardcoded versions, but there's something to compile self.depend(MINPYCDEP) args = '' vr = options.vrange if vr: args += "-V %s" % vrange_str(vr) if vr[0]: # minimum version specified self.depend("python (>= %s)" % vrepr(vr[0])) if vr[1]: # maximum version specified self.depend("python (<< %s)" % vrepr(vr[1])) for pattern in options.regexpr or []: args += " -X '%s'" % pattern.replace("'", r"\'") self.rtscript((private_dir, args)) if options.guess_deps: for fn in stats['requires.txt']: # TODO: should options.recommends and options.suggests be # removed from requires.txt? for i in parse_pydep(fn): self.depend(i) # add dependencies from --depends for item in options.depends or []: self.depend(guess_dependency(item)) # add dependencies from --recommends for item in options.recommends or []: self.recommend(guess_dependency(item)) # add dependencies from --suggests for item in options.suggests or []: self.suggest(guess_dependency(item)) log.debug(self) PKy?Z[ debpython/debhelper.pynuW+A# -*- coding: UTF-8 -*- # Copyright © 2010 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import logging import re from os import makedirs, chmod from os.path import exists, join, dirname log = logging.getLogger(__name__) class DebHelper(object): """Reinvents the wheel / some dh functionality (Perl is ugly ;-P)""" def __init__(self, packages=None, no_packages=None): self.packages = {} self.python_version = None source_section = True binary_package = None try: fp = open('debian/control', 'r') except IOError: log.error('cannot find debian/control file') exit(15) for line in fp: if not line.strip(): source_section = False binary_package = None continue if binary_package: if binary_package.startswith('python3'): continue if packages and binary_package not in packages: continue if no_packages and binary_package in no_packages: continue if line.startswith('Architecture:'): arch = line[13:].strip() # TODO: if arch doesn't match current architecture: #del self.packages[binary_package] self.packages[binary_package]['arch'] = arch continue elif line.startswith('Breaks:') and '${python:Breaks}' in line: self.packages[binary_package]['uses_breaks'] = True continue elif line.startswith('Package:'): binary_package = line[8:].strip() if binary_package.startswith('python3'): log.debug('skipping Python 3.X package: %s', binary_package) continue if packages and binary_package not in packages: continue if no_packages and binary_package in no_packages: continue self.packages[binary_package] = {'substvars': {}, 'autoscripts': {}, 'rtupdates': [], 'uses_breaks': False} elif line.startswith('Source:'): self.source_name = line[7:].strip() elif source_section: if line.startswith('XS-Python-Version:') and not self.python_version: self.python_version = line[18:].strip() if line.startswith('X-Python-Version:'): self.python_version = line[17:].strip() log.debug('source=%s, binary packages=%s', self.source_name, \ self.packages.keys()) def addsubstvar(self, package, name, value): """debhelper's addsubstvar""" self.packages[package]['substvars'].setdefault(name, []).append(value) def autoscript(self, package, when, template, args): """debhelper's autoscript""" self.packages[package]['autoscripts'].setdefault(when, {})\ .setdefault(template, []).append(args) def add_rtupdate(self, package, value): self.packages[package]['rtupdates'].append(value) def save_autoscripts(self): for package, settings in self.packages.iteritems(): autoscripts = settings.get('autoscripts') if not autoscripts: continue for when, templates in autoscripts.iteritems(): fn = "debian/%s.%s.debhelper" % (package, when) if exists(fn): data = open(fn, 'r').read() else: data = '' new_data = '' for tpl_name, args in templates.iteritems(): for i in args: # try local one first (useful while testing dh_python2) fpath = join(dirname(__file__), '..', "autoscripts/%s" % tpl_name) if not exists(fpath): fpath = "/usr/share/debhelper/autoscripts/%s" % tpl_name tpl = open(fpath, 'r').read() tpl = tpl.replace('#PACKAGE#', package) tpl = tpl.replace('#ARGS#', i) if tpl not in data and tpl not in new_data: new_data += "\n%s" % tpl if new_data: data += "\n# Automatically added by dh_python2:" +\ "%s\n# End automatically added section\n" % new_data fp = open(fn, 'w') fp.write(data) fp.close() def save_substvars(self): for package, settings in self.packages.iteritems(): substvars = settings.get('substvars') if not substvars: continue fn = "debian/%s.substvars" % package if exists(fn): data = open(fn, 'r').read() else: data = '' for name, values in substvars.iteritems(): p = data.find("%s=" % name) if p > -1: # parse the line and remove it from data e = data[p:].find('\n') line = data[p + len("%s=" % name):\ p + e if e > -1 else None] items = [i.strip() for i in line.split(',') if i] if e > -1 and data[p + e:].strip(): data = "%s\n%s" % (data[:p], data[p + e:]) else: data = data[:p] else: items = [] for j in values: if j not in items: items.append(j) if items: if data: data += '\n' data += "%s=%s\n" % (name, ', '.join(items)) data = data.replace('\n\n', '\n') if data: fp = open(fn, 'w') fp.write(data) fp.close() def save_rtupdate(self): for package, settings in self.packages.iteritems(): values = settings.get('rtupdates') if not values: continue d = "debian/%s/usr/share/python/runtime.d" % package if not exists(d): makedirs(d) fn = "%s/%s.rtupdate" % (d, package) if exists(fn): data = open(fn, 'r').read() else: data = '#! /bin/sh -e' for dname, args in values: cmd = 'if [ "$1" = rtupdate ]; then' +\ "\n\tpyclean %s" % dname +\ "\n\tpycompile %s %s\nfi" % (args, dname) if cmd not in data: data += "\n%s" % cmd if data: fp = open(fn, 'w') fp.write(data) fp.close() chmod(fn, 0755) def save(self): self.save_substvars() self.save_autoscripts() self.save_rtupdate() PKy?Z[G,,debpython/pydist.pynuW+A# -*- coding: UTF-8 -*- # Copyright © 2010 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from __future__ import with_statement import logging import os import re from os.path import exists, isdir, join from subprocess import PIPE, Popen from debpython.version import vrepr, getver, get_requested_versions from debpython.tools import memoize log = logging.getLogger(__name__) PUBLIC_DIR_RE = re.compile(r'.*?/usr/lib/python(\d.\d+)/(site|dist)-packages') PYDIST_RE = re.compile(r""" (?P[A-Za-z][A-Za-z0-9_.]*) # Python distribution name \s* (?P(?:-?\d\.\d+(?:-(?:\d\.\d+)?)?)?) # version range \s* (?P(?:[a-z][^;]*)?) # Debian dependency (?: # optional upstream version -> Debian version translator ;\s* (?PPEP386)? # PEP-386 mode \s* (?Ps/.*)? # translator rules )? """, re.VERBOSE) REQUIRES_RE = re.compile(r''' (?P[A-Za-z][A-Za-z0-9_.]*) # Python distribution name \s* (?P(?:\[[^\]]*\])?) # ignored for now \s* (?: # optional minimum/maximum version (?P<=?|>=?|==|!=) \s* (?P(\w|[-.])+) )? ''', re.VERBOSE) def validate(fpath, exit_on_error=False): """Check if pydist file looks good.""" with open(fpath) as fp: for line in fp: line = line.strip('\r\n') if line.startswith('#') or not line: continue if not PYDIST_RE.match(line): log.error('invalid pydist data in file %s: %s', \ fpath.rsplit('/', 1)[-1], line) if exit_on_error: exit(3) return False return True @memoize def load(dname='/usr/share/python/dist/', fname='debian/pydist-overrides', fbname='/usr/share/python/dist_fallback'): """Load iformation about installed Python distributions.""" if exists(fname): to_check = [fname] # first one! else: to_check = [] if isdir(dname): to_check.extend(join(dname, i) for i in os.listdir(dname)) if exists(fbname): # fall back generated at python-defaults build time to_check.append(fbname) # last one! result = {} for fpath in to_check: with open(fpath) as fp: for line in fp: line = line.strip('\r\n') if line.startswith('#') or not line: continue dist = PYDIST_RE.search(line) if not dist: log.error('%s file has a broken line: %s', fpath, line) exit(9) dist = dist.groupdict() name = safe_name(dist['name']) dist['versions'] = get_requested_versions(dist['vrange']) dist['dependency'] = dist['dependency'].strip() if dist['rules']: dist['rules'] = dist['rules'].split(';') else: dist['rules'] = [] result.setdefault(name, []).append(dist) return result def guess_dependency(req, version=None): log.debug('trying to guess dependency for %s (python=%s)', req, vrepr(version) if version else None) if isinstance(version, basestring): version = getver(version) # some upstreams have weird ideas for distribution name... name, rest = re.compile('([^><= ]+)(.*)').match(req).groups() req = safe_name(name) + rest data = load() req_dict = REQUIRES_RE.match(req) if not req_dict: log.error('requirement is not valid: %s', req) log.info('please ask dh_python2 author to fix REQUIRES_RE ' 'or your upstream author to fix requires.txt') exit(8) req_dict = req_dict.groupdict() details = data.get(req_dict['name'].lower()) if details: for item in details: if version and version not in item.get('versions', version): # rule doesn't match version, try next one continue if not item['dependency']: return # this requirement should be ignored if item['dependency'].endswith(')'): # no need to translate versions if version is hardcoded in Debian # dependency return item['dependency'] if req_dict['version']: # FIXME: translate it (rules, versions) return item['dependency'] else: return item['dependency'] # try dpkg -S query = "'%s-?*\.egg-info'" % safe_name(name) # TODO: .dist-info if version: query = "%s | grep '/python%s/\|/pyshared/'" % \ (query, vrepr(version)) else: query = "%s | grep '/python2\../\|/pyshared/'" % query log.debug("invoking dpkg -S %s", query) process = Popen("/usr/bin/dpkg -S %s" % query, \ shell=True, stdout=PIPE) stdout, stderr = process.communicate() if process.returncode == 0: result = set() for line in stdout.split('\n'): if not line.strip(): continue result.add(line.split(':')[0]) if len(result) > 1: log.error('more than one package name found for %s dist', name) else: return result.pop() # fall back to python-distname pname = sensible_pname(name) log.warn('Cannot find package that provides %s. ' 'Using %s as package name. Please add "%s correct_package_name" ' 'line to debian/pydist-overrides to override it.', name, pname, name) return pname def parse_pydep(fname): public_dir = PUBLIC_DIR_RE.match(fname) if public_dir: ver = public_dir.group(1) else: ver = None result = [] with open(fname, 'r') as fp: for line in fp: line = line.strip() # ignore all optional sections if line.startswith('['): break if line: dependency = guess_dependency(line, ver) if dependency: result.append(dependency) return result def safe_name(name): """Emulate distribute's safe_name.""" return re.compile('[^A-Za-z0-9.]+').sub('_', name).lower() def sensible_pname(egg_name): """Guess Debian package name from Egg name.""" egg_name = safe_name(egg_name).replace('_', '-') if egg_name.startswith('python-'): egg_name = egg_name[7:] return "python-%s" % egg_name.lower() PKy?Z[Q<\!!debpython/version.pynuW+A# -*- coding: UTF-8 -*- # Copyright © 2010 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import re from os.path import exists from types import GeneratorType SUPPORTED = [(2, 5), (2, 6)] DEFAULT = (2, 6) RANGE_PATTERN = r'(-)?(\d\.\d+)(?:(-)(\d\.\d+)?)?' RANGE_RE = re.compile(RANGE_PATTERN) def get_requested_versions(vrange=None, available=None): """Return a set of requested and supported Python versions. :param available: if set to `True`, return installed versions only, if set to `False`, return requested versions that are not installed. By default returns all requested versions. :type available: bool >>> sorted(get_requested_versions([(2, 5), (3, 0)])) [(2, 5), (2, 6)] >>> sorted(get_requested_versions('')) == sorted(SUPPORTED) True >>> sorted(get_requested_versions([None, None])) == sorted(SUPPORTED) True >>> get_requested_versions([(5, 0), None]) set([]) """ if isinstance(vrange, basestring): vrange = parse_vrange(vrange) if not vrange or list(vrange) == [None, None]: versions = set(SUPPORTED) else: minv = (0, 0) if vrange[0] is None else vrange[0] maxv = (99, 99) if vrange[1] is None else vrange[1] if minv == maxv: versions = set((minv,) if minv in SUPPORTED else tuple()) else: versions = set(v for v in SUPPORTED if minv <= v < maxv) if available: versions = set(v for v in versions \ if exists("/usr/bin/python%d.%d" % v)) elif available is False: versions = set(v for v in versions \ if not exists("/usr/bin/python%d.%d" % v)) return versions def parse_vrange(value): """Return minimum and maximum Python version from given range. >>> parse_vrange('2.4-') ((2, 4), None) >>> parse_vrange('2.4-2.6') ((2, 4), (2, 6)) >>> parse_vrange('2.4-3.0') ((2, 4), (3, 0)) >>> parse_vrange('-2.7') (None, (2, 7)) >>> parse_vrange('2.5') ((2, 5), (2, 5)) >>> parse_vrange('') == parse_vrange('-') == (None, None) True """ if value in ('', '-'): return None, None match = RANGE_RE.match(value) if not match: raise ValueError("version range is invalid: %s" % value) groups = match.groups() if list(groups).count(None) == 3: # only one version is allowed minv = tuple(int(i) for i in groups[1].split('.')) return minv, minv minv = maxv = None if groups[0]: # maximum version only maxv = groups[1] else: minv = groups[1] maxv = groups[3] minv = tuple(int(i) for i in minv.split('.')) if minv else None maxv = tuple(int(i) for i in maxv.split('.')) if maxv else None if maxv and minv and minv > maxv: raise ValueError("version range is invalid: %s" % value) return minv, maxv def parse_pycentral_vrange(value): """Parse XS-Python-Version. >>> parse_pycentral_vrange('current') == (DEFAULT, DEFAULT) True >>> parse_pycentral_vrange('all') (None, None) >>> parse_pycentral_vrange('all, >= 2.4') ((2, 4), None) >>> parse_pycentral_vrange('all, << 3.0') (None, (3, 0)) >>> parse_pycentral_vrange('2.6') ((2, 6), (2, 6)) >>> parse_pycentral_vrange('2.5, 2.6') ((2, 5), None) """ get = lambda x: get_requested_versions(parse_vrange(x)) current = False minv = maxv = None hardcoded = set() for item in value.split(','): item = item.strip() if item == 'all': continue elif item == 'current': current = True continue match = re.match('>=\s*([\d\.]+)', item) if match: minv = "%.3s" % match.group(1) continue match = re.match('<<\s*([\d\.]+)', item) if match: maxv = "%.3s" % match.group(1) continue match = re.match('^[\d\.]+$', item) if match: hardcoded.add("%.3s" % match.group(0)) if len(hardcoded) == 1: ver = hardcoded.pop() return getver(ver), getver(ver) if not minv and hardcoded: # yeah, no maxv! minv = sorted(hardcoded)[0] if current: versions = sorted(get("%s-%s" % (minv if minv else '', \ maxv if maxv else ''))) if not versions: raise ValueError("version range doesn't match installed Python versions: %s" % value) # not really what "current" means... if DEFAULT in versions: return DEFAULT, DEFAULT else: return versions[0], versions[0] return getver(minv) if minv else None, \ getver(maxv) if maxv else None def vrange_str(vrange): """Return version range string from given range. >>> vrange_str(((2, 4), None)) '2.4-' >>> vrange_str(((2, 4), (2, 6))) '2.4-2.6' >>> vrange_str(((2, 4), (3, 0))) '2.4-3.0' >>> vrange_str((None, (2, 7))) '-2.7' >>> vrange_str(((2, 5), (2, 5))) '2.5' >>> vrange_str((None, None)) '-' """ if vrange[0] is vrange[1] is None: return '-' if vrange[0] == vrange[1]: return '.'.join(str(i) for i in vrange[0]) elif vrange[0] is None: return '-' + '.'.join(str(i) for i in vrange[1]) elif vrange[1] is None: return '.'.join(str(i) for i in vrange[0]) + '-' else: return "%s-%s" % ('.'.join(str(i) for i in vrange[0]), '.'.join(str(i) for i in vrange[1])) def vrepr(value): """ >>> vrepr(([2, 7], [3, 2])) ['2.7', '3.2'] >>> vrepr(('2.6', '3.1')) ['2.6', '3.1'] >>> vrepr('2.7') '2.7' >>> vrepr((2, 7)) '2.7' """ if isinstance(value, basestring): return value elif not isinstance(value, (GeneratorType, set))\ and isinstance(value[0], int): return '.'.join(str(i) for i in value) result = [] for version in value: if isinstance(version, basestring): result.append(version) else: result.append('.'.join(str(i) for i in version)) return result def getver(value): """Return pair of integers that represent version. >>> getver('2.5') (2, 5) >>> getver('2.6.4') (2, 6) >>> getver(None) '' """ if not value: return '' return tuple(int(i) for i in value.split('.', 2))[:2] def debsorted(versions, return_str=None): """Return sorted list of versions starting with default Python version (if available) then list of suppored versions greater than default one followed by reversed list of older versions. List of versions sorted this way can be used in Depends field. :param vrepr: return string represenatations of versions, by default the same format is used as in :param:`versions` >>> debsorted([(2, 6), (3, 1), (2, 5), (2, 4), (2, 7)])[0] == DEFAULT True >>> debsorted(('2.4', '3.2', '2.6', '2.7'))[-1] (2, 4) >>> debsorted(set([(2, 1), (2, 2)])) [(2, 2), (2, 1)] >>> debsorted([(2, 1), (2, 2)], return_str=True) ['2.2', '2.1'] """ result = [] old_versions = [] for version in sorted(versions): if isinstance(version, basestring): version = getver(version) if version < DEFAULT: old_versions.append(version) else: result.append(version) result.extend(reversed(old_versions)) if return_str and result: return vrepr(result) return result PKy?Z[debpython/__init__.pynuW+APKy?Z[6f&&debpython/version.pycnuW+A Oc@sddkZddklZddklZddgZdZdZeieZ dddZ d Z d Z d Zd Zd ZddZdS(iN(texists(t GeneratorTypeiiis(-)?(\d\.\d+)(?:(-)(\d\.\d+)?)?cs7t|tot|}n| pt|ddgjott}n|ddjodn|d|ddjod n|djo*ttjo fnt}n tfdtD}|otd|D}n(|tjotd|D}n|S( sFReturn a set of requested and supported Python versions. :param available: if set to `True`, return installed versions only, if set to `False`, return requested versions that are not installed. By default returns all requested versions. :type available: bool >>> sorted(get_requested_versions([(2, 5), (3, 0)])) [(2, 5), (2, 6)] >>> sorted(get_requested_versions('')) == sorted(SUPPORTED) True >>> sorted(get_requested_versions([None, None])) == sorted(SUPPORTED) True >>> get_requested_versions([(5, 0), None]) set([]) iiicc3s;x4|]-}|jo jno |VqqWdS(N((t.0tv(tmaxvtminv(s&/usr/share/python/debpython/version.pys <s css.x'|] }td|o |VqqWdS(s/usr/bin/python%d.%dN(R(RR((s&/usr/share/python/debpython/version.pys ?s css.x'|] }td|p |VqqWdS(s/usr/bin/python%d.%dN(R(RR((s&/usr/share/python/debpython/version.pys Bs N(ii(icic( t isinstancet basestringt parse_vrangetlisttNonetsett SUPPORTEDttupletFalse(tvranget availabletversions((RRs&/usr/share/python/debpython/version.pytget_requested_versions s!"" * cCs\|d jod Sti|}|ptd|n|i}t|id djo.td|didD}||fSd }}|do|d}n|d}|d}|o td |idDnd }|o td |idDnd }|o(|o!||jotd|n||fS(sReturn minimum and maximum Python version from given range. >>> parse_vrange('2.4-') ((2, 4), None) >>> parse_vrange('2.4-2.6') ((2, 4), (2, 6)) >>> parse_vrange('2.4-3.0') ((2, 4), (3, 0)) >>> parse_vrange('-2.7') (None, (2, 7)) >>> parse_vrange('2.5') ((2, 5), (2, 5)) >>> parse_vrange('') == parse_vrange('-') == (None, None) True tt-sversion range is invalid: %sicssx|]}t|VqWdS(N(tint(Rti((s&/usr/share/python/debpython/version.pys as it.icssx|]}t|VqWdS(N(R(RR((s&/usr/share/python/debpython/version.pys ks cssx|]}t|VqWdS(N(R(RR((s&/usr/share/python/debpython/version.pys ls (RRN(NN( R tRANGE_REtmatcht ValueErrortgroupsR tcountR tsplit(tvalueRRRR((s&/usr/share/python/debpython/version.pyRHs&  #     --c Cs&d}t}d}}t}x|idD]}|i}|djoq2n|djo t}q2ntid|}|od|id}q2ntid|}|od|id}q2ntid |}|o|i d|id q2q2Wt |djo#|i }t |t |fS| o|ot |d }n|ot |d |o|nd |o|nd f} | ptd |nt| jo ttfS| d | d fSn|o t |nd|o t |ndfS(sParse XS-Python-Version. >>> parse_pycentral_vrange('current') == (DEFAULT, DEFAULT) True >>> parse_pycentral_vrange('all') (None, None) >>> parse_pycentral_vrange('all, >= 2.4') ((2, 4), None) >>> parse_pycentral_vrange('all, << 3.0') (None, (3, 0)) >>> parse_pycentral_vrange('2.6') ((2, 6), (2, 6)) >>> parse_pycentral_vrange('2.5, 2.6') ((2, 5), None) cSstt|S((RR(tx((s&/usr/share/python/debpython/version.pytst,talltcurrents>=\s*([\d\.]+)s%.3sis<<\s*([\d\.]+)s ^[\d\.]+$is%s-%sRs9version range doesn't match installed Python versions: %sN(RR R RtstriptTruetreRtgrouptaddtlentpoptgetvertsortedRtDEFAULT( RtgetR#RRt hardcodedtitemRtverR((s&/usr/share/python/debpython/version.pytparse_pycentral_vrangetsL      "   cCs|d|djo d jnodS|d|djodid|dDS|dd jo ddid|dDS|dd jo did|dDdSddid |dDdid |dDfSd S( sMReturn version range string from given range. >>> vrange_str(((2, 4), None)) '2.4-' >>> vrange_str(((2, 4), (2, 6))) '2.4-2.6' >>> vrange_str(((2, 4), (3, 0))) '2.4-3.0' >>> vrange_str((None, (2, 7))) '-2.7' >>> vrange_str(((2, 5), (2, 5))) '2.5' >>> vrange_str((None, None)) '-' iiRRcssx|]}t|VqWdS(N(tstr(RR((s&/usr/share/python/debpython/version.pys s cssx|]}t|VqWdS(N(R3(RR((s&/usr/share/python/debpython/version.pys s cssx|]}t|VqWdS(N(R3(RR((s&/usr/share/python/debpython/version.pys s s%s-%scssx|]}t|VqWdS(N(R3(RR((s&/usr/share/python/debpython/version.pys s cssx|]}t|VqWdS(N(R3(RR((s&/usr/share/python/debpython/version.pys s N(R tjoin(R((s&/usr/share/python/debpython/version.pyt vrange_strs&  cCst|to|St|ttf o,t|dtodid|DSg}xO|D]G}t|to|i|qe|idid|DqeW|S(s >>> vrepr(([2, 7], [3, 2])) ['2.7', '3.2'] >>> vrepr(('2.6', '3.1')) ['2.6', '3.1'] >>> vrepr('2.7') '2.7' >>> vrepr((2, 7)) '2.7' iRcssx|]}t|VqWdS(N(R3(RR((s&/usr/share/python/debpython/version.pys s cssx|]}t|VqWdS(N(R3(RR((s&/usr/share/python/debpython/version.pys s (RRRR RR4tappend(Rtresulttversion((s&/usr/share/python/debpython/version.pytvreprs $cCs0|pdStd|iddDd S(sReturn pair of integers that represent version. >>> getver('2.5') (2, 5) >>> getver('2.6.4') (2, 6) >>> getver(None) '' Rcssx|]}t|VqWdS(N(R(RR((s&/usr/share/python/debpython/version.pys s Ri(R R(R((s&/usr/share/python/debpython/version.pyR+s cCsg}g}x_t|D]Q}t|tot|}n|tjo|i|q|i|qW|it||o|o t|S|S(sReturn sorted list of versions starting with default Python version (if available) then list of suppored versions greater than default one followed by reversed list of older versions. List of versions sorted this way can be used in Depends field. :param vrepr: return string represenatations of versions, by default the same format is used as in :param:`versions` >>> debsorted([(2, 6), (3, 1), (2, 5), (2, 4), (2, 7)])[0] == DEFAULT True >>> debsorted(('2.4', '3.2', '2.6', '2.7'))[-1] (2, 4) >>> debsorted(set([(2, 1), (2, 2)])) [(2, 2), (2, 1)] >>> debsorted([(2, 1), (2, 2)], return_str=True) ['2.2', '2.1'] ( R,RRR+R-R6textendtreversedR9(Rt return_strR7t old_versionsR8((s&/usr/share/python/debpython/version.pyt debsorteds   (ii(ii(ii(R&tos.pathRttypesRR R-t RANGE_PATTERNtcompileRR RRR2R5R9R+R>(((s&/usr/share/python/debpython/version.pyts  ( , A   PKy?Z[qdebpython/tools.pycnuW+A Oc @sddklZddkZddkZddklZddklZddkl Z ei e Z ei dZei dZdedZd Zd Zd Zd Zd efdYZdS(i(twith_statementN(tdumps(tsymlink(tgetvers/(.*?)(-py\d\.\d(?:-[^.]*)?)?(\.egg-info|\.pth)$s8^#!\s*/usr/bin/(?:env\s+)?(python(\d+\.\d+)?(?:-dbg)?).*cCst|to#td|idD}n|d jod|}n d|}|od|}n|od||f}n|S( sReturn path to site-packages directory. >>> sitedir((2, 5)) '/usr/lib/python2.5/site-packages/' >>> sitedir((2, 7), 'python-foo', True) 'debian/python-foo/usr/lib/debug/usr/lib/python2.7/dist-packages/' cssx|]}t|VqWdS(N(tint(t.0ti((s$/usr/share/python/debpython/tools.pys +s t.iis#/usr/lib/python%d.%d/dist-packages/s#/usr/lib/python%d.%d/site-packages/s/usr/lib/debug%ss debian/%s%s(ii(t isinstancet basestringttupletsplit(tversiontpackagetgdbtpath((s$/usr/share/python/debpython/tools.pytsitedir"s#  cCsk|id}|id}x(|d|djo|d=|d=q!Wdidgt|d|S(s~Return relative path. >>> relpath('/usr/share/python-foo/foo.py', '/usr/bin/foo', ) '../share/python-foo/foo.py' t/is..i(R tjointlen(ttargettlinktttl((s$/usr/share/python/debpython/tools.pytrelpath:s cCstt|||S(sCreate relative symlink.(RR(RR((s$/usr/share/python/debpython/tools.pytrelative_symlinkGsc Csyt|ii}z~|~}|id}ti|}|pdS|i}|djo.|do|dt|df}n|SWdQXWn#t j ot i d|nXdS(spCheck file's shebang. :rtype: tuple :returns: pair of Python interpreter string and Python version i iiNscannot open %s(NN( topent__exit__t __enter__treadt SHEBANG_REtmatchtNonetgroupsRtIOErrortlogterror(tfnamet_[1]tfptdataRtres((s$/usr/share/python/debpython/tools.pyt shebang2pyverLs#   cCsJti|}|o0|iddj odi|iddS|S(sRemove Python version and platform name from Egg files/dirs. >>> clean_egg_name('python_pipeline-0.1.3_py3k-py3.1.egg-info') 'python_pipeline-0.1.3_py3k.egg-info' >>> clean_egg_name('Foo-1.2-py2.7-linux-x86_64.egg-info') 'Foo-1.2.egg-info' itiiN(t EGGnPTH_RERtgroupR R(tnameR((s$/usr/share/python/debpython/tools.pytclean_egg_nameastmemoizecBseZdZdZRS(cCs||_h|_dS(N(tfunctcache(tselfR1((s$/usr/share/python/debpython/tools.pyt__init__ps cOsJt||f}||ijo|i|||i|s     PKy?Z[~~debpython/__init__.pycnuW+A Oc@sdS(N((((s'/usr/share/python/debpython/__init__.pytsPKy?Z[7ՙdebpython/debhelper.pycnuW+A Oc@ssddkZddkZddklZlZddklZlZlZei e Z de fdYZ dS(iN(tmakedirstchmod(texiststjointdirnamet DebHelpercBs\eZdZd d dZdZdZdZdZdZ dZ dZ RS( s>Reinvents the wheel / some dh functionality (Perl is ugly ;-P)c Csh|_d|_t}d}ytdd}Wn*tj otidtdnXx(|D] }|i pt }d}qen|o|i doqen|o||joqen|o||joqen|i do(|di }||i|d        cCs:x3|iiD]"\}}|id}|pqnd|}t|ot|di}nd}x}|iD]o\}}|id|}|djo||id} ||td|| djo || nd!} g} | i dD]} | o| | i qq~ } | djo5||| i o d || ||| f}q|| }ng} x,|D]$}|| jo| i |qqW| o6|o|d7}n|d |d i | f7}q|q|W|i d d}|o*t|d }|i||iqqWdS(NR sdebian/%s.substvarsRR.s%s=is t,s%s %ss%s=%s s, s R/(R R0R1RRR2tfindtlenRtsplitRR$RR4R5R6(RR%R7R R9R:R&tvaluestpteR!t_[1]R=titemstjR ((s(/usr/share/python/debpython/debhelper.pytsave_substvarssD     ;"  % c Cs2x+|iiD]\}}|id}|pqnd|}t|pt|nd||f}t|ot|di}nd}xO|D]G\}}dd|d||f} | |jo|d | 7}qqW|o7t|d } | i|| it |d qqWdS( NR s$debian/%s/usr/share/python/runtime.ds%s/%s.rtupdateRs #! /bin/sh -esif [ "$1" = rtupdate ]; thens pyclean %ss pycompile %s %s fis %sR/i( R R0R1RRRR2R5R6R( RR%R7REtdR9R:tdnameR+tcmdR ((s(/usr/share/python/debpython/debhelper.pyt save_rtupdates.         cCs"|i|i|idS(N(RKR@RO(R((s(/usr/share/python/debpython/debhelper.pytsaves  N( t__name__t __module__t__doc__RR"R(R,R-R@RKRORP(((s(/usr/share/python/debpython/debhelper.pyRs8    ! $ (tloggingtretosRRtos.pathRRRt getLoggerRQRtobjectR(((s(/usr/share/python/debpython/debhelper.pyts  PKy?Z[h[A-Za-z][A-Za-z0-9_.]*) # Python distribution name \s* (?P(?:-?\d\.\d+(?:-(?:\d\.\d+)?)?)?) # version range \s* (?P(?:[a-z][^;]*)?) # Debian dependency (?: # optional upstream version -> Debian version translator ;\s* (?PPEP386)? # PEP-386 mode \s* (?Ps/.*)? # translator rules )? s (?P[A-Za-z][A-Za-z0-9_.]*) # Python distribution name \s* (?P(?:\[[^\]]*\])?) # ignored for now \s* (?: # optional minimum/maximum version (?P<=?|>=?|==|!=) \s* (?P(\w|[-.])+) )? c Cst|ii}z|~}x|D]}|id}|idp| oq*nti|p=tid|i ddd||ot dnt Sq*WWdQXt S( s Check if pydist file looks good.s t#s"invalid pydist data in file %s: %st/iiiN( topent__exit__t __enter__tstript startswitht PYDIST_REtmatchtlogterrortrsplittexittFalsetTrue(tfpatht exit_on_errort_[1]tfptline((s%/usr/share/python/debpython/pydist.pytvalidate<s# s/usr/share/python/dist/sdebian/pydist-overridess/usr/share/python/dist_fallbackc st|o |g}ng}to*|ifdtiDnt|o|i|nh}x:|D]2}t|ii}z|~}x|D]}|i d}|i dp| oqnt i |} | p!t id||tdn| i} t| d} t| d| d<| d i | d <| d o| d id | d Us s R s%s file has a broken line: %si tnametvrangetversionst dependencytrulest;N(RRtextendtostlistdirtappendR R RRRRtsearchRRRt groupdictt safe_nameRtsplitt setdefault( R!tfnametfbnametto_checktresultRRRRtdistR"((R!s%/usr/share/python/debpython/pydist.pytloadLs:   * #   'c Cstid||o t|ndt|tot|}ntidi |i \}}t ||}t }t i |}|p+tid|tidtdn|i}|i|di}|ox|D]v}|o ||id|joqn|dpdS|did o |dS|d o |dS|dSqWnd t |}|od |t|f}n d |}tid|td|dtdt} | i\} } | idjot} xE| idD]4} | ipqn| i| iddqWt| djotid|q| iSnt |}ti!d||||S(Ns-trying to guess dependency for %s (python=%s)s([^><= ]+)(.*)srequirement is not valid: %ss[please ask dh_python2 author to fix REQUIRES_RE or your upstream author to fix requires.txtiR"R$R%t)tversions'%s-?*\.egg-info's"%s | grep '/python%s/\|/pyshared/'s$%s | grep '/python2\../\|/pyshared/'sinvoking dpkg -S %ss/usr/bin/dpkg -S %stshelltstdoutis t:is,more than one package name found for %s distsCannot find package that provides %s. Using %s as package name. Please add "%s correct_package_name" line to debian/pydist-overrides to override it.("RtdebugRtNonet isinstancet basestringRtretcompileRtgroupsR.R6t REQUIRES_RERtinfoRR-tgettlowertendswithRRRt communicatet returncodetsetR/Rtaddtlentpoptsensible_pnametwarn(treqR8R"tresttdatatreq_dicttdetailstitemtquerytprocessR:tstderrR4Rtpname((s%/usr/share/python/debpython/pydist.pytguess_dependencypsb $               cCsti|}|o|id}nd}g}t|dii}zq|~}xa|D]Y}|i}|idoPn|o+t ||}|o|i |qqbqbWWdQX|S(Nitrt[( t PUBLIC_DIR_RERtgroupR=R R RRRRZR+(R1t public_dirtverR4RRRR%((s%/usr/share/python/debpython/pydist.pyt parse_pydeps & cCstidid|iS(sEmulate distribute's safe_name.s[^A-Za-z0-9.]+t_(R@RAtsubRF(R"((s%/usr/share/python/debpython/pydist.pyR.scCsDt|idd}|ido|d}nd|iS(s(Guess Debian package name from Egg name.Rbt-spython-is python-%s(R.treplaceRRF(tegg_name((s%/usr/share/python/debpython/pydist.pyRNs("t __future__RtloggingR)R@tos.pathRRRt subprocessRRtdebpython.versionRRRtdebpython.toolsR t getLoggert__name__RRAR]tVERBOSERRCRRR6R=RZRaR.RN(((s%/usr/share/python/debpython/pydist.pyts*      " E  PKy?Z[Hdebpython/depends.pycnuW+A Oc@syddkZddklZlZddklZlZlZlZl Z dZ ei e Z defdYZdS(iN(t parse_pydeptguess_dependency(t SUPPORTEDtDEFAULTt debsortedtvreprt vrange_strspython (>= 2.6.6-3+squeeze3~)t DependenciescBskeZdZedZdZdZdZdZdZ dZ dZ d Z d Z RS( s6Store relations (dependencies, etc.) between packages.cCsL||_||_g|_g|_g|_g|_g|_g|_dS(N(tpackaget use_breakstdependst recommendstsuggeststenhancestbreakst rtscripts(tselfRR ((s&/usr/share/python/debpython/depends.pyt__init__#s       cCsx'|iD]}|i|id|q Wx'|iD]}|i|id|q4Wx'|iD]}|i|id|q^Wx'|iD]}|i|id|qWx'|iD]}|i|id|qWx$|iD]}|i|i|qWdS(sFill in debhelper's substvars.spython:Dependsspython:Recommendsspython:Suggestsspython:Enhancess python:BreaksN( R t addsubstvarRR R R RRt add_rtupdate(Rtdhti((s&/usr/share/python/debpython/depends.pyt export_to-s$      cCs,d|i|i|i|i|i|ifS(Ns#D=%s; R=%s; S=%s; E=%s, B=%s; RT=%s(R R R R RR(R((s&/usr/share/python/debpython/depends.pyt__str__<s cCs/|o$||ijo|ii|ndS(N(R tappend(Rtvalue((s&/usr/share/python/debpython/depends.pytdependAscCs/|o$||ijo|ii|ndS(N(R R(RR((s&/usr/share/python/debpython/depends.pyt recommendEscCs/|o$||ijo|ii|ndS(N(R R(RR((s&/usr/share/python/debpython/depends.pytsuggestIscCs/|o$||ijo|ii|ndS(N(R R(RR((s&/usr/share/python/debpython/depends.pytenhanceMscCs/|o$||ijo|ii|ndS(N(RR(RR((s&/usr/share/python/debpython/depends.pytbreak_QscCs(||ijo|ii|ndS(N(RR(RR((s&/usr/share/python/debpython/depends.pytrtscriptUscsqtid|it|di|d}|o|iid}|odnd}tt}|d}|d}|d} |d} |o d nd |id ifd t |D|i on| |jo&|i d || d| dfn| |jo*|i d|| d| ddfqq| t jo&|id|| d| dfn| t jo*|id || d| ddfqn|do|it nx%|dD]\} } |i| qWx|diD]|\} }td|idgD}t|djo!tid| |tdqt|djo|id |dq|idto|it d}|i}|ol|dt|7}|do|idt|dn|do|idt|dq?nx2|ipgD] }|d|idd7}qPW|i| |fqqW|io=x:|dD]*}x!t|D]}|i|qWqWnx+|ipgD]}|it|qWx+|ipgD]}|i t|qWx+|i!pgD]}|i"t|qCWti|dS(Ns&generating dependencies for package %st public_verst public_exts-dbgs python-dbgtpythoniispython%d.%d-dbgs python%d.%ds | c3sx|]}|VqWdS(N((t.0R(ttpl2(s&/usr/share/python/debpython/depends.pys is s %s (<< %d.%d)is %s (>= %d.%d)tcompiletshebangst private_dirscss*x#|]\}}|o |VqqWdS(N((R#Rtv((s&/usr/share/python/debpython/depends.pys s sFmore than one Python dependency from shebangs(%s shebang versions: %s)i ts-V %sspython (>= %s)spython (<< %s)s -X '%s't's\'s requires.txt(#tlogtdebugRtsortedtuniontendswithRRtjoinRR RRt MINPYCDEPt iteritemstlisttgettlenterrortexittFalsetvrangeRRtregexprtreplaceRt guess_depsRR RR RR R(Rtstatstoptionstpub_verstdbgpkgttplt supportedtmin_supptmax_supptminvtmaxvt interpretertversiont private_dirtdetailstversionstargstvrtpatterntfnRtitem((R$s&/usr/share/python/debpython/depends.pytparseYs      ,     %    %   "      #   (t__name__t __module__t__doc__R8RRRRRRRRRRQ(((s&/usr/share/python/debpython/depends.pyR s        (tloggingtdebpython.pydistRRtdebpython.versionRRRRRR1t getLoggerRRR+tobjectR(((s&/usr/share/python/debpython/depends.pyts (PKy?Z[PM44debpython/tools.pynuW+A# -*- coding: UTF-8 -*- # Copyright © 2010 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from __future__ import with_statement import logging import re from cPickle import dumps from os import symlink from debpython.version import getver log = logging.getLogger(__name__) EGGnPTH_RE = re.compile(r'(.*?)(-py\d\.\d(?:-[^.]*)?)?(\.egg-info|\.pth)$') SHEBANG_RE = re.compile(r'^#!\s*/usr/bin/(?:env\s+)?(python(\d+\.\d+)?(?:-dbg)?).*') def sitedir(version, package=None, gdb=False): """Return path to site-packages directory. >>> sitedir((2, 5)) '/usr/lib/python2.5/site-packages/' >>> sitedir((2, 7), 'python-foo', True) 'debian/python-foo/usr/lib/debug/usr/lib/python2.7/dist-packages/' """ if isinstance(version, basestring): version = tuple(int(i) for i in version.split('.')) if version >= (2, 6): path = "/usr/lib/python%d.%d/dist-packages/" % version else: path = "/usr/lib/python%d.%d/site-packages/" % version if gdb: path = "/usr/lib/debug%s" % path if package: path = "debian/%s%s" % (package, path) return path def relpath(target, link): """Return relative path. >>> relpath('/usr/share/python-foo/foo.py', '/usr/bin/foo', ) '../share/python-foo/foo.py' """ t = target.split('/') l = link.split('/') while l[0] == t[0]: del l[0], t[0] return '/'.join(['..'] * (len(l) - 1) + t) def relative_symlink(target, link): """Create relative symlink.""" return symlink(relpath(target, link), link) def shebang2pyver(fname): """Check file's shebang. :rtype: tuple :returns: pair of Python interpreter string and Python version """ try: with open(fname) as fp: data = fp.read(32) match = SHEBANG_RE.match(data) if not match: return None res = match.groups() if res != (None, None): if res[1]: res = res[0], getver(res[1]) return res except IOError: log.error('cannot open %s', fname) def clean_egg_name(name): """Remove Python version and platform name from Egg files/dirs. >>> clean_egg_name('python_pipeline-0.1.3_py3k-py3.1.egg-info') 'python_pipeline-0.1.3_py3k.egg-info' >>> clean_egg_name('Foo-1.2-py2.7-linux-x86_64.egg-info') 'Foo-1.2.egg-info' """ match = EGGnPTH_RE.match(name) if match and match.group(2) is not None: return ''.join(match.group(1, 3)) return name class memoize(object): def __init__(self, func): self.func = func self.cache = {} def __call__(self, *args, **kwargs): key = dumps((args, kwargs)) if key not in self.cache: self.cache[key] = self.func(*args, **kwargs) return self.cache[key] PKy?Z[=OOdebpython/option.pynuW+A# -*- coding: UTF-8 -*- # Copyright © 2010 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import re import optparse from copy import copy from debpython.version import parse_vrange def parse_version_range(option, opt, value): try: return parse_vrange(value) except ValueError: raise optparse.OptionValueError("version range is invalid: %s" % value) def compile_regexpr(option, opt, value): try: pattern = re.compile(value) except: raise optparse.OptionValueError('regular expression is not valid') return pattern class Option(optparse.Option): TYPES = optparse.Option.TYPES + ('version_range', 'regexpr') TYPE_CHECKER = copy(optparse.Option.TYPE_CHECKER) TYPE_CHECKER['version_range'] = parse_version_range TYPE_CHECKER['regexpr'] = compile_regexpr PKy?Z[&^1^1pyversions.pycnuW+A Oc @sXddkZddkZddkZy eZWn1ej o%ddkZeiZeiZnXda ddZ e dZ da e dZdae dZdae dZdae dZe dZe d Zd efd YZd efd YZdZdZe dZdZdZedjo endS(iNc Csddkl}l}tpktiidoT|}y|itdWn't j o}|GHt i dnX|aqnto>|o7yti d|}Wn|j o t nX|SdS(Ni(tSafeConfigParsert NoOptionErrors!/usr/share/python/debian_defaultsitDEFAULT(t ConfigParserRRt _defaultstostpathtexiststreadfptfiletIOErrortsystexittgett ValueErrortNone(tnameRRtconfigtmsgtvalue((s/usr/share/python/pyversions.pyt read_default s"  c Csrddk}h|id6|id6|id6|id6|id6}h}tg}ttdtt dt}t }xa|i dD]P}|i }|djod|d=s<=s<=|<=|<<|=)? *(\d\.\d)$s&error parsing Python-Version attributeiit.tvexact(scurrentR(NR(toperatorteqRtgetletlttsettsupported_versionstTruet old_versionstFalsetsplittstript setdefaulttretcompiletmatchRtgrouptaddt Exceptiontunion(tvstringt add_exactRt operatorstvinfotexact_versionst version_ranget relop_seentfieldtvetmtoptvtvmajtvmintfiltopt_[1]tav((s/usr/share/python/pyversions.pytparse_versions sZ          9   c Cstp`y@td}g}|idD]}||iq*~aWqgtj o gaqgXn|o$g}tD]}||dqy~StSdS(Ns old-versionsRi(t _old_versionsRR(R)R(RRRAtst_[2]R=((s/usr/share/python/pyversions.pyR&Vs 4$c Cstp`y@td}g}|idD]}||iq*~aWqgtj o gaqgXn|o$g}tD]}||dqy~StSdS(Nsunsupported-versionsRi(t_unsupported_versionsRR(R)R(RRRARERFR=((s/usr/share/python/pyversions.pytunsupported_versionsds 4$c Cstpy@td}g}|idD]}||iq*~aWqtj o6ddddg}y=ddk}|i|dd d td |i}|i }Wn+t j ot i d i |}nXd}xG|D]?} | id o)| idd d iid}qqW|i|o:g} |D]}| tidd|qA~ }|antpddgaqqXn|o$g} tD]} | | dq~ StSdS(Nssupported-versionsRs/usr/bin/apt-caches--no-all-versionstshows python-allitbufsizeitshelltstdoutt sDepends:t:s\s*(\S+)[ (]?.*s\1s python2.5s python2.6i(t_supported_versionsRR(R)Rt subprocesstPopenR'tPIPERLt ImportErrorRtpopentjoinRt startswithtcloseR+tsub( RRRAREtcmdRPtptfdtdependstlineRFt_[3]R=((s/usr/share/python/pyversions.pyR$rs8 4   - 0 $c CsitpJytida}Wntj odayLdddg}ddk}|i|dddtd|i}|i }Wn"t j oti d }nX|i i }|itid |od |aqnXytd }Wntj o d }nXt|tiid|fjotd|n|an|o tdStSdS(Ns/usr/bin/pythons-cs!import sys; print sys.version[:3]iRJiRKRLs6/usr/bin/python -c 'import sys; print sys.version[:3]'s\d\.\d$tpythonsdefault-versions python2.6s/usr/binsZ/usr/bin/python does not match the python default version. It must be reset to point to %si(t_default_versionRtreadlinktOSErrorRRPRQR'RRRLRSRTtreadlineR)RWR+R-RRRRU(RtlinkRYRPRZR[R]tdebian_default((s/usr/share/python/pyversions.pytdefault_versions6    "  cCs7d}t|dt}tdt}t|djold|jo |}qd|jotdtg}qd|jo|d}q|di|}nHd|jod|jo tdn!d|joVd|jo|di|}n t|}d|jo|i |dqnd|jo:tdt}||djo td n|g}nwd|jp d|joSt}d|jo|di|}nd|jo|i |dqn td |ptd n|o|Sg}|D]}|d |q~SdS( NR3RiRRRRs*both `current' and `all' in version strings+`current' version not in supported versionss$No Python versions in version strings+computed set of supported versions is emptyspython%s( RRCR%R$tlenRft intersectionRR#tupdate(R2RRR5t supportedRRAR=((s/usr/share/python/pyversions.pytrequested_versionssH                cCsddk}t}g}|idD]6}tii||jo|tii|q)q)~}|i|o$g}|D]}||dq~S|SdS(Nis/usr/bin/python[0-9].[0-9]i(tglobR$RRtbasenametsort(RRlRjRARERRFR=((s/usr/share/python/pyversions.pytinstalled_versionss  9 $tControlFileValueErrorcBseZRS((t__name__t __module__(((s/usr/share/python/pyversions.pyRpstMissingVersionValueErrorcBseZRS((RqRr(((s/usr/share/python/pyversions.pyRsscCsd}d}d}yt|d}Wn1tj o%}d||fGHtidnXx*|D]"}|i}|djo0|djoq`n|djoPnd}q`|ido d}q`|id|o |}q`|idp|id o:|djo td n|id d d i}q`|id o1||jo |id d d i}qq`q`W|djo t dn|djo|djo t dn|S|djot d|n|S(sread the debian/control file, extract the X-Python-Version or XS-Python-Version field; check that XB-Python-Version exists for the package.trsCannot open %s: %sittSourcesSource:s Package: sXS-Python-Version:sX-Python-Version:s3attribute X(S)-Python-Version not in Source sectionRNisXB-Python-Version:snot a control files+missing X(S)-Python-Version in control files)missing XB-Python-Version for package `%sN( RR R R R R)RVRR(RpRs(tfntpkgtversiontsversiontsectiontfpRR]((s/usr/share/python/pyversions.pytextract_pyversion_attributesP            (      cCsmg}|idD]}|t|q~}g}|idD]}|t|qD~}t||S(NR(R(tinttcmp(tver1tver2RAtitv1RFtv2((s/usr/share/python/pyversions.pyt version_cmps00c Cszg}tdt}x |idD]}|id}t|djo|dp|d|dsc Cs ddkl}d}|d|}|iddddd d d d |id dddd d d d|iddddd d d d|iddddd d d d|iddddd td d d d|i\}}tiiti d}|i o[t |djoHyt |i GHWq tj o#}d|G|GHtidq Xn|io.t |djod it|i GHnm|io.t |djod it|i GHn5|iot |djot |djo d!}n |d}ytii|oO|}y%t|d"} t| |i } Wqtj o.tiid#||ftidqtj otiitii|d$}tiid%||fy"t|} t| |i } Wqzt j o*tiid&|t|i } qzXqtj o0} tiid'|| ftid(qXnt||i } d i| GHWq tj o0}tiid'||ftidq Xn(tiid)||ftiddS(*Ni(t OptionParsersk[-v] [-h] [-d|--default] [-s|--supported] [-i|--installed] [-r|--requested |]tusages-ds --defaultthelps print the default python versiontactiont store_truetdesttdefaults-ss --supporteds#print the supported python versionsRjs-rs --requestedsprint the python versions requested by a build; the argument is either the name of a control file or the value of the X(S)-Python-Version attributet requesteds-is --installeds-print the installed supported python versionst installeds-vs --versions print just the version number(s)Ris%s:iRMsdebian/controlRvs%s: not a control file: %s, t pyversionssA%s: missing X(S)-Python-Version in control file, fall back to %s sD%s: missing debian/pyversions file, fall back to supported versions s%s: %s is usage: %s %s (!toptparseRt add_optionR't parse_argsRRRmR targvRRgRfRRR RjRUR$RRoRtisfileR}RkRptstderrtwriteRstdirnameRRR ( RRtparsertoptstargstprogramRRRwR2tvste((s/usr/share/python/pyversions.pytmainBs        !   t__main__( RR+R R#tSetTypet NameErrortsetstSetRRRR'RCRDR&RGRHROR$R`RfRkRoRRpRsR}RRRRRq(((s/usr/share/python/pyversions.pyts8$     5   ! *  /    G PKy?Z[ @BB!runtime.d/python-support.rtremovenuW+A#! /bin/sh set -e pyversion="$2" rm -rf /usr/lib/pymodules/"$2" PKy?Z[s2Dww"runtime.d/public_modules.rtinstallnuW+A#! /bin/sh set -e VERSION=${2#python} case "$VERSION" in 2.[45]) sitedir=/usr/lib/python$VERSION/site-packages;; *) sitedir=/usr/lib/python$VERSION/dist-packages esac if which python >/dev/null 2>&1 && which pycompile >/dev/null 2>&1; then pycompile -V $VERSION $sitedir else echo >&2 "python or pycompile not found in $(basename $0) hook." exit 1 fi PKy?Z[]]!runtime.d/python-support.rtupdatenuW+A#! /bin/sh set -e if [ "$1" = rtupdate ]; then exec /usr/sbin/update-python-modules -a fi PKy?Z[!<<!runtime.d/public_modules.rtremovenuW+A#! /bin/sh set -e VERSION=${2#python} case "$VERSION" in 2.[45]) sitedir=/usr/lib/python$VERSION/site-packages;; *) sitedir=/usr/lib/python$VERSION/dist-packages esac if which python >/dev/null 2>&1 && which pyclean >/dev/null 2>&1; then pyclean $sitedir else find $sitedir -name '*.py[co]' -delete fi PKy?Z[XK77"runtime.d/python-support.rtinstallnuW+A#! /bin/sh set -e exec /usr/sbin/update-python-modules PKy?Z[&AW66debian_defaultsnuW+A[DEFAULT] # the default python version default-version = python2.6 # all supported python versions supported-versions = python2.5, python2.6 # formerly supported python versions old-versions = python2.3, python2.4 # unsupported versions, including older versions unsupported-versions = python2.3, python2.4 PKy?Z[G 99 pyversions.pynuW+A#! /usr/bin/python import os, re, sys try: SetType = set except NameError: import sets SetType = sets.Set set = sets.Set _defaults = None def read_default(name=None): global _defaults from ConfigParser import SafeConfigParser, NoOptionError if not _defaults: if os.path.exists('/usr/share/python/debian_defaults'): config = SafeConfigParser() try: config.readfp(file('/usr/share/python/debian_defaults')) except IOError, msg: print msg sys.exit(1) _defaults = config if _defaults and name: try: value = _defaults.get('DEFAULT', name) except NoOptionError: raise ValueError return value return None def parse_versions(vstring, add_exact=False): import operator operators = { None: operator.eq, '=': operator.eq, '>=': operator.ge, '<=': operator.le, '<<': operator.lt } vinfo = {} exact_versions = set([]) version_range = set(supported_versions(version_only=True) + old_versions(version_only=True)) relop_seen = False for field in vstring.split(','): field = field.strip() if field == 'all': vinfo['all'] = 'all' continue if field in ('current', 'current_ext'): vinfo['current'] = field continue vinfo.setdefault('versions', set()) ve = re.compile('(>=|<=|<<|=)? *(\d\.\d)$') m = ve.match(field) try: if not m: raise ValueError('error parsing Python-Version attribute') op, v = m.group(1), m.group(2) vmaj, vmin = v.split('.') # Don't silently ignore Python 3 versions for Squeeze. #if int(vmaj) > 2: # continue if op in (None, '='): exact_versions.add(v) else: relop_seen = True filtop = operators[op] version_range = [av for av in version_range if filtop(av ,v)] except Exception: raise ValueError, 'error parsing Python-Version attribute' if add_exact: if exact_versions: vinfo['vexact'] = exact_versions if 'versions' in vinfo: if relop_seen: vinfo['versions'] = set(version_range) else: del vinfo['versions'] else: if 'versions' in vinfo: vinfo['versions'] = exact_versions if relop_seen: vinfo['versions'] = exact_versions.union(version_range) return vinfo _old_versions = None def old_versions(version_only=False): global _old_versions if not _old_versions: try: value = read_default('old-versions') _old_versions = [s.strip() for s in value.split(',')] except ValueError: _old_versions = [] if version_only: return [v[6:] for v in _old_versions] else: return _old_versions _unsupported_versions = None def unsupported_versions(version_only=False): global _unsupported_versions if not _unsupported_versions: try: value = read_default('unsupported-versions') _unsupported_versions = [s.strip() for s in value.split(',')] except ValueError: _unsupported_versions = [] if version_only: return [v[6:] for v in _unsupported_versions] else: return _unsupported_versions _supported_versions = None def supported_versions(version_only=False): global _supported_versions if not _supported_versions: try: value = read_default('supported-versions') _supported_versions = [s.strip() for s in value.split(',')] except ValueError: cmd = ['/usr/bin/apt-cache', '--no-all-versions', 'show', 'python-all'] try: import subprocess p = subprocess.Popen(cmd, bufsize=1, shell=False, stdout=subprocess.PIPE) fd = p.stdout except ImportError: fd = os.popen(' '.join(cmd)) depends = None for line in fd: if line.startswith('Depends:'): depends = line.split(':', 1)[1].strip().split(',') fd.close() if depends: depends = [re.sub(r'\s*(\S+)[ (]?.*', r'\1', s) for s in depends] _supported_versions = depends if not _supported_versions: # last resort: python-minimal not installed, apt-cache # not available, hard code the value, #394084 _supported_versions = ['python2.5', 'python2.6'] if version_only: return [v[6:] for v in _supported_versions] else: return _supported_versions _default_version = None def default_version(version_only=False): global _default_version if not _default_version: try: _default_version = link = os.readlink('/usr/bin/python') except OSError: _default_version = None try: cmd = ['/usr/bin/python', '-c', 'import sys; print sys.version[:3]'] import subprocess p = subprocess.Popen(cmd, bufsize=1, shell=False, stdout=subprocess.PIPE) fd = p.stdout except ImportError: fd = os.popen("/usr/bin/python -c 'import sys; print sys.version[:3]'") line = fd.readline().strip() fd.close() if re.match(r'\d\.\d$', line): _default_version = 'python' + line # consistency check try: debian_default = read_default('default-version') except ValueError: debian_default = "python2.6" if not _default_version in (debian_default, os.path.join('/usr/bin', debian_default)): raise ValueError, "/usr/bin/python does not match the python default version. It must be reset to point to %s" % debian_default _default_version = debian_default if version_only: return _default_version[6:] else: return _default_version def requested_versions(vstring, version_only=False): versions = None vinfo = parse_versions(vstring, add_exact=True) supported = supported_versions(version_only=True) if len(vinfo) == 1: if 'all' in vinfo: versions = supported elif 'current' in vinfo: versions = [default_version(version_only=True)] elif 'vexact' in vinfo: versions = vinfo['vexact'] else: versions = vinfo['versions'].intersection(supported) elif 'all' in vinfo and 'current' in vinfo: raise ValueError, "both `current' and `all' in version string" elif 'all' in vinfo: if 'versions' in vinfo: versions = vinfo['versions'].intersection(supported) else: versions = set(supported) if 'vexact' in vinfo: versions.update(vinfo['vexact']) elif 'current' in vinfo: current = default_version(version_only=True) if not current in vinfo['versions']: raise ValueError, "`current' version not in supported versions" versions = [current] elif 'versions' in vinfo or 'vexact' in vinfo: versions = set() if 'versions' in vinfo: versions = vinfo['versions'].intersection(supported) if 'vexact' in vinfo: versions.update(vinfo['vexact']) else: raise ValueError, 'No Python versions in version string' if not versions: raise ValueError('computed set of supported versions is empty') if version_only: return versions else: return ['python%s' % v for v in versions] def installed_versions(version_only=False): import glob supported = supported_versions() versions = [os.path.basename(s) for s in glob.glob('/usr/bin/python[0-9].[0-9]') if os.path.basename(s) in supported] versions.sort() if version_only: return [v[6:] for v in versions] else: return versions class ControlFileValueError(ValueError): pass class MissingVersionValueError(ValueError): pass def extract_pyversion_attribute(fn, pkg): """read the debian/control file, extract the X-Python-Version or XS-Python-Version field; check that XB-Python-Version exists for the package.""" version = None sversion = None section = None try: fp = file(fn, 'r') except IOError, msg: print "Cannot open %s: %s" % (fn, msg) sys.exit(2) for line in fp: line = line.strip() if line == '': if section == None: continue if pkg == 'Source': break section = None elif line.startswith('Source:'): section = 'Source' elif line.startswith('Package: ' + pkg): section = pkg elif line.startswith('XS-Python-Version:') or line.startswith('X-Python-Version:'): if section != 'Source': raise ValueError, \ 'attribute X(S)-Python-Version not in Source section' sversion = line.split(':', 1)[1].strip() elif line.startswith('XB-Python-Version:'): if section == pkg: version = line.split(':', 1)[1].strip() if section == None: raise ControlFileValueError, 'not a control file' if pkg == 'Source': if sversion == None: raise MissingVersionValueError, \ 'missing X(S)-Python-Version in control file' return sversion if version == None: raise MissingVersionValueError, \ 'missing XB-Python-Version for package `%s' % pkg return version # compatibility functions to parse debian/pyversions def version_cmp(ver1,ver2): v1=[int(i) for i in ver1.split('.')] v2=[int(i) for i in ver2.split('.')] return cmp(v1,v2) def requested_versions_bis(vstring, version_only=False): versions = [] py_supported_short = supported_versions(version_only=True) for item in vstring.split(','): v=item.split('-') if len(v)>1: if not v[0]: v[0] = py_supported_short[0] if not v[1]: v[1] = py_supported_short[-1] for ver in py_supported_short: try: if version_cmp(ver,v[0]) >= 0 \ and version_cmp(ver,v[1]) <= 0: versions.append(ver) except ValueError: pass else: if v[0] in py_supported_short: versions.append(v[0]) versions.sort(version_cmp) if not versions: raise ValueError, 'empty set of versions' if not version_only: versions=['python'+i for i in versions] return versions def extract_pyversion_attribute_bis(fn): vstring = file(fn).readline().rstrip('\n') return vstring def main(): from optparse import OptionParser usage = '[-v] [-h] [-d|--default] [-s|--supported] [-i|--installed] [-r|--requested |]' parser = OptionParser(usage=usage) parser.add_option('-d', '--default', help='print the default python version', action='store_true', dest='default') parser.add_option('-s', '--supported', help='print the supported python versions', action='store_true', dest='supported') parser.add_option('-r', '--requested', help='print the python versions requested by a build; the argument is either the name of a control file or the value of the X(S)-Python-Version attribute', action='store_true', dest='requested') parser.add_option('-i', '--installed', help='print the installed supported python versions', action='store_true', dest='installed') parser.add_option('-v', '--version', help='print just the version number(s)', default=False, action='store_true', dest='version_only') opts, args = parser.parse_args() program = os.path.basename(sys.argv[0]) if opts.default and len(args) == 0: try: print default_version(opts.version_only) except ValueError, msg: print "%s:" % program, msg sys.exit(1) elif opts.supported and len(args) == 0: print ' '.join(supported_versions(opts.version_only)) elif opts.installed and len(args) == 0: print ' '.join(installed_versions(opts.version_only)) elif opts.requested and len(args) <= 1: if len(args) == 0: versions = 'debian/control' else: versions = args[0] try: if os.path.isfile(versions): fn = versions try: vstring = extract_pyversion_attribute(fn, 'Source') vs = requested_versions(vstring, opts.version_only) except ControlFileValueError: sys.stderr.write("%s: not a control file: %s, " \ % (program, fn)) sys.exit(1) except MissingVersionValueError: fn = os.path.join(os.path.dirname(fn), 'pyversions') sys.stderr.write("%s: missing X(S)-Python-Version in control file, fall back to %s\n" \ % (program, fn)) try: vstring = extract_pyversion_attribute_bis(fn) vs = requested_versions_bis(vstring, opts.version_only) except IOError: sys.stderr.write("%s: missing debian/pyversions file, fall back to supported versions\n" \ % program) vs = supported_versions(opts.version_only) except ValueError, e: sys.stderr.write("%s: %s\n" % (program, e)) sys.exit(4) else: vs = requested_versions(versions, opts.version_only) print ' '.join(vs) except ValueError, msg: sys.stderr.write("%s: %s\n" % (program, msg)) sys.exit(1) else: sys.stderr.write("usage: %s %s\n" % (program, usage)) sys.exit(1) if __name__ == '__main__': main() PKy?Z[]fg88 dist_fallbacknuW+APKy?Z[+  8python.mknuW+APKy?Z[??debpython/option.pycnuW+APKy?Z[mDdebpython/depends.pynuW+APKy?Z[ 7`debpython/debhelper.pynuW+APKy?Z[G,,Qdebpython/pydist.pynuW+APKy?Z[Q<\!!debpython/version.pynuW+APKy?Z[debpython/__init__.pynuW+APKy?Z[6f&& debpython/version.pycnuW+APKy?Z[qhdebpython/tools.pycnuW+APKy?Z[~~debpython/__init__.pycnuW+APKy?Z[7ՙ^debpython/debhelper.pycnuW+APKy?Z[h