66import imp
77import sys
88import errno
9+ import codecs
910import shutil
1011import string
1112import hashlib
@@ -417,7 +418,8 @@ def byte_compile(py_files, optimize=0, force=False, prefix=None,
417418 # cfile - byte-compiled file
418419 # dfile - purported source filename (same as 'file' by default)
419420 if optimize >= 0 :
420- cfile = imp .cache_from_source (file , debug_override = not optimize )
421+ cfile = imp .cache_from_source (file ,
422+ debug_override = not optimize )
421423 else :
422424 cfile = imp .cache_from_source (file )
423425 dfile = file
@@ -931,6 +933,24 @@ def _iglob(path_glob):
931933 yield file
932934
933935
936+ # HOWTO change cfg_to_args
937+ #
938+ # This function has two major constraints: It is copied by inspect.getsource
939+ # in generate_setup_py; it is used in generated setup.py which may be run by
940+ # any Python version supported by distutils2 (2.4-3.3).
941+ #
942+ # * Keep objects like D1_D2_SETUP_ARGS static, i.e. in the function body
943+ # instead of global.
944+ # * If you use a function from another module, update the imports in
945+ # SETUP_TEMPLATE. Use only modules, classes and functions compatible with
946+ # all versions: codecs.open instead of open, RawConfigParser.readfp instead
947+ # of read, standard exceptions instead of Packaging*Error, etc.
948+ # * If you use a function from this module, update the template and
949+ # generate_setup_py.
950+ #
951+ # test_util tests this function and the generated setup.py, but does not test
952+ # that it's compatible with all Python versions.
953+
934954def cfg_to_args (path = 'setup.cfg' ):
935955 """Compatibility helper to use setup.cfg in setup.py.
936956
@@ -941,8 +961,6 @@ def cfg_to_args(path='setup.cfg'):
941961 *file* is the path to the setup.cfg file. If it doesn't exist,
942962 PackagingFileError is raised.
943963 """
944- # We need to declare the following constants here so that it's easier to
945- # generate the setup.py afterwards, using inspect.getsource.
946964
947965 # XXX ** == needs testing
948966 D1_D2_SETUP_ARGS = {"name" : ("metadata" ,),
@@ -986,10 +1004,11 @@ def has_get_option(config, section, option):
9861004
9871005 # The real code starts here
9881006 config = RawConfigParser ()
989- if not os .path .exists (path ):
990- raise PackagingFileError ("file '%s' does not exist" %
991- os .path .abspath (path ))
992- config .read (path , encoding = 'utf-8' )
1007+ f = codecs .open (path , encoding = 'utf-8' )
1008+ try :
1009+ config .readfp (f )
1010+ finally :
1011+ f .close ()
9931012
9941013 kwargs = {}
9951014 for arg in D1_D2_SETUP_ARGS :
@@ -1011,8 +1030,11 @@ def has_get_option(config, section, option):
10111030 filenames = split_multiline (filenames )
10121031 in_cfg_value = []
10131032 for filename in filenames :
1014- with open (filename ) as fp :
1033+ fp = codecs .open (filename , encoding = 'utf-8' )
1034+ try :
10151035 in_cfg_value .append (fp .read ())
1036+ finally :
1037+ fp .close ()
10161038 in_cfg_value = '\n \n ' .join (in_cfg_value )
10171039 else :
10181040 continue
@@ -1029,13 +1051,19 @@ def has_get_option(config, section, option):
10291051 return kwargs
10301052
10311053
1032- _SETUP_TMPL = """\
1054+ SETUP_TEMPLATE = """\
10331055 # This script was automatically generated by packaging
10341056import os
1057+ import codecs
10351058from distutils.core import setup
1036- from ConfigParser import RawConfigParser
1059+ try:
1060+ from ConfigParser import RawConfigParser
1061+ except ImportError:
1062+ from configparser import RawConfigParser
1063+
1064+ %(split_multiline)s
10371065
1038- %(func )s
1066+ %(cfg_to_args )s
10391067
10401068setup(**cfg_to_args())
10411069"""
@@ -1049,8 +1077,10 @@ def generate_setup_py():
10491077 if os .path .exists ("setup.py" ):
10501078 raise PackagingFileError ("a setup.py file already exists" )
10511079
1080+ source = SETUP_TEMPLATE % {'split_multiline' : getsource (split_multiline ),
1081+ 'cfg_to_args' : getsource (cfg_to_args )}
10521082 with open ("setup.py" , "w" , encoding = 'utf-8' ) as fp :
1053- fp .write (_SETUP_TMPL % { 'func' : getsource ( cfg_to_args )} )
1083+ fp .write (source )
10541084
10551085
10561086# Taken from the pip project
@@ -1307,6 +1337,8 @@ def get_install_method(path):
13071337def copy_tree (src , dst , preserve_mode = True , preserve_times = True ,
13081338 preserve_symlinks = False , update = False , verbose = True ,
13091339 dry_run = False ):
1340+ # FIXME use of this function is why we get spurious logging message on
1341+ # stdout when tests run; kill and replace by shuil!
13101342 from distutils .file_util import copy_file
13111343
13121344 if not dry_run and not os .path .isdir (src ):
0 commit comments