mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-01 14:07:48 +00:00
first commit
This commit is contained in:
@ -0,0 +1 @@
|
||||
pip
|
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Alex Hall
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
229
.venv/Lib/site-packages/pure_eval-0.2.2.dist-info/METADATA
Normal file
229
.venv/Lib/site-packages/pure_eval-0.2.2.dist-info/METADATA
Normal file
@ -0,0 +1,229 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: pure-eval
|
||||
Version: 0.2.2
|
||||
Summary: Safely evaluate AST nodes without side effects
|
||||
Home-page: http://github.com/alexmojaki/pure_eval
|
||||
Author: Alex Hall
|
||||
Author-email: alex.mojaki@gmail.com
|
||||
License: MIT
|
||||
Platform: UNKNOWN
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.6
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Description-Content-Type: text/markdown
|
||||
License-File: LICENSE.txt
|
||||
Provides-Extra: tests
|
||||
Requires-Dist: pytest ; extra == 'tests'
|
||||
|
||||
# `pure_eval`
|
||||
|
||||
[](https://travis-ci.org/alexmojaki/pure_eval) [](https://coveralls.io/github/alexmojaki/pure_eval?branch=master) [](https://pypi.python.org/pypi/pure_eval)
|
||||
|
||||
This is a Python package that lets you safely evaluate certain AST nodes without triggering arbitrary code that may have unwanted side effects.
|
||||
|
||||
It can be installed from PyPI:
|
||||
|
||||
pip install pure_eval
|
||||
|
||||
To demonstrate usage, suppose we have an object defined as follows:
|
||||
|
||||
```python
|
||||
class Rectangle:
|
||||
def __init__(self, width, height):
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
print("Calculating area...")
|
||||
return self.width * self.height
|
||||
|
||||
|
||||
rect = Rectangle(3, 5)
|
||||
```
|
||||
|
||||
Given the `rect` object, we want to evaluate whatever expressions we can in this source code:
|
||||
|
||||
```python
|
||||
source = "(rect.width, rect.height, rect.area)"
|
||||
```
|
||||
|
||||
This library works with the AST, so let's parse the source code and peek inside:
|
||||
|
||||
```python
|
||||
import ast
|
||||
|
||||
tree = ast.parse(source)
|
||||
the_tuple = tree.body[0].value
|
||||
for node in the_tuple.elts:
|
||||
print(ast.dump(node))
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```python
|
||||
Attribute(value=Name(id='rect', ctx=Load()), attr='width', ctx=Load())
|
||||
Attribute(value=Name(id='rect', ctx=Load()), attr='height', ctx=Load())
|
||||
Attribute(value=Name(id='rect', ctx=Load()), attr='area', ctx=Load())
|
||||
```
|
||||
|
||||
Now to actually use the library. First construct an Evaluator:
|
||||
|
||||
```python
|
||||
from pure_eval import Evaluator
|
||||
|
||||
evaluator = Evaluator({"rect": rect})
|
||||
```
|
||||
|
||||
The argument to `Evaluator` should be a mapping from variable names to their values. Or if you have access to the stack frame where `rect` is defined, you can instead use:
|
||||
|
||||
```python
|
||||
evaluator = Evaluator.from_frame(frame)
|
||||
```
|
||||
|
||||
Now to evaluate some nodes, using `evaluator[node]`:
|
||||
|
||||
```python
|
||||
print("rect.width:", evaluator[the_tuple.elts[0]])
|
||||
print("rect:", evaluator[the_tuple.elts[0].value])
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
rect.width: 3
|
||||
rect: <__main__.Rectangle object at 0x105b0dd30>
|
||||
```
|
||||
|
||||
OK, but you could have done the same thing with `eval`. The useful part is that it will refuse to evaluate the property `rect.area` because that would trigger unknown code. If we try, it'll raise a `CannotEval` exception.
|
||||
|
||||
```python
|
||||
from pure_eval import CannotEval
|
||||
|
||||
try:
|
||||
print("rect.area:", evaluator[the_tuple.elts[2]]) # fails
|
||||
except CannotEval as e:
|
||||
print(e) # prints CannotEval
|
||||
```
|
||||
|
||||
To find all the expressions that can be evaluated in a tree:
|
||||
|
||||
```python
|
||||
for node, value in evaluator.find_expressions(tree):
|
||||
print(ast.dump(node), value)
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```python
|
||||
Attribute(value=Name(id='rect', ctx=Load()), attr='width', ctx=Load()) 3
|
||||
Attribute(value=Name(id='rect', ctx=Load()), attr='height', ctx=Load()) 5
|
||||
Name(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30>
|
||||
Name(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30>
|
||||
Name(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30>
|
||||
```
|
||||
|
||||
Note that this includes `rect` three times, once for each appearance in the source code. Since all these nodes are equivalent, we can group them together:
|
||||
|
||||
```python
|
||||
from pure_eval import group_expressions
|
||||
|
||||
for nodes, values in group_expressions(evaluator.find_expressions(tree)):
|
||||
print(len(nodes), "nodes with value:", values)
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
1 nodes with value: 3
|
||||
1 nodes with value: 5
|
||||
3 nodes with value: <__main__.Rectangle object at 0x10d374d30>
|
||||
```
|
||||
|
||||
If we want to list all the expressions in a tree, we may want to filter out certain expressions whose values are obvious. For example, suppose we have a function `foo`:
|
||||
|
||||
```python
|
||||
def foo():
|
||||
pass
|
||||
```
|
||||
|
||||
If we refer to `foo` by its name as usual, then that's not interesting:
|
||||
|
||||
```python
|
||||
from pure_eval import is_expression_interesting
|
||||
|
||||
node = ast.parse('foo').body[0].value
|
||||
print(ast.dump(node))
|
||||
print(is_expression_interesting(node, foo))
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```python
|
||||
Name(id='foo', ctx=Load())
|
||||
False
|
||||
```
|
||||
|
||||
But if we refer to it by a different name, then it's interesting:
|
||||
|
||||
```python
|
||||
node = ast.parse('bar').body[0].value
|
||||
print(ast.dump(node))
|
||||
print(is_expression_interesting(node, foo))
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```python
|
||||
Name(id='bar', ctx=Load())
|
||||
True
|
||||
```
|
||||
|
||||
In general `is_expression_interesting` returns False for the following values:
|
||||
- Literals (e.g. `123`, `'abc'`, `[1, 2, 3]`, `{'a': (), 'b': ([1, 2], [3])}`)
|
||||
- Variables or attributes whose name is equal to the value's `__name__`, such as `foo` above or `self.foo` if it was a method.
|
||||
- Builtins (e.g. `len`) referred to by their usual name.
|
||||
|
||||
To make things easier, you can combine finding expressions, grouping them, and filtering out the obvious ones with:
|
||||
|
||||
```python
|
||||
evaluator.interesting_expressions_grouped(root)
|
||||
```
|
||||
|
||||
To get the source code of an AST node, I recommend [asttokens](https://github.com/gristlabs/asttokens).
|
||||
|
||||
Here's a complete example that brings it all together:
|
||||
|
||||
```python
|
||||
from asttokens import ASTTokens
|
||||
from pure_eval import Evaluator
|
||||
|
||||
source = """
|
||||
x = 1
|
||||
d = {x: 2}
|
||||
y = d[x]
|
||||
"""
|
||||
|
||||
names = {}
|
||||
exec(source, names)
|
||||
atok = ASTTokens(source, parse=True)
|
||||
for nodes, value in Evaluator(names).interesting_expressions_grouped(atok.tree):
|
||||
print(atok.get_text(nodes[0]), "=", value)
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```python
|
||||
x = 1
|
||||
d = {1: 2}
|
||||
y = 2
|
||||
d[x] = 2
|
||||
```
|
||||
|
||||
|
17
.venv/Lib/site-packages/pure_eval-0.2.2.dist-info/RECORD
Normal file
17
.venv/Lib/site-packages/pure_eval-0.2.2.dist-info/RECORD
Normal file
@ -0,0 +1,17 @@
|
||||
pure_eval-0.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
pure_eval-0.2.2.dist-info/LICENSE.txt,sha256=pHaiyw70xBRQNApXeii5GsTH9mkTay7hSAR_q9X8QYE,1066
|
||||
pure_eval-0.2.2.dist-info/METADATA,sha256=7ymWO8RGYzKetW67FHk45j-x3cig4U3pWAk2V-w5U38,6245
|
||||
pure_eval-0.2.2.dist-info/RECORD,,
|
||||
pure_eval-0.2.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
||||
pure_eval-0.2.2.dist-info/top_level.txt,sha256=aj24vzw3wc3XsL3Q0sHidIX6N7TaViEDr1R_R4Qbgjo,10
|
||||
pure_eval/__init__.py,sha256=epP1aW7z2hYB0FtC_x3w1AFlnhSgn4UVkRamFlVfXd4,285
|
||||
pure_eval/__pycache__/__init__.cpython-310.pyc,,
|
||||
pure_eval/__pycache__/core.cpython-310.pyc,,
|
||||
pure_eval/__pycache__/my_getattr_static.cpython-310.pyc,,
|
||||
pure_eval/__pycache__/utils.cpython-310.pyc,,
|
||||
pure_eval/__pycache__/version.cpython-310.pyc,,
|
||||
pure_eval/core.py,sha256=bxshWghVwCawdVfrNdXLqHj5UOpaPz1aAkB0T3xh_3Q,15309
|
||||
pure_eval/my_getattr_static.py,sha256=JvAM30EQcf7RQKG3fYSJT1tiwEKbkPnpqPRWXjIoV8o,4076
|
||||
pure_eval/py.typed,sha256=w3xYJo71zA7pDnF65xr6u8FL8gvJ7GdAKMJSLuv2IPU,68
|
||||
pure_eval/utils.py,sha256=eSI-lVyBzYW1D2vRQPrvhXPhQpRArhv_GoBx1AIfWHc,4415
|
||||
pure_eval/version.py,sha256=pKh2_hmFNUwG0JxbL18qxdmi_nmFpgRbR8X6IPZr08o,21
|
5
.venv/Lib/site-packages/pure_eval-0.2.2.dist-info/WHEEL
Normal file
5
.venv/Lib/site-packages/pure_eval-0.2.2.dist-info/WHEEL
Normal file
@ -0,0 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.37.1)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
@ -0,0 +1 @@
|
||||
pure_eval
|
Reference in New Issue
Block a user