-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve encoding handling for setup.cfg
#1180
improve encoding handling for setup.cfg
#1180
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to defer this work until setuptools adopts distutils (#417)?
setuptools/py36compat.py
Outdated
@@ -33,11 +47,16 @@ def parse_config_files(self, filenames=None): | |||
if DEBUG: | |||
self.announce("Distribution.parse_config_files():") | |||
|
|||
parser = ConfigParser(interpolation=None) | |||
parser = ConfigParser() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know interpolation causes problems when a percent appears in the setup.cfg (such as for a password). I think there are tests to protect this behavior (perhaps only in CPython).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the other way round, interpolation as always been enabled, see: #889 (comment)
This compatibility code was actually not used, that's why I added a test first to make sure this behavior (interpolation enabled) did not change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right. Good point. I wonder then if that means we (I) need to update the code in distutils for Python 3.7 to restore interpolation before it goes live.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, reviewing the history on the CPython issue, I see that there's not yet a patch in CPython that's affected by this change.
e110db5
to
2c897b5
Compare
Reworked and slightly expanded tests. |
I agree that this could wait for distutils code to be included in setuptools. |
We can either wait for the distutils code to be adopted by Setuptools or we can simply override the parse_config_files in Distribution (and own it, rather than working to rely on the upstream version). I'm slightly inclined toward the latter, not knowing when/if distutils will land. Would you like to work on those changes or would you rather I do it (I feel some responsibility having put the compatibility layer in place)? |
ouch, this is still an issue :/ |
Hi and thanks for working on this. I also got bitten by #1136 and followed the thread here. Is this planned to be merged? |
A bug is blocking setuptools from working with python2 [bug]. Work is on its way [pr]. Until that is fixed, package_dir should be defined in setup.py to preserve compatibility of the native str type. [bug]: pypa/setuptools#1136 [pr]: pypa/setuptools#1180 Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
I think we do basically want to adopt this change, but as part of a refactor to have setuptools take ownership of the relevant functionality from distutils (rather than trying to contribute it upstream first, which was the intention here). |
I'm sorry to have left this to languish for so long. I want to accept these changes with some small tweaks (mainly proper adoption of the config file parsing functionality). I'll resolve the conflicts and press forward. |
…e upstream, just incorporate the functionality directly.
I believe this work is ready to go, but tests are failing due to #1644. |
There's still a failing test on Python 2.7. I'm not yet clear on why. |
That's an issue somewhere in the bowels of distutils, when handling boolean options: setuptools/dist.py | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git i/setuptools/dist.py w/setuptools/dist.py
index 4cc3bdfe..6cabfb60 100644
--- i/setuptools/dist.py
+++ w/setuptools/dist.py
@@ -12,6 +12,7 @@
import distutils.cmd
import distutils.dist
from distutils.errors import DistutilsOptionError
+from distutils.fancy_getopt import translate_longopt
from distutils.util import strtobool
from distutils.debug import DEBUG
import itertools
@@ -560,6 +561,50 @@ def _clean_req(self, req):
req.marker = None
return req
+ def _set_command_options(self, command_obj, option_dict=None):
+ """Set the options for 'command_obj' from 'option_dict'. Basically
+ this means copying elements of a dictionary ('option_dict') to
+ attributes of an instance ('command').
+
+ 'command_obj' must be a Command instance. If 'option_dict' is not
+ supplied, uses the standard option dictionary for this command
+ (from 'self.command_options').
+ """
+ command_name = command_obj.get_command_name()
+ if option_dict is None:
+ option_dict = self.get_option_dict(command_name)
+
+ if DEBUG:
+ self.announce(" setting options for '%s' command:" % command_name)
+ for (option, (source, value)) in option_dict.items():
+ if DEBUG:
+ self.announce(" %s = %s (from %s)" % (option, value,
+ source))
+ try:
+ bool_opts = [translate_longopt(o)
+ for o in command_obj.boolean_options]
+ except AttributeError:
+ bool_opts = []
+ try:
+ neg_opt = command_obj.negative_opt
+ except AttributeError:
+ neg_opt = {}
+
+ try:
+ is_string = isinstance(value, six.string_types)
+ if option in neg_opt and is_string:
+ setattr(command_obj, neg_opt[option], not strtobool(value))
+ elif option in bool_opts and is_string:
+ setattr(command_obj, option, strtobool(value))
+ elif hasattr(command_obj, option):
+ setattr(command_obj, option, value)
+ else:
+ raise DistutilsOptionError(
+ "error in %s: command '%s' has no such option '%s'"
+ % (source, command_name, option))
+ except ValueError as msg:
+ raise DistutilsOptionError(msg)
+
def _parse_config_files(self, filenames=None):
"""
Adapted from distutils.dist.Distribution.parse_config_files, |
The remaining test failure (just one) is due to an option "tag-date=0" being parsed as |
…ter string detection.
@benoit-pierre Assuming tests pass (they do for me locally), would you please review the latest changes? |
Well, I can't approve my own PR, but looks good to me! |
PR pypa#1180 and 24be5ab changed the way we read setup.cfg, but when editing setup.cfg we might still lose the encoding hint on the file, which can cause failures in subsequent steps. This change detectes the encoding like in `_parse_config_files` and writes an encoding hint header if the file encoding was detected. Fixes jaraco/configparser#37.
PR pypa#1180 and 24be5ab changed the way we read setup.cfg, but when editing setup.cfg we might still lose the encoding hint on the file, which can cause failures in subsequent steps. This change detectes the encoding like in `_parse_config_files` and writes an encoding hint header if the file encoding was detected. Fixes jaraco/configparser#37.
PR pypa#1180 and 24be5ab changed the way we read setup.cfg, but when editing setup.cfg we might still lose the encoding hint on the file, which can cause failures in subsequent steps. This change detectes the encoding like in `_parse_config_files` and writes an encoding hint header if the file encoding was detected. Fixes jaraco/configparser#37.
Support the same mechanism as for Python sources for declaring the encoding to be used when reading
setup.cfg
(see PEP 263), and return the results of reading it as Unicode.Fix #1062 and #1136.