Updated to 3.3.3, added bdist_rpm5

This commit is contained in:
Denis Silakov 2014-01-16 06:40:02 -05:00
parent 13cebd07e8
commit 24bcc4a2db
5 changed files with 487 additions and 22 deletions

View file

@ -1,8 +1,10 @@
removed_sources:
Python-3.3.0.tar.xz: 833d73565e1b665f1878504081dc985a5a06e46a
python-3.3.0-docs-html.tar.bz2: 5299b1523ede931767199a5b13388a5bf35351d5
Python-3.3.1.tar.xz: 393d7302c48bc911cd7faa7fa9b5fbcb9919bddc
Python-3.3.2.tar.xz: 87009d0c156c6e1354dfec5c98c328cae93950ad
python-3.3.0-docs-html.tar.bz2: 5299b1523ede931767199a5b13388a5bf35351d5
python-3.3.1-docs-html.tar.bz2: 55c3b3f3453346835b0df2b3b0ad7fe20833a7f7
sources:
"Python-3.3.2.tar.xz": 87009d0c156c6e1354dfec5c98c328cae93950ad
"python-3.3.2-docs-html.tar.bz2": 514e1a0810fa9e6433f4bc64bdc0ad407d49ebc5
Python-3.3.3.tar.xz: af4e75a34bd538c79b9871227c2e7f56569ac107
python-3.3.2-docs-html.tar.bz2: 514e1a0810fa9e6433f4bc64bdc0ad407d49ebc5
python-3.3.3-docs-html.tar.bz2: bcd1f17d3d32f59288eda50aa6432135394b5ab5

235
bdist_rpm5.py Normal file
View file

@ -0,0 +1,235 @@
from distutils.command.bdist_rpm import bdist_rpm
import distutils.command.sdist
from distutils.sysconfig import get_config_var
from distutils.filelist import FileList
import string, os, sys
from types import *
from glob import glob
# import rpm
class bdist_rpm5(bdist_rpm):
def _make_spec_file(self):
"""Generate the text of an RPM spec file and return it as a
list of strings (one per line).
"""
sdist = self.reinitialize_command('sdist')
sdist.finalize_options()
sdist.filelist = FileList()
sdist.get_file_list()
manifest = sdist.filelist.files
# definitions and headers
name = self.distribution.get_name()
version = self.distribution.get_version().replace('-','_')
release = self.release.replace('-','_')
summary = self.distribution.get_description().strip().strip('.')
spec_file = [
'%define\toname\t'+name,
]
if name[:2] == "py":
spec_file.append('%define\tmodule\t' + name[2:])
module = '%{module}'
else:
module = '%{oname}'
spec_file.extend([
'',
'Name:\t\tpython3-' + module,
'Version:\t' + version,
'Release:\t' + release,
'Summary:\t' + summary,
'Source0:\thttp://pypi.python.org/packages/source/%c/%%{oname}/%%{oname}-%%{version}.tar' % name[0],
])
# XXX yuck! this filename is available from the "sdist" command,
# but only after it has run: and we create the spec file before
# running "sdist", in case of --spec-only.
if sdist.formats and 'xztar' in sdist.formats:
spec_file[-1] += '.xz'
elif sdist.formats and 'bztar' in sdist.formats:
spec_file[-1] += '.bz2'
else:
spec_file[-1] += '.gz'
license = self.distribution.get_license()
if license == "UNKNOWN":
classifiers = self.distribution.get_classifiers()
for classifier in classifiers:
values = classifier.split(" :: ")
if values[0] == "License":
license = values[-1]
license.replace("GPL ", "GPLv").strip()
# Hardcoded value from bdist_rpm not suitable for ROSA
if self.group == "Development/Libraries":
self.group == "Development/Python"
spec_file.extend([
'License:\t' + license,
'Group:\t\t' + self.group,])
if self.distribution.get_url() != 'UNKNOWN':
spec_file.append('Url:\t\t' + self.distribution.get_url())
doc_names = ['README', 'CHANGES','ChangeLog', 'NEWS', 'THANKS',
'HISTORY', 'AUTHORS', 'BUGS', 'ReleaseNotes', 'DISCLAIMER',
'TODO', 'TROUBLESHOOTING', 'IDEAS', 'HACKING', 'WISHLIST',
'CREDITS', 'PROJECTS', 'LEGAL', 'KNOWN_BUGS',
'MISSING_FEATURES', 'FAQ', 'ANNOUNCE', 'FEATURES', 'WHATSNEW']
license_names = ['LICENSE', 'COPYRIGHT', 'COPYING']
common_licenses = glob('/usr/share/common-licenses/*')
for i in range(len(common_licenses)):
common_licenses[i] = os.path.basename(common_licenses[i])
doc_names.extend(license_names)
doc_suffixes = ('.doc', '.htm', '.txt', '.pdf', '.odt')
self.doc_files = []
all_files = []
if self.distribution.data_files:
all_files.extend(self.distribution.data_files)
if manifest:
all_files.extend(manifest)
if all_files:
for data_file in all_files:
done = False
for doc_name in doc_names:
if doc_name.lower() in data_file[1][0].lower():
if doc_name in license_names and license in common_licenses:
done = True
break
self.doc_files.append(data_file)
done = True
break
if done:
continue
for doc_suffix in doc_suffixes:
ext = os.path.splitext(data_file.lower())[1]
if ext.lower().startswith(doc_suffix.lower()):
self.doc_files.append(data_file)
break
if not self.force_arch:
# noarch if no extension modules
if not self.distribution.has_ext_modules():
spec_file.append('BuildArch:\tnoarch')
else:
spec_file.append( 'BuildArch:\t%s' % self.force_arch )
for field in ('Provides',
'Requires',
'Conflicts',
'Obsoletes',
):
val = getattr(self, field.lower())
if type(val) == list:
spec_file.append('%s: %s' % (field, string.join(val)))
elif val is not None:
spec_file.append('%s: %s' % (field, val))
build_requires = []
if self.distribution.has_ext_modules():
build_requires.append('python3-devel')
# Ugly, but should mostly work... :p
if 'setuptools' in str(self.distribution.__dict__) or 'setuptools' in str(sdist.__dict__):
build_requires.append('python3egg(distribute)')
if build_requires:
spec_file.append('BuildRequires:\t' +
" ".join(build_requires))
if self.build_requires:
spec_file.append('BuildRequires:\t' +
" ".join(self.build_requires))
spec_file.extend([
'',
'%description',
self.distribution.get_long_description().strip()
])
# insert contents of files
# XXX this is kind of misleading: user-supplied options are files
# that we open and interpolate into the spec file, but the defaults
# are just text that we drop in as-is. Hmmm.
if 'test_suite' in self.distribution.__dict__ and self.distribution.test_suite:
verify_script = "python3 setup.py test"
else:
verify_script = None
script_options = [
('prep', 'prep_script', "%setup -qn %{oname}-%{version}"),
('build', 'build_script', "python3 setup.py build"),
('install', 'install_script',
("python3 setup.py install "
"--root=%{buildroot}")),
('check', 'verify_script', verify_script),
('pre', 'pre_install', None),
('post', 'post_install', None),
('preun', 'pre_uninstall', None),
('postun', 'post_uninstall', None),
]
for (rpm_opt, attr, default) in script_options:
# Insert contents of file referred to, if no file is referred to
# use 'default' as contents of script
val = getattr(self, attr)
if val or default:
spec_file.extend([
'',
'%' + rpm_opt,])
if val:
spec_file.extend(string.split(open(val, 'r').read(), '\n'))
else:
spec_file.append(default)
# files section
spec_file.extend([
'',
'%files',
])
for doc_file in self.doc_files:
spec_file.append('%doc ' + doc_file)
if self.distribution.has_ext_modules():
site_pkgs = '%{py3_platsitedir}'
else:
site_pkgs = '%{py3_puresitedir}'
if self.distribution.has_scripts():
for script in self.distribution.scripts:
if type(script) == StringType:
spec_file.append(os.path.join('%{_bindir}', os.path.basename(script)))
site_pkgs_files = []
if self.distribution.data_files:
for data_file in self.distribution.data_files:
site_pkgs_files.append(os.path.join(site_pkgs, data_file))
if 'entry_points' in self.distribution.__dict__ and self.distribution.entry_points:
if type(self.distribution.entry_points) is DictType:
for entry_points in self.distribution.entry_points:
for entry_point in self.distribution.entry_points[entry_points]:
site_pkgs_files.append(os.path.join('%{_bindir}', os.path.basename(entry_point.split('=')[0])))
if 'py_modules' in self.distribution.__dict__ and self.distribution.py_modules:
for py_module in self.distribution.py_modules:
py_module = py_module.replace('.', os.path.sep)
site_pkgs_files.append(os.path.join(site_pkgs, py_module + '.py*'))
if 'packages' in self.distribution.__dict__ and self.distribution.packages:
for package in self.distribution.packages:
package = package.replace('.', os.path.sep)
#spec_file.append('%dir ' + os.path.join(site_pkgs, package))
site_pkgs_files.append(os.path.join(site_pkgs, package, '*.py*'))
if self.distribution.has_ext_modules():
for ext_module in self.distribution.ext_modules:
ext_module = ext_module.name.replace('.', os.path.sep)
site_pkgs_files.append(os.path.join(site_pkgs, ext_module + ".so"))
site_pkgs_files.sort()
for f in site_pkgs_files:
spec_file.append(f)
spec_file.append(os.path.join(site_pkgs, name.replace('-', '_') + '*.egg-info'))
return spec_file
# _make_spec_file ()

View file

@ -1,13 +0,0 @@
--- Python-3.3.0/Lib/test/test_urllibnet.py.bero 2013-01-17 16:14:46.177742527 +0100
+++ Python-3.3.0/Lib/test/test_urllibnet.py 2013-01-17 16:17:09.843089767 +0100
@@ -118,6 +118,10 @@ class urlopenNetworkTests(unittest.TestC
socket.gethostbyname(bogus_domain)
except socket.gaierror:
pass
+ except TimeoutError:
+ # Happens in chroots with bogus setups and "secured" build
+ # environments that just drop all traffic
+ self.skipTest("test_bad_address skipped due to timeout")
else:
# This happens with some overzealous DNS providers such as OpenDNS
self.skipTest("%r should not resolve for test to work" % bogus_domain)

View file

@ -0,0 +1,238 @@
diff -Naur Python-3.3.3.orig/Lib/test/test_urllibnet.py Python-3.3.3/Lib/test/test_urllibnet.py
--- Python-3.3.3.orig/Lib/test/test_urllibnet.py 2014-01-16 05:23:06.563537167 -0500
+++ Python-3.3.3/Lib/test/test_urllibnet.py 2014-01-16 05:23:12.598537003 -0500
@@ -121,6 +121,10 @@
# fail with EAI_SYSTEM and ETIMEDOUT (seen on Ubuntu 13.04),
# i.e. Python's TimeoutError.
pass
+ except TimeoutError:
+ # Happens in chroots with bogus setups and "secured" build
+ # environments that just drop all traffic
+ self.skipTest("test_bad_address skipped due to timeout")
else:
# This happens with some overzealous DNS providers such as OpenDNS
self.skipTest("%r should not resolve for test to work" % bogus_domain)
diff -Naur Python-3.3.3.orig/Lib/test/test_urllibnet.py.orig Python-3.3.3/Lib/test/test_urllibnet.py.orig
--- Python-3.3.3.orig/Lib/test/test_urllibnet.py.orig 1969-12-31 19:00:00.000000000 -0500
+++ Python-3.3.3/Lib/test/test_urllibnet.py.orig 2013-11-17 02:22:49.000000000 -0500
@@ -0,0 +1,220 @@
+#!/usr/bin/env python3
+
+import unittest
+from test import support
+
+import contextlib
+import socket
+import urllib.request
+import sys
+import os
+import email.message
+import time
+
+
+class URLTimeoutTest(unittest.TestCase):
+ # XXX this test doesn't seem to test anything useful.
+
+ TIMEOUT = 30.0
+
+ def setUp(self):
+ socket.setdefaulttimeout(self.TIMEOUT)
+
+ def tearDown(self):
+ socket.setdefaulttimeout(None)
+
+ def testURLread(self):
+ with support.transient_internet("www.python.org"):
+ f = urllib.request.urlopen("http://www.python.org/")
+ x = f.read()
+
+
+class urlopenNetworkTests(unittest.TestCase):
+ """Tests urllib.reqest.urlopen using the network.
+
+ These tests are not exhaustive. Assuming that testing using files does a
+ good job overall of some of the basic interface features. There are no
+ tests exercising the optional 'data' and 'proxies' arguments. No tests
+ for transparent redirection have been written.
+
+ setUp is not used for always constructing a connection to
+ http://www.python.org/ since there a few tests that don't use that address
+ and making a connection is expensive enough to warrant minimizing unneeded
+ connections.
+
+ """
+
+ @contextlib.contextmanager
+ def urlopen(self, *args, **kwargs):
+ resource = args[0]
+ with support.transient_internet(resource):
+ r = urllib.request.urlopen(*args, **kwargs)
+ try:
+ yield r
+ finally:
+ r.close()
+
+ def test_basic(self):
+ # Simple test expected to pass.
+ with self.urlopen("http://www.python.org/") as open_url:
+ for attr in ("read", "readline", "readlines", "fileno", "close",
+ "info", "geturl"):
+ self.assertTrue(hasattr(open_url, attr), "object returned from "
+ "urlopen lacks the %s attribute" % attr)
+ self.assertTrue(open_url.read(), "calling 'read' failed")
+
+ def test_readlines(self):
+ # Test both readline and readlines.
+ with self.urlopen("http://www.python.org/") as open_url:
+ self.assertIsInstance(open_url.readline(), bytes,
+ "readline did not return a string")
+ self.assertIsInstance(open_url.readlines(), list,
+ "readlines did not return a list")
+
+ def test_info(self):
+ # Test 'info'.
+ with self.urlopen("http://www.python.org/") as open_url:
+ info_obj = open_url.info()
+ self.assertIsInstance(info_obj, email.message.Message,
+ "object returned by 'info' is not an "
+ "instance of email.message.Message")
+ self.assertEqual(info_obj.get_content_subtype(), "html")
+
+ def test_geturl(self):
+ # Make sure same URL as opened is returned by geturl.
+ URL = "http://www.python.org/"
+ with self.urlopen(URL) as open_url:
+ gotten_url = open_url.geturl()
+ self.assertEqual(gotten_url, URL)
+
+ def test_getcode(self):
+ # test getcode() with the fancy opener to get 404 error codes
+ URL = "http://www.python.org/XXXinvalidXXX"
+ with support.transient_internet(URL):
+ open_url = urllib.request.FancyURLopener().open(URL)
+ try:
+ code = open_url.getcode()
+ finally:
+ open_url.close()
+ self.assertEqual(code, 404)
+
+ def test_fileno(self):
+ if sys.platform in ('win32',):
+ # On Windows, socket handles are not file descriptors; this
+ # test can't pass on Windows.
+ return
+ # Make sure fd returned by fileno is valid.
+ with self.urlopen("http://www.python.org/", timeout=None) as open_url:
+ fd = open_url.fileno()
+ with os.fdopen(fd, encoding='utf-8') as f:
+ self.assertTrue(f.read(), "reading from file created using fd "
+ "returned by fileno failed")
+
+ def test_bad_address(self):
+ # Make sure proper exception is raised when connecting to a bogus
+ # address.
+ bogus_domain = "sadflkjsasf.i.nvali.d"
+ try:
+ socket.gethostbyname(bogus_domain)
+ except OSError:
+ # socket.gaierror is too narrow, since getaddrinfo() may also
+ # fail with EAI_SYSTEM and ETIMEDOUT (seen on Ubuntu 13.04),
+ # i.e. Python's TimeoutError.
+ pass
+ else:
+ # This happens with some overzealous DNS providers such as OpenDNS
+ self.skipTest("%r should not resolve for test to work" % bogus_domain)
+ self.assertRaises(IOError,
+ # SF patch 809915: In Sep 2003, VeriSign started
+ # highjacking invalid .com and .net addresses to
+ # boost traffic to their own site. This test
+ # started failing then. One hopes the .invalid
+ # domain will be spared to serve its defined
+ # purpose.
+ # urllib.urlopen, "http://www.sadflkjsasadf.com/")
+ urllib.request.urlopen,
+ "http://sadflkjsasf.i.nvali.d/")
+
+
+class urlretrieveNetworkTests(unittest.TestCase):
+ """Tests urllib.request.urlretrieve using the network."""
+
+ @contextlib.contextmanager
+ def urlretrieve(self, *args, **kwargs):
+ resource = args[0]
+ with support.transient_internet(resource):
+ file_location, info = urllib.request.urlretrieve(*args, **kwargs)
+ try:
+ yield file_location, info
+ finally:
+ support.unlink(file_location)
+
+ def test_basic(self):
+ # Test basic functionality.
+ with self.urlretrieve("http://www.python.org/") as (file_location, info):
+ self.assertTrue(os.path.exists(file_location), "file location returned by"
+ " urlretrieve is not a valid path")
+ with open(file_location, encoding='utf-8') as f:
+ self.assertTrue(f.read(), "reading from the file location returned"
+ " by urlretrieve failed")
+
+ def test_specified_path(self):
+ # Make sure that specifying the location of the file to write to works.
+ with self.urlretrieve("http://www.python.org/",
+ support.TESTFN) as (file_location, info):
+ self.assertEqual(file_location, support.TESTFN)
+ self.assertTrue(os.path.exists(file_location))
+ with open(file_location, encoding='utf-8') as f:
+ self.assertTrue(f.read(), "reading from temporary file failed")
+
+ def test_header(self):
+ # Make sure header returned as 2nd value from urlretrieve is good.
+ with self.urlretrieve("http://www.python.org/") as (file_location, info):
+ self.assertIsInstance(info, email.message.Message,
+ "info is not an instance of email.message.Message")
+
+ logo = "http://www.python.org/community/logos/python-logo-master-v3-TM.png"
+
+ def test_data_header(self):
+ with self.urlretrieve(self.logo) as (file_location, fileheaders):
+ datevalue = fileheaders.get('Date')
+ dateformat = '%a, %d %b %Y %H:%M:%S GMT'
+ try:
+ time.strptime(datevalue, dateformat)
+ except ValueError:
+ self.fail('Date value not in %r format', dateformat)
+
+ def test_reporthook(self):
+ records = []
+ def recording_reporthook(blocks, block_size, total_size):
+ records.append((blocks, block_size, total_size))
+
+ with self.urlretrieve(self.logo, reporthook=recording_reporthook) as (
+ file_location, fileheaders):
+ expected_size = int(fileheaders['Content-Length'])
+
+ records_repr = repr(records) # For use in error messages.
+ self.assertGreater(len(records), 1, msg="There should always be two "
+ "calls; the first one before the transfer starts.")
+ self.assertEqual(records[0][0], 0)
+ self.assertGreater(records[0][1], 0,
+ msg="block size can't be 0 in %s" % records_repr)
+ self.assertEqual(records[0][2], expected_size)
+ self.assertEqual(records[-1][2], expected_size)
+
+ block_sizes = {block_size for _, block_size, _ in records}
+ self.assertEqual({records[0][1]}, block_sizes,
+ msg="block sizes in %s must be equal" % records_repr)
+ self.assertGreaterEqual(records[-1][0]*records[0][1], expected_size,
+ msg="number of blocks * block size must be"
+ " >= total size in %s" % records_repr)
+
+
+def test_main():
+ support.requires('network')
+ support.run_unittest(URLTimeoutTest,
+ urlopenNetworkTests,
+ urlretrieveNetworkTests)
+
+if __name__ == "__main__":
+ test_main()

View file

@ -1,4 +1,4 @@
%define docver 3.3.2
%define docver 3.3.3
%define dirver 3.3
%define familyver 3
@ -14,7 +14,7 @@
%endif
Summary: An interpreted, interactive object-oriented programming language
Name: python3
Version: 3.3.2
Version: 3.3.3
Release: 1
License: Modified CNRI Open Source License
Group: Development/Python
@ -24,13 +24,14 @@ Source1: http://www.python.org/ftp/python/doc/%{docver}/python-%{docver}-docs-ht
Source2: python3.macros
Source100: %{name}.rpmlintrc
#Source4: python-mode-1.0.tar.bz2
Source5: bdist_rpm5.py
Patch0: python-3.3.0-module-linkage.patch
Patch1: python3-3.3.0-fdr-lib64.patch
Patch2: python3-3.2.3-fdr-lib64-fix-for-test_install.patch
#Patch3: python-3.3.0-module-dependencies.patch
Patch4: python-3.3.0-fix-urllibnet-test.patch
Patch5: python-3.3.0-distutils-multiarch.patch
Patch4: python-3.3.3-fix-urllibnet-test.patch
Patch5: python-3.3.0-distutils-multiarch.patch
URL: http://www.python.org/
Conflicts: tkinter3 < %{version}
@ -164,7 +165,7 @@ bzcat %{SOURCE1} | tar x -C html
find . -type f -print0 | xargs -0 perl -p -i -e 's@/usr/local/bin/python@/usr/bin/python3@'
cat > README.mga << EOF
cat > README.urpmi << EOF
Python interpreter support readline completion by default.
This is only used with the interpreter. In order to remove it,
you can :
@ -328,8 +329,10 @@ EOF
mkdir -p %{buildroot}%{_sysconfdir}/rpm/macros.d
install -m644 %{SOURCE2} %{buildroot}%{_sysconfdir}/rpm/macros.d/
install -m644 %{SOURCE5} -D %{buildroot}%{_libdir}/python%{dirver}/distutils/command/bdist_rpm5.py
%files
%doc README.mga
%doc README.urpmi
# conflicts with python2.6
#%config(noreplace) %{_sysconfdir}/emacs/site-start.d/%{name}.el
%{_sysconfdir}/rpm/macros.d/*.macros