We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ValueError: invalid literal for int() with base 10: 'post20190705'
It seems that code from setup.py is broken as it makes the wrong assumption that `setuptools.__version__.` will always return only integers:

https://github.com/ansible/molecule/blob/master/setup.py#L36

```
        RUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')))
    ValueError: invalid literal for int() with base 10: 'post20190705'
```

As seen here the minor version can be a non numeric value. The quick workaround is to only look at the fist two elements.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `setup.py`
Content:
```
1 #! /usr/bin/env python
2 #  Copyright (c) 2019 Red Hat, Inc.
3 #  Copyright (c) 2015-2018 Cisco Systems, Inc.
4 #
5 #  Permission is hereby granted, free of charge, to any person obtaining a copy
6 #  of this software and associated documentation files (the "Software"), to
7 #  deal in the Software without restriction, including without limitation the
8 #  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 #  sell copies of the Software, and to permit persons to whom the Software is
10 #  furnished to do so, subject to the following conditions:
11 #
12 #  The above copyright notice and this permission notice shall be included in
13 #  all copies or substantial portions of the Software.
14 #
15 #  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 #  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 #  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 #  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 #  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 #  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 #  DEALINGS IN THE SOFTWARE.
22 """Molecule distribution package setuptools installer."""
23 
24 import setuptools
25 
26 HAS_DIST_INFO_CMD = False
27 try:
28     import setuptools.command.dist_info
29 
30     HAS_DIST_INFO_CMD = True
31 except ImportError:
32     """Setuptools version is too old."""
33 
34 
35 ALL_STRING_TYPES = tuple(map(type, ('', b'', u'')))
36 MIN_NATIVE_SETUPTOOLS_VERSION = 34, 4, 0
37 """Minimal setuptools having good read_configuration implementation."""
38 
39 RUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')))
40 """Setuptools imported now."""
41 
42 READ_CONFIG_SHIM_NEEDED = RUNTIME_SETUPTOOLS_VERSION < MIN_NATIVE_SETUPTOOLS_VERSION
43 
44 
45 def str_if_nested_or_str(s):
46     """Turn input into a native string if possible."""
47     if isinstance(s, ALL_STRING_TYPES):
48         return str(s)
49     if isinstance(s, (list, tuple)):
50         return type(s)(map(str_if_nested_or_str, s))
51     if isinstance(s, (dict,)):
52         return stringify_dict_contents(s)
53     return s
54 
55 
56 def stringify_dict_contents(dct):
57     """Turn dict keys and values into native strings."""
58     return {str_if_nested_or_str(k): str_if_nested_or_str(v) for k, v in dct.items()}
59 
60 
61 if not READ_CONFIG_SHIM_NEEDED:
62     from setuptools.config import read_configuration, ConfigOptionsHandler
63     import setuptools.config
64     import setuptools.dist
65 
66     # Set default value for 'use_scm_version'
67     setattr(setuptools.dist.Distribution, 'use_scm_version', False)
68 
69     # Attach bool parser to 'use_scm_version' option
70     class ShimConfigOptionsHandler(ConfigOptionsHandler):
71         """Extension class for ConfigOptionsHandler."""
72 
73         @property
74         def parsers(self):
75             """Return an option mapping with default data type parsers."""
76             _orig_parsers = super(ShimConfigOptionsHandler, self).parsers
77             return dict(use_scm_version=self._parse_bool, **_orig_parsers)
78 
79         def parse_section_packages__find(self, section_options):
80             find_kwargs = super(
81                 ShimConfigOptionsHandler, self
82             ).parse_section_packages__find(section_options)
83             return stringify_dict_contents(find_kwargs)
84 
85     setuptools.config.ConfigOptionsHandler = ShimConfigOptionsHandler
86 else:
87     """This is a shim for setuptools<required."""
88     import functools
89     import io
90     import json
91     import sys
92     import warnings
93 
94     try:
95         import setuptools.config
96 
97         def filter_out_unknown_section(i):
98             def chi(self, *args, **kwargs):
99                 i(self, *args, **kwargs)
100                 self.sections = {
101                     s: v for s, v in self.sections.items() if s != 'packages.find'
102                 }
103 
104             return chi
105 
106         setuptools.config.ConfigHandler.__init__ = filter_out_unknown_section(
107             setuptools.config.ConfigHandler.__init__
108         )
109     except ImportError:
110         pass
111 
112     def ignore_unknown_options(s):
113         @functools.wraps(s)
114         def sw(**attrs):
115             try:
116                 ignore_warning_regex = (
117                     r"Unknown distribution option: "
118                     r"'(license_file|project_urls|python_requires)'"
119                 )
120                 warnings.filterwarnings(
121                     'ignore',
122                     message=ignore_warning_regex,
123                     category=UserWarning,
124                     module='distutils.dist',
125                 )
126                 return s(**attrs)
127             finally:
128                 warnings.resetwarnings()
129 
130         return sw
131 
132     def parse_predicates(python_requires):
133         import itertools
134         import operator
135 
136         sorted_operators_map = tuple(
137             sorted(
138                 {
139                     '>': operator.gt,
140                     '<': operator.lt,
141                     '>=': operator.ge,
142                     '<=': operator.le,
143                     '==': operator.eq,
144                     '!=': operator.ne,
145                     '': operator.eq,
146                 }.items(),
147                 key=lambda i: len(i[0]),
148                 reverse=True,
149             )
150         )
151 
152         def is_decimal(s):
153             return type(u'')(s).isdecimal()
154 
155         conditions = map(str.strip, python_requires.split(','))
156         for c in conditions:
157             for op_sign, op_func in sorted_operators_map:
158                 if not c.startswith(op_sign):
159                     continue
160                 raw_ver = itertools.takewhile(
161                     is_decimal, c[len(op_sign) :].strip().split('.')
162                 )
163                 ver = tuple(map(int, raw_ver))
164                 yield op_func, ver
165                 break
166 
167     def validate_required_python_or_fail(python_requires=None):
168         if python_requires is None:
169             return
170 
171         python_version = sys.version_info
172         preds = parse_predicates(python_requires)
173         for op, v in preds:
174             py_ver_slug = python_version[: max(len(v), 3)]
175             condition_matches = op(py_ver_slug, v)
176             if not condition_matches:
177                 raise RuntimeError(
178                     "requires Python '{}' but the running Python is {}".format(
179                         python_requires, '.'.join(map(str, python_version[:3]))
180                     )
181                 )
182 
183     def verify_required_python_runtime(s):
184         @functools.wraps(s)
185         def sw(**attrs):
186             try:
187                 validate_required_python_or_fail(attrs.get('python_requires'))
188             except RuntimeError as re:
189                 sys.exit('{} {!s}'.format(attrs['name'], re))
190             return s(**attrs)
191 
192         return sw
193 
194     setuptools.setup = ignore_unknown_options(setuptools.setup)
195     setuptools.setup = verify_required_python_runtime(setuptools.setup)
196 
197     try:
198         from configparser import ConfigParser, NoSectionError
199     except ImportError:
200         from ConfigParser import ConfigParser, NoSectionError
201 
202         ConfigParser.read_file = ConfigParser.readfp
203 
204     def maybe_read_files(d):
205         """Read files if the string starts with `file:` marker."""
206         FILE_FUNC_MARKER = 'file:'
207 
208         d = d.strip()
209         if not d.startswith(FILE_FUNC_MARKER):
210             return d
211         descs = []
212         for fname in map(str.strip, str(d[len(FILE_FUNC_MARKER) :]).split(',')):
213             with io.open(fname, encoding='utf-8') as f:
214                 descs.append(f.read())
215         return ''.join(descs)
216 
217     def cfg_val_to_list(v):
218         """Turn config val to list and filter out empty lines."""
219         return list(filter(bool, map(str.strip, str(v).strip().splitlines())))
220 
221     def cfg_val_to_dict(v):
222         """Turn config val to dict and filter out empty lines."""
223         return dict(
224             map(
225                 lambda l: list(map(str.strip, l.split('=', 1))),
226                 filter(bool, map(str.strip, str(v).strip().splitlines())),
227             )
228         )
229 
230     def cfg_val_to_primitive(v):
231         """Parse primitive config val to appropriate data type."""
232         return json.loads(v.strip().lower())
233 
234     def read_configuration(filepath):
235         """Read metadata and options from setup.cfg located at filepath."""
236         cfg = ConfigParser()
237         with io.open(filepath, encoding='utf-8') as f:
238             cfg.read_file(f)
239 
240         md = dict(cfg.items('metadata'))
241         for list_key in 'classifiers', 'keywords', 'project_urls':
242             try:
243                 md[list_key] = cfg_val_to_list(md[list_key])
244             except KeyError:
245                 pass
246         try:
247             md['long_description'] = maybe_read_files(md['long_description'])
248         except KeyError:
249             pass
250         opt = dict(cfg.items('options'))
251         for list_key in 'include_package_data', 'use_scm_version', 'zip_safe':
252             try:
253                 opt[list_key] = cfg_val_to_primitive(opt[list_key])
254             except KeyError:
255                 pass
256         for list_key in 'scripts', 'install_requires', 'setup_requires':
257             try:
258                 opt[list_key] = cfg_val_to_list(opt[list_key])
259             except KeyError:
260                 pass
261         try:
262             opt['package_dir'] = cfg_val_to_dict(opt['package_dir'])
263         except KeyError:
264             pass
265         try:
266             opt_package_data = dict(cfg.items('options.package_data'))
267             if not opt_package_data.get('', '').strip():
268                 opt_package_data[''] = opt_package_data['*']
269                 del opt_package_data['*']
270         except (KeyError, NoSectionError):
271             opt_package_data = {}
272         try:
273             opt_extras_require = dict(cfg.items('options.extras_require'))
274             opt['extras_require'] = {}
275             for k, v in opt_extras_require.items():
276                 opt['extras_require'][k] = cfg_val_to_list(v)
277         except NoSectionError:
278             pass
279         opt['package_data'] = {}
280         for k, v in opt_package_data.items():
281             opt['package_data'][k] = cfg_val_to_list(v)
282         try:
283             opt_exclude_package_data = dict(cfg.items('options.exclude_package_data'))
284             if (
285                 not opt_exclude_package_data.get('', '').strip()
286                 and '*' in opt_exclude_package_data
287             ):
288                 opt_exclude_package_data[''] = opt_exclude_package_data['*']
289                 del opt_exclude_package_data['*']
290         except NoSectionError:
291             pass
292         else:
293             opt['exclude_package_data'] = {}
294             for k, v in opt_exclude_package_data.items():
295                 opt['exclude_package_data'][k] = cfg_val_to_list(v)
296         cur_pkgs = opt.get('packages', '').strip()
297         if '\n' in cur_pkgs:
298             opt['packages'] = cfg_val_to_list(opt['packages'])
299         elif cur_pkgs.startswith('find:'):
300             opt_packages_find = stringify_dict_contents(
301                 dict(cfg.items('options.packages.find'))
302             )
303             opt['packages'] = setuptools.find_packages(**opt_packages_find)
304         return {'metadata': md, 'options': opt}
305 
306 
307 def cut_local_version_on_upload(version):
308     """Generate a PEP440 local version if uploading to PyPI."""
309     import os
310     import setuptools_scm.version  # only present during setup time
311 
312     IS_PYPI_UPLOAD = os.getenv('PYPI_UPLOAD') == 'true'  # set in tox.ini
313     return (
314         ''
315         if IS_PYPI_UPLOAD
316         else setuptools_scm.version.get_local_node_and_date(version)
317     )
318 
319 
320 if HAS_DIST_INFO_CMD:
321 
322     class patched_dist_info(setuptools.command.dist_info.dist_info):
323         def run(self):
324             self.egg_base = str_if_nested_or_str(self.egg_base)
325             return setuptools.command.dist_info.dist_info.run(self)
326 
327 
328 declarative_setup_params = read_configuration('setup.cfg')
329 """Declarative metadata and options as read by setuptools."""
330 
331 
332 setup_params = {}
333 """Explicit metadata for passing into setuptools.setup() call."""
334 
335 setup_params = dict(setup_params, **declarative_setup_params['metadata'])
336 setup_params = dict(setup_params, **declarative_setup_params['options'])
337 
338 if HAS_DIST_INFO_CMD:
339     setup_params['cmdclass'] = {'dist_info': patched_dist_info}
340 
341 setup_params['use_scm_version'] = {'local_scheme': cut_local_version_on_upload}
342 
343 # Patch incorrectly decoded package_dir option
344 # ``egg_info`` demands native strings failing with unicode under Python 2
345 # Ref https://github.com/pypa/setuptools/issues/1136
346 setup_params = stringify_dict_contents(setup_params)
347 
348 
349 __name__ == '__main__' and setuptools.setup(**setup_params)
350
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -33,10 +33,11 @@
 
 
 ALL_STRING_TYPES = tuple(map(type, ('', b'', u'')))
-MIN_NATIVE_SETUPTOOLS_VERSION = 34, 4, 0
+MIN_NATIVE_SETUPTOOLS_VERSION = 34, 4
 """Minimal setuptools having good read_configuration implementation."""
 
-RUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')))
+# Patch version can be a non integer value, like 'post20190705'
+RUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')[:2]))
 """Setuptools imported now."""
 
 READ_CONFIG_SHIM_NEEDED = RUNTIME_SETUPTOOLS_VERSION < MIN_NATIVE_SETUPTOOLS_VERSION

{"golden_diff": "diff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -33,10 +33,11 @@\n \n \n ALL_STRING_TYPES = tuple(map(type, ('', b'', u'')))\n-MIN_NATIVE_SETUPTOOLS_VERSION = 34, 4, 0\n+MIN_NATIVE_SETUPTOOLS_VERSION = 34, 4\n \"\"\"Minimal setuptools having good read_configuration implementation.\"\"\"\n \n-RUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')))\n+# Patch version can be a non integer value, like 'post20190705'\n+RUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')[:2]))\n \"\"\"Setuptools imported now.\"\"\"\n \n READ_CONFIG_SHIM_NEEDED = RUNTIME_SETUPTOOLS_VERSION < MIN_NATIVE_SETUPTOOLS_VERSION\n", "issue": "ValueError: invalid literal for int() with base 10: 'post20190705'\nIt seems that code from setup.py is broken as it makes the wrong assumption that `setuptools.__version__.` will always return only integers:\r\n\r\nhttps://github.com/ansible/molecule/blob/master/setup.py#L36\r\n\r\n```\r\n        RUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')))\r\n    ValueError: invalid literal for int() with base 10: 'post20190705'\r\n```\r\n\r\nAs seen here the minor version can be a non numeric value. The quick workaround is to only look at the fist two elements.\n", "before_files": [{"content": "#! /usr/bin/env python\n#  Copyright (c) 2019 Red Hat, Inc.\n#  Copyright (c) 2015-2018 Cisco Systems, Inc.\n#\n#  Permission is hereby granted, free of charge, to any person obtaining a copy\n#  of this software and associated documentation files (the \"Software\"), to\n#  deal in the Software without restriction, including without limitation the\n#  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n#  sell copies of the Software, and to permit persons to whom the Software is\n#  furnished to do so, subject to the following conditions:\n#\n#  The above copyright notice and this permission notice shall be included in\n#  all copies or substantial portions of the Software.\n#\n#  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n#  DEALINGS IN THE SOFTWARE.\n\"\"\"Molecule distribution package setuptools installer.\"\"\"\n\nimport setuptools\n\nHAS_DIST_INFO_CMD = False\ntry:\n    import setuptools.command.dist_info\n\n    HAS_DIST_INFO_CMD = True\nexcept ImportError:\n    \"\"\"Setuptools version is too old.\"\"\"\n\n\nALL_STRING_TYPES = tuple(map(type, ('', b'', u'')))\nMIN_NATIVE_SETUPTOOLS_VERSION = 34, 4, 0\n\"\"\"Minimal setuptools having good read_configuration implementation.\"\"\"\n\nRUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')))\n\"\"\"Setuptools imported now.\"\"\"\n\nREAD_CONFIG_SHIM_NEEDED = RUNTIME_SETUPTOOLS_VERSION < MIN_NATIVE_SETUPTOOLS_VERSION\n\n\ndef str_if_nested_or_str(s):\n    \"\"\"Turn input into a native string if possible.\"\"\"\n    if isinstance(s, ALL_STRING_TYPES):\n        return str(s)\n    if isinstance(s, (list, tuple)):\n        return type(s)(map(str_if_nested_or_str, s))\n    if isinstance(s, (dict,)):\n        return stringify_dict_contents(s)\n    return s\n\n\ndef stringify_dict_contents(dct):\n    \"\"\"Turn dict keys and values into native strings.\"\"\"\n    return {str_if_nested_or_str(k): str_if_nested_or_str(v) for k, v in dct.items()}\n\n\nif not READ_CONFIG_SHIM_NEEDED:\n    from setuptools.config import read_configuration, ConfigOptionsHandler\n    import setuptools.config\n    import setuptools.dist\n\n    # Set default value for 'use_scm_version'\n    setattr(setuptools.dist.Distribution, 'use_scm_version', False)\n\n    # Attach bool parser to 'use_scm_version' option\n    class ShimConfigOptionsHandler(ConfigOptionsHandler):\n        \"\"\"Extension class for ConfigOptionsHandler.\"\"\"\n\n        @property\n        def parsers(self):\n            \"\"\"Return an option mapping with default data type parsers.\"\"\"\n            _orig_parsers = super(ShimConfigOptionsHandler, self).parsers\n            return dict(use_scm_version=self._parse_bool, **_orig_parsers)\n\n        def parse_section_packages__find(self, section_options):\n            find_kwargs = super(\n                ShimConfigOptionsHandler, self\n            ).parse_section_packages__find(section_options)\n            return stringify_dict_contents(find_kwargs)\n\n    setuptools.config.ConfigOptionsHandler = ShimConfigOptionsHandler\nelse:\n    \"\"\"This is a shim for setuptools<required.\"\"\"\n    import functools\n    import io\n    import json\n    import sys\n    import warnings\n\n    try:\n        import setuptools.config\n\n        def filter_out_unknown_section(i):\n            def chi(self, *args, **kwargs):\n                i(self, *args, **kwargs)\n                self.sections = {\n                    s: v for s, v in self.sections.items() if s != 'packages.find'\n                }\n\n            return chi\n\n        setuptools.config.ConfigHandler.__init__ = filter_out_unknown_section(\n            setuptools.config.ConfigHandler.__init__\n        )\n    except ImportError:\n        pass\n\n    def ignore_unknown_options(s):\n        @functools.wraps(s)\n        def sw(**attrs):\n            try:\n                ignore_warning_regex = (\n                    r\"Unknown distribution option: \"\n                    r\"'(license_file|project_urls|python_requires)'\"\n                )\n                warnings.filterwarnings(\n                    'ignore',\n                    message=ignore_warning_regex,\n                    category=UserWarning,\n                    module='distutils.dist',\n                )\n                return s(**attrs)\n            finally:\n                warnings.resetwarnings()\n\n        return sw\n\n    def parse_predicates(python_requires):\n        import itertools\n        import operator\n\n        sorted_operators_map = tuple(\n            sorted(\n                {\n                    '>': operator.gt,\n                    '<': operator.lt,\n                    '>=': operator.ge,\n                    '<=': operator.le,\n                    '==': operator.eq,\n                    '!=': operator.ne,\n                    '': operator.eq,\n                }.items(),\n                key=lambda i: len(i[0]),\n                reverse=True,\n            )\n        )\n\n        def is_decimal(s):\n            return type(u'')(s).isdecimal()\n\n        conditions = map(str.strip, python_requires.split(','))\n        for c in conditions:\n            for op_sign, op_func in sorted_operators_map:\n                if not c.startswith(op_sign):\n                    continue\n                raw_ver = itertools.takewhile(\n                    is_decimal, c[len(op_sign) :].strip().split('.')\n                )\n                ver = tuple(map(int, raw_ver))\n                yield op_func, ver\n                break\n\n    def validate_required_python_or_fail(python_requires=None):\n        if python_requires is None:\n            return\n\n        python_version = sys.version_info\n        preds = parse_predicates(python_requires)\n        for op, v in preds:\n            py_ver_slug = python_version[: max(len(v), 3)]\n            condition_matches = op(py_ver_slug, v)\n            if not condition_matches:\n                raise RuntimeError(\n                    \"requires Python '{}' but the running Python is {}\".format(\n                        python_requires, '.'.join(map(str, python_version[:3]))\n                    )\n                )\n\n    def verify_required_python_runtime(s):\n        @functools.wraps(s)\n        def sw(**attrs):\n            try:\n                validate_required_python_or_fail(attrs.get('python_requires'))\n            except RuntimeError as re:\n                sys.exit('{} {!s}'.format(attrs['name'], re))\n            return s(**attrs)\n\n        return sw\n\n    setuptools.setup = ignore_unknown_options(setuptools.setup)\n    setuptools.setup = verify_required_python_runtime(setuptools.setup)\n\n    try:\n        from configparser import ConfigParser, NoSectionError\n    except ImportError:\n        from ConfigParser import ConfigParser, NoSectionError\n\n        ConfigParser.read_file = ConfigParser.readfp\n\n    def maybe_read_files(d):\n        \"\"\"Read files if the string starts with `file:` marker.\"\"\"\n        FILE_FUNC_MARKER = 'file:'\n\n        d = d.strip()\n        if not d.startswith(FILE_FUNC_MARKER):\n            return d\n        descs = []\n        for fname in map(str.strip, str(d[len(FILE_FUNC_MARKER) :]).split(',')):\n            with io.open(fname, encoding='utf-8') as f:\n                descs.append(f.read())\n        return ''.join(descs)\n\n    def cfg_val_to_list(v):\n        \"\"\"Turn config val to list and filter out empty lines.\"\"\"\n        return list(filter(bool, map(str.strip, str(v).strip().splitlines())))\n\n    def cfg_val_to_dict(v):\n        \"\"\"Turn config val to dict and filter out empty lines.\"\"\"\n        return dict(\n            map(\n                lambda l: list(map(str.strip, l.split('=', 1))),\n                filter(bool, map(str.strip, str(v).strip().splitlines())),\n            )\n        )\n\n    def cfg_val_to_primitive(v):\n        \"\"\"Parse primitive config val to appropriate data type.\"\"\"\n        return json.loads(v.strip().lower())\n\n    def read_configuration(filepath):\n        \"\"\"Read metadata and options from setup.cfg located at filepath.\"\"\"\n        cfg = ConfigParser()\n        with io.open(filepath, encoding='utf-8') as f:\n            cfg.read_file(f)\n\n        md = dict(cfg.items('metadata'))\n        for list_key in 'classifiers', 'keywords', 'project_urls':\n            try:\n                md[list_key] = cfg_val_to_list(md[list_key])\n            except KeyError:\n                pass\n        try:\n            md['long_description'] = maybe_read_files(md['long_description'])\n        except KeyError:\n            pass\n        opt = dict(cfg.items('options'))\n        for list_key in 'include_package_data', 'use_scm_version', 'zip_safe':\n            try:\n                opt[list_key] = cfg_val_to_primitive(opt[list_key])\n            except KeyError:\n                pass\n        for list_key in 'scripts', 'install_requires', 'setup_requires':\n            try:\n                opt[list_key] = cfg_val_to_list(opt[list_key])\n            except KeyError:\n                pass\n        try:\n            opt['package_dir'] = cfg_val_to_dict(opt['package_dir'])\n        except KeyError:\n            pass\n        try:\n            opt_package_data = dict(cfg.items('options.package_data'))\n            if not opt_package_data.get('', '').strip():\n                opt_package_data[''] = opt_package_data['*']\n                del opt_package_data['*']\n        except (KeyError, NoSectionError):\n            opt_package_data = {}\n        try:\n            opt_extras_require = dict(cfg.items('options.extras_require'))\n            opt['extras_require'] = {}\n            for k, v in opt_extras_require.items():\n                opt['extras_require'][k] = cfg_val_to_list(v)\n        except NoSectionError:\n            pass\n        opt['package_data'] = {}\n        for k, v in opt_package_data.items():\n            opt['package_data'][k] = cfg_val_to_list(v)\n        try:\n            opt_exclude_package_data = dict(cfg.items('options.exclude_package_data'))\n            if (\n                not opt_exclude_package_data.get('', '').strip()\n                and '*' in opt_exclude_package_data\n            ):\n                opt_exclude_package_data[''] = opt_exclude_package_data['*']\n                del opt_exclude_package_data['*']\n        except NoSectionError:\n            pass\n        else:\n            opt['exclude_package_data'] = {}\n            for k, v in opt_exclude_package_data.items():\n                opt['exclude_package_data'][k] = cfg_val_to_list(v)\n        cur_pkgs = opt.get('packages', '').strip()\n        if '\\n' in cur_pkgs:\n            opt['packages'] = cfg_val_to_list(opt['packages'])\n        elif cur_pkgs.startswith('find:'):\n            opt_packages_find = stringify_dict_contents(\n                dict(cfg.items('options.packages.find'))\n            )\n            opt['packages'] = setuptools.find_packages(**opt_packages_find)\n        return {'metadata': md, 'options': opt}\n\n\ndef cut_local_version_on_upload(version):\n    \"\"\"Generate a PEP440 local version if uploading to PyPI.\"\"\"\n    import os\n    import setuptools_scm.version  # only present during setup time\n\n    IS_PYPI_UPLOAD = os.getenv('PYPI_UPLOAD') == 'true'  # set in tox.ini\n    return (\n        ''\n        if IS_PYPI_UPLOAD\n        else setuptools_scm.version.get_local_node_and_date(version)\n    )\n\n\nif HAS_DIST_INFO_CMD:\n\n    class patched_dist_info(setuptools.command.dist_info.dist_info):\n        def run(self):\n            self.egg_base = str_if_nested_or_str(self.egg_base)\n            return setuptools.command.dist_info.dist_info.run(self)\n\n\ndeclarative_setup_params = read_configuration('setup.cfg')\n\"\"\"Declarative metadata and options as read by setuptools.\"\"\"\n\n\nsetup_params = {}\n\"\"\"Explicit metadata for passing into setuptools.setup() call.\"\"\"\n\nsetup_params = dict(setup_params, **declarative_setup_params['metadata'])\nsetup_params = dict(setup_params, **declarative_setup_params['options'])\n\nif HAS_DIST_INFO_CMD:\n    setup_params['cmdclass'] = {'dist_info': patched_dist_info}\n\nsetup_params['use_scm_version'] = {'local_scheme': cut_local_version_on_upload}\n\n# Patch incorrectly decoded package_dir option\n# ``egg_info`` demands native strings failing with unicode under Python 2\n# Ref https://github.com/pypa/setuptools/issues/1136\nsetup_params = stringify_dict_contents(setup_params)\n\n\n__name__ == '__main__' and setuptools.setup(**setup_params)\n", "path": "setup.py"}], "after_files": [{"content": "#! /usr/bin/env python\n#  Copyright (c) 2019 Red Hat, Inc.\n#  Copyright (c) 2015-2018 Cisco Systems, Inc.\n#\n#  Permission is hereby granted, free of charge, to any person obtaining a copy\n#  of this software and associated documentation files (the \"Software\"), to\n#  deal in the Software without restriction, including without limitation the\n#  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n#  sell copies of the Software, and to permit persons to whom the Software is\n#  furnished to do so, subject to the following conditions:\n#\n#  The above copyright notice and this permission notice shall be included in\n#  all copies or substantial portions of the Software.\n#\n#  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n#  DEALINGS IN THE SOFTWARE.\n\"\"\"Molecule distribution package setuptools installer.\"\"\"\n\nimport setuptools\n\nHAS_DIST_INFO_CMD = False\ntry:\n    import setuptools.command.dist_info\n\n    HAS_DIST_INFO_CMD = True\nexcept ImportError:\n    \"\"\"Setuptools version is too old.\"\"\"\n\n\nALL_STRING_TYPES = tuple(map(type, ('', b'', u'')))\nMIN_NATIVE_SETUPTOOLS_VERSION = 34, 4\n\"\"\"Minimal setuptools having good read_configuration implementation.\"\"\"\n\n# Patch version can be a non integer value, like 'post20190705'\nRUNTIME_SETUPTOOLS_VERSION = tuple(map(int, setuptools.__version__.split('.')[:2]))\n\"\"\"Setuptools imported now.\"\"\"\n\nREAD_CONFIG_SHIM_NEEDED = RUNTIME_SETUPTOOLS_VERSION < MIN_NATIVE_SETUPTOOLS_VERSION\n\n\ndef str_if_nested_or_str(s):\n    \"\"\"Turn input into a native string if possible.\"\"\"\n    if isinstance(s, ALL_STRING_TYPES):\n        return str(s)\n    if isinstance(s, (list, tuple)):\n        return type(s)(map(str_if_nested_or_str, s))\n    if isinstance(s, (dict,)):\n        return stringify_dict_contents(s)\n    return s\n\n\ndef stringify_dict_contents(dct):\n    \"\"\"Turn dict keys and values into native strings.\"\"\"\n    return {str_if_nested_or_str(k): str_if_nested_or_str(v) for k, v in dct.items()}\n\n\nif not READ_CONFIG_SHIM_NEEDED:\n    from setuptools.config import read_configuration, ConfigOptionsHandler\n    import setuptools.config\n    import setuptools.dist\n\n    # Set default value for 'use_scm_version'\n    setattr(setuptools.dist.Distribution, 'use_scm_version', False)\n\n    # Attach bool parser to 'use_scm_version' option\n    class ShimConfigOptionsHandler(ConfigOptionsHandler):\n        \"\"\"Extension class for ConfigOptionsHandler.\"\"\"\n\n        @property\n        def parsers(self):\n            \"\"\"Return an option mapping with default data type parsers.\"\"\"\n            _orig_parsers = super(ShimConfigOptionsHandler, self).parsers\n            return dict(use_scm_version=self._parse_bool, **_orig_parsers)\n\n        def parse_section_packages__find(self, section_options):\n            find_kwargs = super(\n                ShimConfigOptionsHandler, self\n            ).parse_section_packages__find(section_options)\n            return stringify_dict_contents(find_kwargs)\n\n    setuptools.config.ConfigOptionsHandler = ShimConfigOptionsHandler\nelse:\n    \"\"\"This is a shim for setuptools<required.\"\"\"\n    import functools\n    import io\n    import json\n    import sys\n    import warnings\n\n    try:\n        import setuptools.config\n\n        def filter_out_unknown_section(i):\n            def chi(self, *args, **kwargs):\n                i(self, *args, **kwargs)\n                self.sections = {\n                    s: v for s, v in self.sections.items() if s != 'packages.find'\n                }\n\n            return chi\n\n        setuptools.config.ConfigHandler.__init__ = filter_out_unknown_section(\n            setuptools.config.ConfigHandler.__init__\n        )\n    except ImportError:\n        pass\n\n    def ignore_unknown_options(s):\n        @functools.wraps(s)\n        def sw(**attrs):\n            try:\n                ignore_warning_regex = (\n                    r\"Unknown distribution option: \"\n                    r\"'(license_file|project_urls|python_requires)'\"\n                )\n                warnings.filterwarnings(\n                    'ignore',\n                    message=ignore_warning_regex,\n                    category=UserWarning,\n                    module='distutils.dist',\n                )\n                return s(**attrs)\n            finally:\n                warnings.resetwarnings()\n\n        return sw\n\n    def parse_predicates(python_requires):\n        import itertools\n        import operator\n\n        sorted_operators_map = tuple(\n            sorted(\n                {\n                    '>': operator.gt,\n                    '<': operator.lt,\n                    '>=': operator.ge,\n                    '<=': operator.le,\n                    '==': operator.eq,\n                    '!=': operator.ne,\n                    '': operator.eq,\n                }.items(),\n                key=lambda i: len(i[0]),\n                reverse=True,\n            )\n        )\n\n        def is_decimal(s):\n            return type(u'')(s).isdecimal()\n\n        conditions = map(str.strip, python_requires.split(','))\n        for c in conditions:\n            for op_sign, op_func in sorted_operators_map:\n                if not c.startswith(op_sign):\n                    continue\n                raw_ver = itertools.takewhile(\n                    is_decimal, c[len(op_sign) :].strip().split('.')\n                )\n                ver = tuple(map(int, raw_ver))\n                yield op_func, ver\n                break\n\n    def validate_required_python_or_fail(python_requires=None):\n        if python_requires is None:\n            return\n\n        python_version = sys.version_info\n        preds = parse_predicates(python_requires)\n        for op, v in preds:\n            py_ver_slug = python_version[: max(len(v), 3)]\n            condition_matches = op(py_ver_slug, v)\n            if not condition_matches:\n                raise RuntimeError(\n                    \"requires Python '{}' but the running Python is {}\".format(\n                        python_requires, '.'.join(map(str, python_version[:3]))\n                    )\n                )\n\n    def verify_required_python_runtime(s):\n        @functools.wraps(s)\n        def sw(**attrs):\n            try:\n                validate_required_python_or_fail(attrs.get('python_requires'))\n            except RuntimeError as re:\n                sys.exit('{} {!s}'.format(attrs['name'], re))\n            return s(**attrs)\n\n        return sw\n\n    setuptools.setup = ignore_unknown_options(setuptools.setup)\n    setuptools.setup = verify_required_python_runtime(setuptools.setup)\n\n    try:\n        from configparser import ConfigParser, NoSectionError\n    except ImportError:\n        from ConfigParser import ConfigParser, NoSectionError\n\n        ConfigParser.read_file = ConfigParser.readfp\n\n    def maybe_read_files(d):\n        \"\"\"Read files if the string starts with `file:` marker.\"\"\"\n        FILE_FUNC_MARKER = 'file:'\n\n        d = d.strip()\n        if not d.startswith(FILE_FUNC_MARKER):\n            return d\n        descs = []\n        for fname in map(str.strip, str(d[len(FILE_FUNC_MARKER) :]).split(',')):\n            with io.open(fname, encoding='utf-8') as f:\n                descs.append(f.read())\n        return ''.join(descs)\n\n    def cfg_val_to_list(v):\n        \"\"\"Turn config val to list and filter out empty lines.\"\"\"\n        return list(filter(bool, map(str.strip, str(v).strip().splitlines())))\n\n    def cfg_val_to_dict(v):\n        \"\"\"Turn config val to dict and filter out empty lines.\"\"\"\n        return dict(\n            map(\n                lambda l: list(map(str.strip, l.split('=', 1))),\n                filter(bool, map(str.strip, str(v).strip().splitlines())),\n            )\n        )\n\n    def cfg_val_to_primitive(v):\n        \"\"\"Parse primitive config val to appropriate data type.\"\"\"\n        return json.loads(v.strip().lower())\n\n    def read_configuration(filepath):\n        \"\"\"Read metadata and options from setup.cfg located at filepath.\"\"\"\n        cfg = ConfigParser()\n        with io.open(filepath, encoding='utf-8') as f:\n            cfg.read_file(f)\n\n        md = dict(cfg.items('metadata'))\n        for list_key in 'classifiers', 'keywords', 'project_urls':\n            try:\n                md[list_key] = cfg_val_to_list(md[list_key])\n            except KeyError:\n                pass\n        try:\n            md['long_description'] = maybe_read_files(md['long_description'])\n        except KeyError:\n            pass\n        opt = dict(cfg.items('options'))\n        for list_key in 'include_package_data', 'use_scm_version', 'zip_safe':\n            try:\n                opt[list_key] = cfg_val_to_primitive(opt[list_key])\n            except KeyError:\n                pass\n        for list_key in 'scripts', 'install_requires', 'setup_requires':\n            try:\n                opt[list_key] = cfg_val_to_list(opt[list_key])\n            except KeyError:\n                pass\n        try:\n            opt['package_dir'] = cfg_val_to_dict(opt['package_dir'])\n        except KeyError:\n            pass\n        try:\n            opt_package_data = dict(cfg.items('options.package_data'))\n            if not opt_package_data.get('', '').strip():\n                opt_package_data[''] = opt_package_data['*']\n                del opt_package_data['*']\n        except (KeyError, NoSectionError):\n            opt_package_data = {}\n        try:\n            opt_extras_require = dict(cfg.items('options.extras_require'))\n            opt['extras_require'] = {}\n            for k, v in opt_extras_require.items():\n                opt['extras_require'][k] = cfg_val_to_list(v)\n        except NoSectionError:\n            pass\n        opt['package_data'] = {}\n        for k, v in opt_package_data.items():\n            opt['package_data'][k] = cfg_val_to_list(v)\n        try:\n            opt_exclude_package_data = dict(cfg.items('options.exclude_package_data'))\n            if (\n                not opt_exclude_package_data.get('', '').strip()\n                and '*' in opt_exclude_package_data\n            ):\n                opt_exclude_package_data[''] = opt_exclude_package_data['*']\n                del opt_exclude_package_data['*']\n        except NoSectionError:\n            pass\n        else:\n            opt['exclude_package_data'] = {}\n            for k, v in opt_exclude_package_data.items():\n                opt['exclude_package_data'][k] = cfg_val_to_list(v)\n        cur_pkgs = opt.get('packages', '').strip()\n        if '\\n' in cur_pkgs:\n            opt['packages'] = cfg_val_to_list(opt['packages'])\n        elif cur_pkgs.startswith('find:'):\n            opt_packages_find = stringify_dict_contents(\n                dict(cfg.items('options.packages.find'))\n            )\n            opt['packages'] = setuptools.find_packages(**opt_packages_find)\n        return {'metadata': md, 'options': opt}\n\n\ndef cut_local_version_on_upload(version):\n    \"\"\"Generate a PEP440 local version if uploading to PyPI.\"\"\"\n    import os\n    import setuptools_scm.version  # only present during setup time\n\n    IS_PYPI_UPLOAD = os.getenv('PYPI_UPLOAD') == 'true'  # set in tox.ini\n    return (\n        ''\n        if IS_PYPI_UPLOAD\n        else setuptools_scm.version.get_local_node_and_date(version)\n    )\n\n\nif HAS_DIST_INFO_CMD:\n\n    class patched_dist_info(setuptools.command.dist_info.dist_info):\n        def run(self):\n            self.egg_base = str_if_nested_or_str(self.egg_base)\n            return setuptools.command.dist_info.dist_info.run(self)\n\n\ndeclarative_setup_params = read_configuration('setup.cfg')\n\"\"\"Declarative metadata and options as read by setuptools.\"\"\"\n\n\nsetup_params = {}\n\"\"\"Explicit metadata for passing into setuptools.setup() call.\"\"\"\n\nsetup_params = dict(setup_params, **declarative_setup_params['metadata'])\nsetup_params = dict(setup_params, **declarative_setup_params['options'])\n\nif HAS_DIST_INFO_CMD:\n    setup_params['cmdclass'] = {'dist_info': patched_dist_info}\n\nsetup_params['use_scm_version'] = {'local_scheme': cut_local_version_on_upload}\n\n# Patch incorrectly decoded package_dir option\n# ``egg_info`` demands native strings failing with unicode under Python 2\n# Ref https://github.com/pypa/setuptools/issues/1136\nsetup_params = stringify_dict_contents(setup_params)\n\n\n__name__ == '__main__' and setuptools.setup(**setup_params)\n", "path": "setup.py"}]}