Index: Misc/NEWS =================================================================== --- Misc/NEWS (revision 62526) +++ Misc/NEWS (working copy) @@ -282,6 +282,9 @@ - Issue #1747858: Fix chown to work with large uid's and gid's on 64-bit platforms. +- Issue #1180: Add a --no-user-cfg option to distutils, allowing the + user to disable ~/.pydistutils.cfg. + - Issue #1202: zlib.crc32 and zlib.adler32 no longer return different values on 32-bit vs. 64-bit python interpreters. Both were correct, but they now both return a signed integer object for consistency. Index: Doc/distutils/builtdist.rst =================================================================== --- Doc/distutils/builtdist.rst (revision 62526) +++ Doc/distutils/builtdist.rst (working copy) @@ -238,7 +238,8 @@ configuration file, :file:`setup.cfg`\ ---see section :ref:`setup-config`. If you distribute or package many Python module distributions, you might want to put options that apply to all of them in your personal Distutils configuration -file (:file:`~/.pydistutils.cfg`). +file (:file:`~/.pydistutils.cfg`). If you want to temporarily disable +this file, you can pass the --no-user-cfg option to setup.py. There are three steps to building a binary RPM package, all of which are handled automatically by the Distutils: Index: Doc/ACKS.txt =================================================================== --- Doc/ACKS.txt (revision 62526) +++ Doc/ACKS.txt (working copy) @@ -201,6 +201,7 @@ * Mats Wichmann * Gerry Wiener * Timothy Wild + * Paul Winkler * Collin Winter * Blake Winton * Dan Wolfe Index: Doc/install/index.rst =================================================================== --- Doc/install/index.rst (revision 62526) +++ Doc/install/index.rst (working copy) @@ -694,6 +694,9 @@ | local | :file:`setup.cfg` | \(3) | +--------------+-------------------------------------------------+-------+ +On all platforms, the "personal" file can be temporarily disabled by +passing the `--no-user-cfg` option. + Notes: (1) Index: Lib/distutils/core.py =================================================================== --- Lib/distutils/core.py (revision 62526) +++ Lib/distutils/core.py (working copy) @@ -131,8 +131,9 @@ if _setup_stop_after == "config": return dist - # Parse the command line; any command-line errors are the end user's - # fault, so turn them into SystemExit to suppress tracebacks. + # Parse the command line and override config files; any + # command-line errors are the end user's fault, so turn them into + # SystemExit to suppress tracebacks. try: ok = dist.parse_command_line() except DistutilsArgError, msg: Index: Lib/distutils/tests/test_dist.py =================================================================== --- Lib/distutils/tests/test_dist.py (revision 62526) +++ Lib/distutils/tests/test_dist.py (working copy) @@ -21,6 +21,79 @@ self.sample_option = None +class DistributionConfigFileTestCase(unittest.TestCase): + + """Tests for the Distribution.find_config_files method.""" + + def setUp(self): + self.distutilsdir = os.path.dirname(sys.modules['distutils'].__file__) + + def test_find_config_nofiles(self): + # No files will be used if they don't actually exist. + d = distutils.dist.Distribution() + d._isfile = lambda name: None + files = d.find_config_files() + self.assertEqual(files, []) + + def test_find_config_files_posix_no_home(self): + d = distutils.dist.Distribution() + d._osname = 'posix' + d._homedir = None + d._isfile = lambda name: True + files = d.find_config_files() + self.assertEqual(len(files), 2) + self.assertEqual(files[0], + os.path.join(self.distutilsdir, 'distutils.cfg')) + self.assertEqual(files[1], 'setup.cfg') + + def test_find_config_files_posix_home(self): + d = distutils.dist.Distribution() + d._osname = 'posix' + d._homedir = '/home/gilliam' + d._isfile = lambda name: True + files = d.find_config_files() + self.assertEqual(len(files), 3) + self.assertEqual(files[0], + os.path.join(self.distutilsdir, 'distutils.cfg')) + self.assertEqual(files[1], + os.path.join('/home', 'gilliam', '.pydistutils.cfg')) + self.assertEqual(files[2], 'setup.cfg') + + def test_find_config_files_win_no_home(self): + d = distutils.dist.Distribution() + d._osname = 'nt' + d._homedir = None + d._isfile = lambda name: True + files = d.find_config_files() + self.assertEqual(len(files), 2) + self.assertEqual(files[0], + os.path.join(self.distutilsdir, 'distutils.cfg')) + self.assertEqual(files[1], 'setup.cfg') + + def test_find_config_files_win_home(self): + d = distutils.dist.Distribution() + d._osname = 'nt' + d._homedir = 'gilliam' + d._isfile = lambda name: True + files = d.find_config_files() + self.assertEqual(len(files), 3) + self.assertEqual(files[0], + os.path.join(self.distutilsdir, 'distutils.cfg')) + self.assertEqual(files[1], os.path.join('gilliam', 'pydistutils.cfg')) + self.assertEqual(files[2], 'setup.cfg') + + def test_find_config_files_disable(self): + # Ticket #1180: Allow user to disable their home config file. + d = distutils.dist.Distribution(attrs={'script_args': + ['--no-user-cfg']}) + d._isfile = lambda name: True + files = d.find_config_files() + self.assertEqual(len(files), 2) + self.assertEqual(files[0], + os.path.join(self.distutilsdir, 'distutils.cfg')) + self.assertEqual(files[1], 'setup.cfg') + + class TestDistribution(distutils.dist.Distribution): """Distribution subclasses that avoids the default search for configuration files. @@ -184,4 +257,5 @@ suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DistributionTestCase)) suite.addTest(unittest.makeSuite(MetadataTestCase)) + suite.addTest(unittest.makeSuite(DistributionConfigFileTestCase)) return suite Index: Lib/distutils/dist.py =================================================================== --- Lib/distutils/dist.py (revision 62526) +++ Lib/distutils/dist.py (working copy) @@ -57,7 +57,9 @@ ('quiet', 'q', "run quietly (turns verbosity off)"), ('dry-run', 'n', "don't actually do anything"), ('help', 'h', "show detailed help message"), - ] + ('no-user-cfg', None, + 'ignore pydistutils.cfg in your home directory'), + ] # 'common_usage' is a short (2-3 line) string describing the common # usage of the setup script. @@ -137,6 +139,7 @@ self.verbose = 1 self.dry_run = 0 self.help = 0 + for attr in self.display_option_names: setattr(self, attr, 0) @@ -222,6 +225,13 @@ # '.get()' rather than a straight lookup. self.have_run = {} + # Cache some dependencies, mostly to allow dependency + # injection for tests. + check_environ() + self._osname = os.name + self._homedir = os.environ.get('HOME') + self._isfile = os.path.isfile + # Now we'll use the attrs dictionary (ultimately, keyword args from # the setup script) to possibly override any or all of these # distribution options. @@ -266,6 +276,13 @@ self.finalize_options() + # no-user-cfg is handled before other command line args + # because other args override the config files, and this + # one is needed before we can load the config files. + # We assume that script_args was passed... + self.no_user_cfg = '--no-user-cfg' in (self.script_args or []) + + # __init__ () @@ -321,38 +338,45 @@ There are three possible config files: distutils.cfg in the Distutils installation directory (ie. where the top-level - Distutils __inst__.py file lives), a file in the user's home + Distutils __inst__.py file lives); a file in the user's home directory named .pydistutils.cfg on Unix and pydistutils.cfg - on Windows/Mac, and setup.cfg in the current directory. + on Windows/Mac; and setup.cfg in the current directory. + + The file in the user's home directory can be disabled with the + --no-user-cfg option. """ files = [] - check_environ() # Where to look for the system-wide Distutils config file sys_dir = os.path.dirname(sys.modules['distutils'].__file__) # Look for the system config file sys_file = os.path.join(sys_dir, "distutils.cfg") - if os.path.isfile(sys_file): + if self._isfile(sys_file): files.append(sys_file) - # What to call the per-user config file - if os.name == 'posix': - user_filename = ".pydistutils.cfg" + # Find the per-user config file, if wanted. + if self.no_user_cfg: + # User explicitly disabled it. + pass else: - user_filename = "pydistutils.cfg" + # Find it in the user's home dir. + if self._osname == 'posix': + user_filename = ".pydistutils.cfg" + else: + user_filename = "pydistutils.cfg" + if self._homedir: + user_file = os.path.join(self._homedir, user_filename) + if self._isfile(user_file): + files.append(user_file) - # And look for the user config file - if 'HOME' in os.environ: - user_file = os.path.join(os.environ.get('HOME'), user_filename) - if os.path.isfile(user_file): - files.append(user_file) - # All platforms support local setup.cfg local_file = "setup.cfg" - if os.path.isfile(local_file): + if self._isfile(local_file): files.append(local_file) + if DEBUG: + print "using config files: %s" % ', '.join(files) return files # find_config_files () @@ -447,6 +471,7 @@ parser = FancyGetopt(toplevel_options + self.display_options) parser.set_negative_aliases(self.negative_opt) parser.set_aliases({'licence': 'license'}) + # Parse each option and store as name-mangled attributes of self. args = parser.getopt(args=self.script_args, object=self) option_order = parser.get_option_order() log.set_verbosity(self.verbose)