77{% set min_python_version = min_python_version|default('2.6') %}
88{% set min_python_version = min_python_version.split('.', 2) %}
99
10+ {# marker_dependencies is implemented as a defaultdict(list)
11+ See https://gsnedders.github.io/python-marker-test/results.html
12+ for acceptable markers ("without parser" columns) #}
13+ {% set marker_dependencies = {} %}
14+ {% for dependency in dependencies: %}
15+ {% if ';' in dependency %}
16+ {% set dependency, marker = dependency.split(';') %}
17+ {% set dependency, marker = dependency.strip(), marker.strip() %}
18+ {% set marker = marker.replace('"', "'") %}
19+ {% if marker in marker_dependencies %}
20+ {% set _ = marker_dependencies[marker].append(dependency) %}
21+ {% else %}
22+ {% set _ = marker_dependencies.__setitem__(marker, [dependency]) %}
23+ {% endif %}
24+ {% endif %}
25+ {% endfor %}
1026{% block header %}
1127# Template by pypi-mobans
1228{% endblock %}
@@ -16,13 +32,24 @@ import os
1632import platform
1733import sys
1834from shutil import rmtree
35+
1936{% if external_module_library %}
2037from distutils.core import setup, Extension
2138{% else %}
22-
2339from setuptools import Command, find_packages, setup
24-
2540{%endif%}
41+ {% if marker_dependencies and setup_use_markers and setup_use_markers_fix %}
42+ from setuptools import __version__ as setuptools_version
43+ from pkg_resources import parse_version
44+
45+ import pkg_resources
46+
47+ try:
48+ import _markerlib.markers
49+ except ImportError:
50+ _markerlib = None
51+ {% endif %}
52+
2653{%block compat_block%}
2754PY2 = sys.version_info[0] == 2
2855PY26 = PY2 and sys.version_info[1] < 7
@@ -188,7 +215,7 @@ SETUP_COMMANDS = {}
188215{% endblock %}
189216
190217{% for dependency in dependencies: %}
191- {% if ';' in dependency: %}
218+ {% if not setup_use_markers and ';' in dependency: %}
192219{{handle_complex_dependency(dependency)}}
193220 {% endif %}
194221{% endfor %}
@@ -212,6 +239,11 @@ EXTRAS_REQUIRE = {
212239 "{{key}}": {{value}},
213240 {% endfor %}
214241 {% endfor %}
242+ {% if setup_use_markers %}
243+ {% for marker, dependencies in marker_dependencies.items(): %}
244+ ":{{marker}}": ["{{dependencies | list|join('", "')}}"],
245+ {% endfor %}
246+ {% endif %}
215247}
216248{% else: %}
217249EXTRAS_REQUIRE = {}
@@ -330,6 +362,50 @@ def filter_out_test_code(file_handle):
330362 else:
331363 yield line
332364
365+ {% if marker_dependencies and setup_use_markers and setup_use_markers_fix %}
366+
367+ # _markerlib.default_environment() obtains its data from _VARS
368+ # and wraps it in another dict, but _markerlib_evaluate writes
369+ # to the dict while it is iterating the keys, causing an error
370+ # on Python 3 only.
371+ # Replace _markerlib.default_environment to return a custom dict
372+ # that has all the necessary markers, and ignores any writes.
373+
374+ class Python3MarkerDict(dict):
375+
376+ def __setitem__(self, key, value):
377+ pass
378+
379+ def pop(self, i=-1):
380+ return self[i]
381+
382+
383+ if _markerlib and sys.version_info[0] == 3:
384+ env = _markerlib.markers._VARS
385+ for key in list(env.keys()):
386+ new_key = key.replace(".", "_")
387+ if new_key != key:
388+ env[new_key] = env[key]
389+
390+ _markerlib.markers._VARS = Python3MarkerDict(env)
391+
392+ def default_environment():
393+ return _markerlib.markers._VARS
394+
395+ _markerlib.default_environment = default_environment
396+
397+ # Avoid the very buggy pkg_resources.parser, which does not consistently
398+ # recognise the markers needed by this setup.py
399+ # See https://github.com/pypa/packaging/issues/72 for details
400+ # Change this to setuptools 20.10.0 to support all markers.
401+ if pkg_resources:
402+ if parse_version(setuptools_version) < parse_version("18.5"):
403+ MarkerEvaluation = pkg_resources.MarkerEvaluation
404+
405+ del pkg_resources.parser
406+ pkg_resources.evaluate_marker = MarkerEvaluation._markerlib_evaluate
407+ MarkerEvaluation.evaluate_marker = MarkerEvaluation._markerlib_evaluate
408+ {% endif %}
333409
334410if __name__ == "__main__":
335411 setup(
0 commit comments