Skip to content

Commit 82f376d

Browse files
authored
Merge pull request #92 from jayvdb/setup-env-markers
✨ dependency environment markers
2 parents 344fad6 + 9df2682 commit 82f376d

File tree

1 file changed

+79
-3
lines changed

1 file changed

+79
-3
lines changed

templates/setup.py.jj2

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@
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
1632
import platform
1733
import sys
1834
from shutil import rmtree
35+
1936
{% if external_module_library %}
2037
from distutils.core import setup, Extension
2138
{% else %}
22-
2339
from 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%}
2754
PY2 = sys.version_info[0] == 2
2855
PY26 = 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: %}
217249
EXTRAS_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

334410
if __name__ == "__main__":
335411
setup(

0 commit comments

Comments
 (0)