aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn T. Wodder II <git@varonathe.org>2019-04-27 19:21:50 +0000
committerJohn T. Wodder II <git@varonathe.org>2020-05-15 18:49:43 +0000
commit6de971f158553c47ce11e7be9d38d268e0398193 (patch)
treeb827f272f5f4aa0daf4d9b2a5af0c09b28b55de0
parent9887350aa500b86feea0859eebe057d56a060d67 (diff)
downloadexternal_python_setuptools-6de971f158553c47ce11e7be9d38d268e0398193.tar.gz
external_python_setuptools-6de971f158553c47ce11e7be9d38d268e0398193.tar.bz2
external_python_setuptools-6de971f158553c47ce11e7be9d38d268e0398193.zip
Implement a "literal_attr:" config directive
-rw-r--r--setuptools/config.py62
-rw-r--r--setuptools/tests/test_config.py64
2 files changed, 117 insertions, 9 deletions
diff --git a/setuptools/config.py b/setuptools/config.py
index 9b9a0c45..d1456cac 100644
--- a/setuptools/config.py
+++ b/setuptools/config.py
@@ -1,4 +1,5 @@
from __future__ import absolute_import, unicode_literals
+import ast
import io
import os
import sys
@@ -316,15 +317,22 @@ class ConfigHandler:
Examples:
attr: package.attr
attr: package.module.attr
+ literal_attr: package.attr
+ literal_attr: package.module.attr
:param str value:
:rtype: str
"""
attr_directive = 'attr:'
- if not value.startswith(attr_directive):
+ literal_attr_directive = 'literal_attr:'
+ if value.startswith(attr_directive):
+ directive = attr_directive
+ elif value.startswith(literal_attr_directive):
+ directive = literal_attr_directive
+ else:
return value
- attrs_path = value.replace(attr_directive, '').strip().split('.')
+ attrs_path = value.replace(directive, '').strip().split('.')
attr_name = attrs_path.pop()
module_name = '.'.join(attrs_path)
@@ -344,13 +352,49 @@ class ConfigHandler:
elif '' in package_dir:
# A custom parent directory was specified for all root modules
parent_path = os.path.join(os.getcwd(), package_dir[''])
- sys.path.insert(0, parent_path)
- try:
- module = import_module(module_name)
- value = getattr(module, attr_name)
-
- finally:
- sys.path = sys.path[1:]
+ if directive == attr_directive:
+ sys.path.insert(0, parent_path)
+ try:
+ module = import_module(module_name)
+ value = getattr(module, attr_name)
+ finally:
+ sys.path = sys.path[1:]
+
+ elif directive == literal_attr_directive:
+ fpath = os.path.join(parent_path, *module_name.split('.'))
+ if os.path.exists(fpath + '.py'):
+ fpath += '.py'
+ elif os.path.isdir(fpath):
+ fpath = os.path.join(fpath, '__init__.py')
+ else:
+ raise DistutilsOptionError(
+ 'Could not find module ' + module_name
+ )
+ with open(fpath, 'rb') as fp:
+ src = fp.read()
+ found = False
+ top_level = ast.parse(src)
+ for statement in top_level.body:
+ if isinstance(statement, ast.Assign):
+ for target in statement.targets:
+ if isinstance(target, ast.Name) \
+ and target.id == attr_name:
+ value = ast.literal_eval(statement.value)
+ found = True
+ elif isinstance(target, ast.Tuple) \
+ and any(isinstance(t, ast.Name) and t.id==attr_name
+ for t in target.elts):
+ stmnt_value = ast.literal_eval(statement.value)
+ for t,v in zip(target.elts, stmnt_value):
+ if isinstance(t, ast.Name) \
+ and t.id == attr_name:
+ value = v
+ found = True
+ if not found:
+ raise DistutilsOptionError(
+ 'No literal assignment to {!r} found in file'
+ .format(attr_name)
+ )
return value
diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py
index 2fa0b374..03e6916b 100644
--- a/setuptools/tests/test_config.py
+++ b/setuptools/tests/test_config.py
@@ -300,6 +300,37 @@ class TestMetadata:
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '2016.11.26'
+ def test_literal_version(self, tmpdir):
+
+ _, config = fake_env(
+ tmpdir,
+ '[metadata]\n'
+ 'version = literal_attr: fake_package.VERSION\n'
+ )
+ with get_dist(tmpdir) as dist:
+ assert dist.metadata.version == '1.2.3'
+
+ config.write(
+ '[metadata]\n'
+ 'version = literal_attr: fake_package.VERSION_MAJOR\n'
+ )
+ with get_dist(tmpdir) as dist:
+ assert dist.metadata.version == '1'
+
+ subpack = tmpdir.join('fake_package').mkdir('subpackage')
+ subpack.join('__init__.py').write('')
+ subpack.join('submodule.py').write(
+ 'import third_party_module\n'
+ 'VERSION = (2016, 11, 26)'
+ )
+
+ config.write(
+ '[metadata]\n'
+ 'version = attr: fake_package.subpackage.submodule.VERSION\n'
+ )
+ with get_dist(tmpdir) as dist:
+ assert dist.metadata.version == '2016.11.26'
+
def test_version_file(self, tmpdir):
_, config = fake_env(
@@ -332,6 +363,17 @@ class TestMetadata:
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '1.2.3'
+ config.write(
+ '[metadata]\n'
+ 'version = literal_attr: fake_package_simple.VERSION\n'
+ '[options]\n'
+ 'package_dir =\n'
+ ' = src\n'
+ )
+
+ with get_dist(tmpdir) as dist:
+ assert dist.metadata.version == '1.2.3'
+
def test_version_with_package_dir_rename(self, tmpdir):
_, config = fake_env(
@@ -347,6 +389,17 @@ class TestMetadata:
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '1.2.3'
+ config.write(
+ '[metadata]\n'
+ 'version = literal_attr: fake_package_rename.VERSION\n'
+ '[options]\n'
+ 'package_dir =\n'
+ ' fake_package_rename = fake_dir\n'
+ )
+
+ with get_dist(tmpdir) as dist:
+ assert dist.metadata.version == '1.2.3'
+
def test_version_with_package_dir_complex(self, tmpdir):
_, config = fake_env(
@@ -362,6 +415,17 @@ class TestMetadata:
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '1.2.3'
+ config.write(
+ '[metadata]\n'
+ 'version = literal_attr: fake_package_complex.VERSION\n'
+ '[options]\n'
+ 'package_dir =\n'
+ ' fake_package_complex = src/fake_dir\n'
+ )
+
+ with get_dist(tmpdir) as dist:
+ assert dist.metadata.version == '1.2.3'
+
def test_unknown_meta_item(self, tmpdir):
fake_env(