{
	"SPDXID":"SPDXRef-DOCUMENT",
	"name":"python3-stack-data-0.0.6.2-1.oe2409.aarch64.rpm",
	"spdxVersion":"SPDX-2.2",
	"creationInfo":{
		"created":"2024-09-30T03:30:07.5589037Z",
		"creators":"[openeuler_creator]"
	},
	"dataLicense":"CC0-1.0",
	"documentNamespace":"https://repo.openeuler.org/security/data/sbom/python3-stack-data-0.0.6.2-1.oe2409.aarch64.rpm",
	"packages":[
		{
			"SPDXID":"SPDXRef-rpm-python3-3.11.6-46a48388-2814-4f07-af71-9388edc427ec-c8599159-51bb-4225-ab57-3cb78e48568e",
			"name":"python3",
			"checksums":[
				{
					"algorithm":"SHA256",
					"checksumValue":"08bd7937d659d460eb57f421500cb0fd93e554c236a1ca9b5bb9efdd64c21d48"
				}
			],
			"description":"Python combines remarkable power with very clear syntax. It has modules,\nclasses, exceptions, very high level dynamic data types, and dynamic\ntyping. There are interfaces to many system calls and libraries, as well\nas to various windowing systems. New built-in modules are easily written\nin C or C++ (or other languages, depending on the chosen implementation).\nPython is also usable as an extension language for applications written\nin other languages that need easy-to-use scripting or automation interfaces.\n\nThis package Provides python version 3.",
			"downloadLocation":"NOASSERTION",
			"externalRefs":[
				{
					"referenceCategory":"PACKAGE_MANAGER",
					"referenceLocator":"pkg:rpm/python3@3.11.6-5.oe2409?arch=aarch64&epoch=0&upstream=python3-3.11.6-5.oe2409.src.rpm",
					"referenceType":"purl"
				}
			],
			"filesAnalyzed":false,
			"homepage":"https://www.python.org/",
			"sourceInfo":"acquired package info from repodata DB: repodata/6e742f68b2ae62313d1861c02b7faa39b44c963cbbc6ac979fb577de9af9babc-primary.sqlite.bz2",
			"summary":"Interpreter of the Python3 programming language",
			"supplier":"Organization: http://openeuler.org",
			"versionInfo":"0:3.11.6-5.oe2409"
		},
		{
			"SPDXID":"SPDXRef-rpm-python3-asttokens-2.4.1-d052c5a7-5e63-492a-a0ac-d05539a295af-50a6e69a-82f4-42b8-947c-2f0fd6ed6a9f",
			"name":"python3-asttokens",
			"checksums":[
				{
					"algorithm":"SHA256",
					"checksumValue":"4adc78e88fe6795d0c7f179e892cc2e172b131830ccdc3e3ab1d51ccef066328"
				}
			],
			"description":"The asttokens module annotates Python abstract syntax trees (ASTs)\nwith the positions of tokens and text in the source code that\ngenerated them. This makes it possible for tools that work with\nlogical AST nodes to find the particular text that resulted in those\nnodes, for example for automated refactoring or highlighting.",
			"downloadLocation":"NOASSERTION",
			"externalRefs":[
				{
					"referenceCategory":"PACKAGE_MANAGER",
					"referenceLocator":"pkg:rpm/python3-asttokens@2.4.1-1.oe2409?arch=noarch&epoch=0&upstream=python-asttokens-2.4.1-1.oe2409.src.rpm",
					"referenceType":"purl"
				}
			],
			"filesAnalyzed":false,
			"homepage":"https://github.com/gristlabs/asttokens",
			"sourceInfo":"acquired package info from repodata DB: repodata/6e742f68b2ae62313d1861c02b7faa39b44c963cbbc6ac979fb577de9af9babc-primary.sqlite.bz2",
			"summary":"Module to annotate Python abstract syntax trees with source code positions",
			"supplier":"Organization: http://openeuler.org",
			"versionInfo":"0:2.4.1-1.oe2409"
		},
		{
			"SPDXID":"SPDXRef-rpm-python3-executing-1.2.0-b2708bc3-777d-489a-b4f9-2091d56cd88b-d2312970-2f0d-4416-8b5f-1fdd45613e74",
			"name":"python3-executing",
			"checksums":[
				{
					"algorithm":"SHA256",
					"checksumValue":"3440d525e6e81b6c494e8a4fca5230cea499ca74a6295825665cf38d4096ac2a"
				}
			],
			"description":"\n\n[![Build Status](https://github.com/alexmojaki/executing/workflows/Tests/badge.svg?branch=master)](https://github.com/alexmojaki/executing/actions) [![Coverage Status](https://coveralls.io/repos/github/alexmojaki/executing/badge.svg?branch=master)](https://coveralls.io/github/alexmojaki/executing?branch=master) [![Supports Python versions 2.7 and 3.5+, including PyPy](https://img.shields.io/pypi/pyversions/executing.svg)](https://pypi.python.org/pypi/executing)\n\nThis mini-package lets you get information about what a frame is currently doing, particularly the AST node being executed.\n\n* [Usage](#usage)\n    * [Getting the AST node](#getting-the-ast-node)\n    * [Getting the source code of the node](#getting-the-source-code-of-the-node)\n    * [Getting the `__qualname__` of the current function](#getting-the-__qualname__-of-the-current-function)\n    * [The Source class](#the-source-class)\n* [Installation](#installation)\n* [How does it work?](#how-does-it-work)\n* [Is it reliable?](#is-it-reliable)\n* [Which nodes can it identify?](#which-nodes-can-it-identify)\n* [Libraries that use this](#libraries-that-use-this)\n\n\n\n\n\n```python\nimport executing\n\nnode = executing.Source.executing(frame).node\n```\n\nThen `node` will be an AST node (from the `ast` standard library module) or None if the node couldn't be identified (which may happen often and should always be checked).\n\n`node` will always be the same instance for multiple calls with frames at the same point of execution.\n\nIf you have a traceback object, pass it directly to `Source.executing()` rather than the `tb_frame` attribute to get the correct node.\n\n\n\nFor this you will need to separately install the [`asttokens`](https://github.com/gristlabs/asttokens) library, then obtain an `ASTTokens` object:\n\n```python\nexecuting.Source.executing(frame).source.asttokens()\n```\n\nor:\n\n```python\nexecuting.Source.for_frame(frame).asttokens()\n```\n\nor use one of the convenience methods:\n\n```python\nexecuting.Source.executing(frame).text()\nexecuting.Source.executing(frame).text_range()\n```\n\n\n\n```python\nexecuting.Source.executing(frame).code_qualname()\n```\n\nor:\n\n```python\nexecuting.Source.for_frame(frame).code_qualname(frame.f_code)\n```\n\n\n\nEverything goes through the `Source` class. Only one instance of the class is created for each filename. Subclassing it to add more attributes on creation or methods is recommended. The classmethods such as `executing` will respect this. See the source code and docstrings for more detail.\n\n\n\n    pip install executing\n\nIf you don't like that you can just copy the file `executing.py`, there are no dependencies (but of course you won't get updates).\n\n\n\nSuppose the frame is executing this line:\n\n```python\nself.foo(bar.x)\n```\n\nand in particular it's currently obtaining the attribute `self.foo`. Looking at the bytecode, specifically `frame.f_code.co_code[frame.f_lasti]`, we can tell that it's loading an attribute, but it's not obvious which one. We can narrow down the statement being executed using `frame.f_lineno` and find the two `ast.Attribute` nodes representing `self.foo` and `bar.x`. How do we find out which one it is, without recreating the entire compiler in Python?\n\nThe trick is to modify the AST slightly for each candidate expression and observe the changes in the bytecode instructions. We change the AST to this:\n\n```python\n(self.foo ** 'longuniqueconstant')(bar.x)\n```\n\nand compile it, and the bytecode will be almost the same but there will be two new instructions:\n\n    LOAD_CONST 'longuniqueconstant'\n    BINARY_POWER\n\nand just before that will be a `LOAD_ATTR` instruction corresponding to `self.foo`. Seeing that it's in the same position as the original instruction lets us know we've found our match.\n\n\n\nYes - if it identifies a node, you can trust that it's identified the correct one. The tests are very thorough - in addition to unit tests which check various situations directly, there are property tests against a large number of files (see the filenames printed in [this build](https://travis-ci.org/alexmojaki/executing/jobs/557970457)) with real code. Specifically, for each file, the tests:\n\n 1. Identify as many nodes as possible from all the bytecode instructions in the file, and assert that they are all distinct\n 2. Find all the nodes that should be identifiable, and assert that they were indeed identified somewhere\n\nIn other words, it shows that there is a one-to-one mapping between the nodes and the instructions that can be handled. This leaves very little room for a bug to creep in.\n\nFurthermore, `executing` checks that the instructions compiled from the modified AST exactly match the original code save for a few small known exceptions. This accounts for all the quirks and optimisations in the interpreter.\n\n\n\nCurrently it works in almost all cases for the following `ast` nodes:\n\n - `Call`, e.g. `self.foo(bar)`\n - `Attribute`, e.g. `point.x`\n - `Subscript`, e.g. `lst[1]`\n - `BinOp`, e.g. `x + y` (doesn't include `and` and `or`)\n - `UnaryOp`, e.g. `-n` (includes `not` but only works sometimes)\n - `Compare` e.g. `a < b` (not for chains such as `0 < p < 1`)\n\nThe plan is to extend to more operations in the future.\n\n\n\n\n\n- **[`stack_data`](https://github.com/alexmojaki/stack_data)**: Extracts data from stack frames and tracebacks, particularly to display more useful tracebacks than the default. Also uses another related library of mine: **[`pure_eval`](https://github.com/alexmojaki/pure_eval)**.\n- **[`futurecoder`](https://futurecoder.io/)**: Highlights the executing node in tracebacks using `executing` via `stack_data`, and provides debugging with `snoop`.\n- **[`snoop`](https://github.com/alexmojaki/snoop)**: A feature-rich and convenient debugging library. Uses `executing` to show the operation which caused an exception and to allow the `pp` function to display the source of its arguments.\n- **[`heartrate`](https://github.com/alexmojaki/heartrate)**: A simple real time visualisation of the execution of a Python program. Uses `executing` to highlight currently executing operations, particularly in each frame of the stack trace.\n- **[`sorcery`](https://github.com/alexmojaki/sorcery)**: Dark magic delights in Python. Uses `executing` to let special callables called spells know where they're being called from.\n\n\n\n- **[`IPython`](https://github.com/ipython/ipython/pull/12150)**: Highlights the executing node in tracebacks using `executing` via [`stack_data`](https://github.com/alexmojaki/stack_data).\n- **[`icecream`](https://github.com/gruns/icecream)**: 🍦 Sweet and creamy print debugging. Uses `executing` to identify where `ic` is called and print its arguments.\n- **[`friendly_traceback`](https://github.com/friendly-traceback/friendly-traceback)**: Uses `stack_data` and `executing` to pinpoint the cause of errors and provide helpful explanations.\n- **[`python-devtools`](https://github.com/samuelcolvin/python-devtools)**: Uses `executing` for print debugging similar to `icecream`.\n- **[`sentry_sdk`](https://github.com/getsentry/sentry-python)**: Add the integration `sentry_sdk.integrations.executingExecutingIntegration()` to show the function `__qualname__` in each frame in sentry events.\n- **[`varname`](https://github.com/pwwang/python-varname)**: Dark magics about variable names in python. Uses `executing` to find where its various magical functions like `varname` and `nameof` are called from.",
			"downloadLocation":"NOASSERTION",
			"externalRefs":[
				{
					"referenceCategory":"PACKAGE_MANAGER",
					"referenceLocator":"pkg:rpm/python3-executing@1.2.0-1.oe2409?arch=noarch&epoch=0&upstream=python-executing-1.2.0-1.oe2409.src.rpm",
					"referenceType":"purl"
				}
			],
			"filesAnalyzed":false,
			"homepage":"https://github.com/alexmojaki/executing",
			"sourceInfo":"acquired package info from repodata DB: repodata/6e742f68b2ae62313d1861c02b7faa39b44c963cbbc6ac979fb577de9af9babc-primary.sqlite.bz2",
			"summary":"Get the currently executing AST node of a frame, and other information",
			"supplier":"Organization: http://openeuler.org",
			"versionInfo":"0:1.2.0-1.oe2409"
		},
		{
			"SPDXID":"SPDXRef-rpm-python3-pure-eval-0.2.2-cd1ec3b2-7bb7-4df3-a42a-99eb0f7fefa0-7d37ebc7-ad40-49b1-9116-96f664aa5044",
			"name":"python3-pure-eval",
			"checksums":[
				{
					"algorithm":"SHA256",
					"checksumValue":"b692eedb3f1c29dfdd6d7808a5170daf83c1c2869063439a1c1913a2f51d9bdb"
				}
			],
			"description":"\n\n[![Build Status](https://travis-ci.org/alexmojaki/pure_eval.svg?branch=master)](https://travis-ci.org/alexmojaki/pure_eval) [![Coverage Status](https://coveralls.io/repos/github/alexmojaki/pure_eval/badge.svg?branch=master)](https://coveralls.io/github/alexmojaki/pure_eval?branch=master) [![Supports Python versions 3.5+](https://img.shields.io/pypi/pyversions/pure_eval.svg)](https://pypi.python.org/pypi/pure_eval)\n\nThis is a Python package that lets you safely evaluate certain AST nodes without triggering arbitrary code that may have unwanted side effects.\n\nIt can be installed from PyPI:\n\n    pip install pure_eval\n\nTo demonstrate usage, suppose we have an object defined as follows:\n\n```python\nclass Rectangle:\n    def __init__(self, width, height):\n        self.width = width\n        self.height = height\n\n    @property\n    def area(self):\n        print(\"Calculating area...\")\n        return self.width * self.height\n\n\nrect = Rectangle(3, 5)\n```\n\nGiven the `rect` object, we want to evaluate whatever expressions we can in this source code:\n\n```python\nsource = \"(rect.width, rect.height, rect.area)\"\n```\n\nThis library works with the AST, so let's parse the source code and peek inside:\n\n```python\nimport ast\n\ntree = ast.parse(source)\nthe_tuple = tree.body[0].value\nfor node in the_tuple.elts:\n    print(ast.dump(node))\n```\n\nOutput:\n\n```python\nAttribute(value=Name(id='rect', ctx=Load()), attr='width', ctx=Load())\nAttribute(value=Name(id='rect', ctx=Load()), attr='height', ctx=Load())\nAttribute(value=Name(id='rect', ctx=Load()), attr='area', ctx=Load())\n```\n\nNow to actually use the library. First construct an Evaluator:\n\n```python\nfrom pure_eval import Evaluator\n\nevaluator = Evaluator({\"rect\": rect})\n```\n\nThe 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:\n\n```python\nevaluator = Evaluator.from_frame(frame)\n```\n\nNow to evaluate some nodes, using `evaluator[node]`:\n\n```python\nprint(\"rect.width:\", evaluator[the_tuple.elts[0]])\nprint(\"rect:\", evaluator[the_tuple.elts[0].value])\n```\n\nOutput:\n\n```\nrect.width: 3\nrect: <__main__.Rectangle object at 0x105b0dd30>\n```\n\nOK, 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.\n\n```python\nfrom pure_eval import CannotEval\n\ntry:\n    print(\"rect.area:\", evaluator[the_tuple.elts[2]])  # fails\nexcept CannotEval as e:\n    print(e)  # prints CannotEval\n```\n\nTo find all the expressions that can be evaluated in a tree:\n\n```python\nfor node, value in evaluator.find_expressions(tree):\n    print(ast.dump(node), value)\n```\n\nOutput:\n\n```python\nAttribute(value=Name(id='rect', ctx=Load()), attr='width', ctx=Load()) 3\nAttribute(value=Name(id='rect', ctx=Load()), attr='height', ctx=Load()) 5\nName(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30>\nName(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30>\nName(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30>\n```\n\nNote 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:\n\n```python\nfrom pure_eval import group_expressions\n\nfor nodes, values in group_expressions(evaluator.find_expressions(tree)):\n    print(len(nodes), \"nodes with value:\", values)\n```\n\nOutput:\n\n```\n1 nodes with value: 3\n1 nodes with value: 5\n3 nodes with value: <__main__.Rectangle object at 0x10d374d30>\n```\n\nIf 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`:\n\n```python\ndef foo():\n    pass\n```\n\nIf we refer to `foo` by its name as usual, then that's not interesting:\n\n```python\nfrom pure_eval import is_expression_interesting\n\nnode = ast.parse('foo').body[0].value\nprint(ast.dump(node))\nprint(is_expression_interesting(node, foo))\n```\n\nOutput:\n\n```python\nName(id='foo', ctx=Load())\nFalse\n```\n\nBut if we refer to it by a different name, then it's interesting:\n\n```python\nnode = ast.parse('bar').body[0].value\nprint(ast.dump(node))\nprint(is_expression_interesting(node, foo))\n```\n\nOutput:\n\n```python\nName(id='bar', ctx=Load())\nTrue\n```\n\nIn general `is_expression_interesting` returns False for the following values:\n- Literals (e.g. `123`, `'abc'`, `[1, 2, 3]`, `{'a': (), 'b': ([1, 2], [3])}`)\n- Variables or attributes whose name is equal to the value's `__name__`, such as `foo` above or `self.foo` if it was a method.\n- Builtins (e.g. `len`) referred to by their usual name.\n\nTo make things easier, you can combine finding expressions, grouping them, and filtering out the obvious ones with:\n\n```python\nevaluator.interesting_expressions_grouped(root)\n```\n\nTo get the source code of an AST node, I recommend [asttokens](https://github.com/gristlabs/asttokens).\n\nHere's a complete example that brings it all together:\n\n```python\nfrom asttokens import ASTTokens\nfrom pure_eval import Evaluator\n\nsource = \"\"\"\nx = 1\nd = {x: 2}\ny = d[x]\n\"\"\"\n\nnames = {}\nexec(source, names)\natok = ASTTokens(source, parse=True)\nfor nodes, value in Evaluator(names).interesting_expressions_grouped(atok.tree):\n    print(atok.get_text(nodes[0]), \"=\", value)\n```\n\nOutput:\n\n```python\nx = 1\nd = {1: 2}\ny = 2\nd[x] = 2\n```",
			"downloadLocation":"NOASSERTION",
			"externalRefs":[
				{
					"referenceCategory":"PACKAGE_MANAGER",
					"referenceLocator":"pkg:rpm/python3-pure-eval@0.2.2-1.oe2409?arch=noarch&epoch=0&upstream=python-pure-eval-0.2.2-1.oe2409.src.rpm",
					"referenceType":"purl"
				}
			],
			"filesAnalyzed":false,
			"homepage":"http://github.com/alexmojaki/pure_eval",
			"sourceInfo":"acquired package info from repodata DB: repodata/6e742f68b2ae62313d1861c02b7faa39b44c963cbbc6ac979fb577de9af9babc-primary.sqlite.bz2",
			"summary":"Safely evaluate AST nodes without side effects",
			"supplier":"Organization: http://openeuler.org",
			"versionInfo":"0:0.2.2-1.oe2409"
		}
	],
	"relationships":[
		{
			"spdxElementId":"SPDXRef-rpm-python3-stack-data-0.6.2-49a31743-86c5-4df4-b945-2950e2e9231f",
			"relationshipType":"DEPENDS_ON",
			"relatedSpdxElement":"SPDXRef-rpm-python3-3.11.6-46a48388-2814-4f07-af71-9388edc427ec-c8599159-51bb-4225-ab57-3cb78e48568e"
		},
		{
			"spdxElementId":"SPDXRef-rpm-python3-stack-data-0.6.2-49a31743-86c5-4df4-b945-2950e2e9231f",
			"relationshipType":"DEPENDS_ON",
			"relatedSpdxElement":"SPDXRef-rpm-python3-asttokens-2.4.1-d052c5a7-5e63-492a-a0ac-d05539a295af-50a6e69a-82f4-42b8-947c-2f0fd6ed6a9f"
		},
		{
			"spdxElementId":"SPDXRef-rpm-python3-stack-data-0.6.2-49a31743-86c5-4df4-b945-2950e2e9231f",
			"relationshipType":"DEPENDS_ON",
			"relatedSpdxElement":"SPDXRef-rpm-python3-executing-1.2.0-b2708bc3-777d-489a-b4f9-2091d56cd88b-d2312970-2f0d-4416-8b5f-1fdd45613e74"
		},
		{
			"spdxElementId":"SPDXRef-rpm-python3-stack-data-0.6.2-49a31743-86c5-4df4-b945-2950e2e9231f",
			"relationshipType":"DEPENDS_ON",
			"relatedSpdxElement":"SPDXRef-rpm-python3-pure-eval-0.2.2-cd1ec3b2-7bb7-4df3-a42a-99eb0f7fefa0-7d37ebc7-ad40-49b1-9116-96f664aa5044"
		}
	]
}