|
18 | 18 |
|
19 | 19 | from __future__ import annotations |
20 | 20 |
|
21 | | -# Standard Library |
22 | | -import ast |
23 | | -import os.path |
24 | | - |
25 | 21 | # External Dependencies |
26 | 22 | import setuptools |
27 | 23 |
|
28 | 24 | PACKAGE_NAME = "exec_helpers" |
29 | 25 |
|
30 | | -with open(os.path.join(os.path.dirname(__file__), PACKAGE_NAME, "__init__.py"), encoding="utf-8") as f: |
31 | | - SOURCE = f.read() |
32 | | - |
33 | | - |
34 | | -# noinspection PyUnresolvedReferences |
35 | | -def get_simple_vars_from_src( |
36 | | - src: str, |
37 | | -) -> dict[str, str | bytes | int | float | complex | list | set | dict | tuple | None | bool | Ellipsis]: |
38 | | - """Get simple (string/number/boolean and None) assigned values from source. |
39 | | -
|
40 | | - :param src: Source code |
41 | | - :type src: str |
42 | | - :return: OrderedDict with keys, values = variable names, values |
43 | | - :rtype: dict[ |
44 | | - str, |
45 | | - str | bytes | int | float | complex | list | set | dict | tuple | None | bool | Ellipsis |
46 | | - ] |
47 | | -
|
48 | | - Limitations: Only defined from scratch variables. |
49 | | - Not supported by design: |
50 | | - * Imports |
51 | | - * Executable code, including string formatting and comprehensions. |
52 | | -
|
53 | | - Examples: |
54 | | - >>> string_sample = "a = '1'" |
55 | | - >>> get_simple_vars_from_src(string_sample) |
56 | | - {'a': '1'} |
57 | | -
|
58 | | - >>> int_sample = "b = 1" |
59 | | - >>> get_simple_vars_from_src(int_sample) |
60 | | - {'b': 1} |
61 | | -
|
62 | | - >>> list_sample = "c = [u'1', b'1', 1, 1.0, 1j, None]" |
63 | | - >>> result = get_simple_vars_from_src(list_sample) |
64 | | - >>> result == {'c': [u'1', b'1', 1, 1.0, 1j, None]} |
65 | | - True |
66 | | -
|
67 | | - >>> iterable_sample = "d = ([1], {1: 1}, {1})" |
68 | | - >>> get_simple_vars_from_src(iterable_sample) |
69 | | - {'d': ([1], {1: 1}, {1})} |
70 | | -
|
71 | | - >>> multiple_assign = "e = f = g = 1" |
72 | | - >>> get_simple_vars_from_src(multiple_assign) |
73 | | - {'e': 1, 'f': 1, 'g': 1} |
74 | | - """ |
75 | | - ast_data = (ast.Constant, ast.List, ast.Set, ast.Dict, ast.Tuple) |
76 | | - |
77 | | - tree = ast.parse(src) |
78 | | - |
79 | | - result = {} |
80 | | - |
81 | | - for node in ast.iter_child_nodes(tree): |
82 | | - if not isinstance(node, ast.Assign) or not isinstance(node.value, ast_data): # We parse assigns only |
83 | | - continue |
84 | | - try: |
85 | | - value = ast.literal_eval(node.value) |
86 | | - except ValueError: # noqa: PERF203 |
87 | | - continue |
88 | | - for tgt in node.targets: |
89 | | - if isinstance(tgt, ast.Name) and isinstance(tgt.ctx, ast.Store): |
90 | | - result[tgt.id] = value |
91 | | - return result |
92 | | - |
93 | | - |
94 | | -VARIABLES = get_simple_vars_from_src(SOURCE) |
95 | | - |
96 | 26 | setuptools.setup( |
97 | 27 | name=PACKAGE_NAME.replace("_", "-"), |
98 | | - url=VARIABLES["__url__"], |
99 | | - python_requires=">=3.8.0", |
| 28 | + url="https://github.com/python-useful-helpers/exec-helpers", |
| 29 | + python_requires=">=3.7.0", |
100 | 30 | # While setuptools cannot deal with pre-installed incompatible versions, |
101 | 31 | # setting a lower bound is not harmful - it makes error messages cleaner. DO |
102 | 32 | # NOT set an upper bound on setuptools, as that will lead to uninstallable |
|
0 commit comments