Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
etuples
Python S-expression emulation using tuple-like objects.
etuple
s are like tuples:
>>> from operator import add
>>> from etuples import etuple, etuplize
>>> et = etuple(add, 1, 2)
>>> et
ExpressionTuple((<built-in function add>, 1, 2))
>>> from IPython.lib.pretty import pprint
>>> pprint(et)
e(<function _operator.add(a, b, /)>, 1, 2)
>>> et[0:2]
ExpressionTuple((<built-in function add>, 1))
etuple
s can also be evaluated:
>>> et.evaled_obj
3
Evaluated etuple
s are cached:
>>> et = etuple(add, "a", "b")
>>> et.evaled_obj
'ab'
>>> et.evaled_obj is et.evaled_obj
True
Reconstructed etuple
s and their evaluation results are preserved across tuple operations:
>>> et_new = (et[0],) + et[1:]
>>> et_new is et
True
>>> et_new.evaled_obj is et.evaled_obj
True
rator
, rands
, and apply
will return the operator, the operands, and apply the operation to the operands:
>>> from etuples import rator, rands, apply
>>> et = etuple(add, 1, 2)
>>> rator(et)
<built-in function add>
>>> rands(et)
ExpressionTuple((1, 2))
>>> apply(rator(et), rands(et))
3
rator
and rands
are multipledispatch
functions that can be extended to handle arbitrary objects:
from etuples.core import ExpressionTuple
from collections.abc import Sequence
class Node:
def __init__(self, rator, rands):
self.rator, self.rands = rator, rands
def __eq__(self, other):
return self.rator == other.rator and self.rands == other.rands
class Operator:
def __init__(self, op_name):
self.op_name = op_name
def __call__(self, *args):
return Node(Operator(self.op_name), args)
def __repr__(self):
return self.op_name
def __eq__(self, other):
return self.op_name == other.op_name
rands.add((Node,), lambda x: x.rands)
rator.add((Node,), lambda x: x.rator)
@apply.register(Operator, (Sequence, ExpressionTuple))
def apply_Operator(rator, rands):
return Node(rator, rands)
>>> mul_op, add_op = Operator("*"), Operator("+")
>>> mul_node = Node(mul_op, [1, 2])
>>> add_node = Node(add_op, [mul_node, 3])
etuplize
will convert non-tuple objects into their corresponding etuple
form:
>>> et = etuplize(add_node)
>>> pprint(et)
e(+, e(*, 1, 2), 3)
>>> et.evaled_obj is add_node
True
etuplize
can also do shallow object-to-etuple
conversions:
>>> et = etuplize(add_node, shallow=True)
>>> pprint(et)
e(+, <__main__.Node at 0x7f347361a080>, 3)
Using pip
:
pip install etuples
First obtain the project source:
git clone git@github.com:pythological/etuples.git
Create a virtual environment and install the development dependencies:
$ pip install -r requirements.txt
Set up pre-commit
hooks:
$ pre-commit install --install-hooks
Tests can be run with the provided Makefile
:
make check
FAQs
Python S-expression emulation using tuple-like objects.
We found that etuples 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
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.