
Security News
Insecure Agents Podcast: Certified Patches, Supply Chain Security, and AI Agents
Socket CEO Feross Aboukhadijeh joins Insecure Agents to discuss CVE remediation and why supply chain attacks require a different security approach.
stackvar
Advanced tools
Dispatch function's parameters through the callstack omitting arguments on intermediary functions. (a.k.a.: stack variable)
Dispatch function’s parameters through the callstack omitting arguments on intermediary functions.
Let’s suppose you have 4 functions nested in the call stack like this:
.. code:: python
def func1(): value_for_func4 = 10 func2()
def func2(): func3()
def func3(): func4()
def func4(value): #need to use value_for_func4 here #print(value_for_func4) ...
If you want to make value_for_func4 to reach func4 you have
these standard options
value_for_func4 through all 4
functions.global value_for_func4 variable.func1 ... func4 inside an object and
setting a shared property self.value_for_func4.context.value_for_func4 or using
**kwargs dictionary through the functions.With stackvar you have a fifth option, which is having a side
channel to dispatch variables through the call stack. Things would be
written as:
.. code:: python
def func1(): with stackvar.send(func4, value_for_func4=10): func2()
def func2(): func3()
def func3(): func4()
@stackvar.receive() def send_email(value_for_func4: stackvar.Variable = None): print(f'value_for_func4={value_for_func4}')
Advantages: - avoids clogging functions arguments - avoids clogging the global namespace - avoids clogging the object’s namespace - each thread has its own value - no need to use objects to solve the problem (still can do functional programming) - you can define default value - you can override when calling the receiver directly - you can dispatch to a function or to a namespace (defined by a UUID)
Disadvantages - not every debugging tools are not prepared to take
stackvar into account. - adds stackvar and pydantic as
dependencies - single programmer project in beta state
Warnings - You can’t send stackvars between threads, this is on purpose, to avoid race conditions for sharing data between threads. You should pass the data to the thread and then send it inside the thread.
https://pypi.org/project/stackvar/
::
pip install -U stackvar
.. code:: python
import stackvar
def test_stackvar(): # sending within a context with stackvar.send(send_email, email='rsanchez@example.com'): foo() # Use default value send_email() # pass specific value send_email('jerry@example.com')
def foo(): # intermediary function bar()
def bar(): # intermediary function send_email()
@stackvar.receive() def send_email(email: stackvar.Variable = 'morty@example.com'): print(f'Sending email to={email}')
if name == 'main': test_stackvar()
Will output
::
Sending email to=rsanchez@example.com Sending email to=morty@example.com Sending email to=jerry@example.com
.. code:: python
import stackvar import uuid
def cheat_sheet_doc(): # Using namespace (recommended method) my_namespace = stackvar.Namespace(uuid.uuid4()) @stackvar.receive(my_namespace) def send_email(email: stackvar.Variable = 'morty@example.com'): print(f'Sending email to={email}') with stackvar.send(my_namespace, email='rsanchez@example.com'): send_email()
# Automatic namespace (solved from function)
@stackvar.receive()
def send_email2(email: stackvar.Variable = 'morty@example.com'):
print(f'Sending email to={email}')
with stackvar.send(send_email2, email='rsanchez@example.com'):
send_email2()
# Without decorator
ns_uuid2 = stackvar.Namespace(uuid.uuid4())
def send_email_nodecorator():
email1 = ns_uuid2.email1
# setting default value for a variable
email2 = getattr(ns_uuid2, 'email2', 'jerry@example.com')
print(f'Sending email1 to={email1} and {email2}')
# another fancier way to set a default
email2 = stackvar.get(ns_uuid2, email2='summer@example.com')
print(f'Sending email1 to={email1} and {email2}')
with stackvar.send(ns_uuid2, email1='rsanchez@example.com'):
send_email_nodecorator()
# No default values
ns_uuid3 = stackvar.Namespace(uuid.uuid4())
@stackvar.receive(ns_uuid3)
def send_no_default(email1: stackvar.Variable, email2: stackvar.Variable):
print(f'Sending={email1} and {email2}')
with stackvar.send(ns_uuid3,
email1='rsanchez@example.com',
email2='summer@example.com'):
send_no_default()
# Using a Factory for default values
ns_uuid4 = stackvar.Namespace(uuid.uuid4())
@stackvar.receive(ns_uuid4)
def send_factory(email_list: stackvar.Factory = list):
email_list.append('squanchy@example.com')
print(f'Sending to={email_list}')
with stackvar.send(ns_uuid4):
send_factory()
if name == 'main': cheat_sheet_doc()
Check examples at https://gitlab.com/joaduo/stackvar/-/tree/main/tests
FAQs
Dispatch function's parameters through the callstack omitting arguments on intermediary functions. (a.k.a.: stack variable)
We found that stackvar demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins Insecure Agents to discuss CVE remediation and why supply chain attacks require a different security approach.

Security News
Tailwind Labs laid off 75% of its engineering team after revenue dropped 80%, as LLMs redirect traffic away from documentation where developers discover paid products.

Security News
The planned feature introduces a review step before releases go live, following the Shai-Hulud attacks and a rocky migration off classic tokens that disrupted maintainer workflows.