Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Tests

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
python-version: ["3.12"]

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Upgrade pip
run: python -m pip install --upgrade pip

# Install your project + dev dependencies (pytest lives here)
- name: Install dependencies
run: |
python -m pip install -e ".[dev]"

# Sanity check (helps debug future CI issues)
- name: Verify environment
run: |
python -c "import sidewinder; print('sidewinder import OK')"
python -m pip show pytest

- name: Run tests
run: python -m pytest -q
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.10
3.12
24 changes: 24 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Transformer",
"type": "debugpy",
"request": "launch",
"module": "sidewinder.analysis.transform.transformer",
"console": "integratedTerminal",
"justMyCode": false
},
{
"name": "Python Debugger: Tests",
"type": "debugpy",
"request": "launch",
"module": "pytest",
"args": [
"test/"
],
"console": "integratedTerminal",
"justMyCode": false
}
]
}
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"python-envs.defaultEnvManager": "ms-python.python:conda",
"python-envs.defaultPackageManager": "ms-python.python:conda"
}
24 changes: 18 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
[build-system]
requires = ["setuptools>=69"]
build-backend = "setuptools.build_meta"

[project]
name = "chugubandar"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = []
name = "sidewinder"
version = "0.0.1"
requires-python = ">=3.12"

[project.optional-dependencies]
dev = [
"pytest>=8",
]

[tool.setuptools]
package-dir = {"" = "src"}

[tool.setuptools.packages.find]
where = ["src"]
4 changes: 0 additions & 4 deletions src/analysis/symbolic/lattice/final_string.py

This file was deleted.

11 changes: 0 additions & 11 deletions src/analysis/symbolic/runtime/values/heap_object.py

This file was deleted.

14 changes: 0 additions & 14 deletions src/analysis/symbolic/runtime/values/symbolic_value.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
This package provides comprehensive Python code analysis capabilities.
"""

from analysis.analyzer import PythonCodeAnalyzer
from analysis.transform.transformer import SidewinderTransformer
from sidewinder.analysis.analyzer import PythonCodeAnalyzer
from sidewinder.analysis.transform.transformer import SidewinderTransformer

__all__ = ['PythonCodeAnalyzer', 'SidewinderTransformer']
__version__ = '1.0.0'
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import ast
from typing import Dict, List, Any, Optional
from analysis.transform.transformer import SidewinderTransformer
from sidewinder.analysis.transform.transformer import SidewinderTransformer


class PythonCodeAnalyzer:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from symbolic.value import SidewinderSymbolicValue
from sidewinder.analysis.symbolic.value import SidewinderSymbolicValue

class SidewinderSymbolicCallableValue(SidewinderSymbolicValue):
pass
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from analysis.symbolic.hook.sidewinder_hook import SidewinderHook, SidewinderHookNames
from sidewinder.analysis.symbolic.hook.sidewinder_hook import SidewinderHook, SidewinderHookNames

from typing import Dict

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from enum import Enum, auto
from typing import Any, Protocol

from analysis.symbolic.runtime.memory.state import SidewinderState
from sidewinder.analysis.symbolic.runtime.memory.state import SidewinderState


class SidewinderHookCallable(Protocol):
Expand Down
4 changes: 4 additions & 0 deletions src/sidewinder/analysis/symbolic/lattice/final_string.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from sidewinder.analysis.symbolic.lattice.placeholder_string import SidewinderPlaceholderString

class SidewinderFinalString(SidewinderPlaceholderString):
pass
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from analysis.symbolic.runtime.state.effect.effect_type import EffectType
from analysis.symbolic.runtime.values.symbolic_value import SymbolicValue
from sidewinder.analysis.symbolic.runtime.values.symbolic_value import SymbolicValue
from enum import Enum, auto

class OperationType(Enum):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from analysis.symbolic.runtime.state.effect import Effect
from analysis.symbolic.runtime.values.symbolic_value import SymbolicValue
from sidewinder.analysis.symbolic.runtime.values.symbolic_value import SymbolicValue


class GuardedEffect:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Protocol

from analysis.symbolic.runtime.values.symbolic_value import SymbolicValue
from sidewinder.analysis.symbolic.runtime.values.symbolic_value import SymbolicValue
from analysis.symbolic.runtime.state.effect.guarded_effect import GuardedEffect


Expand Down
11 changes: 11 additions & 0 deletions src/sidewinder/analysis/symbolic/runtime/values/heap_object.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from __future__ import annotations

from sidewinder.analysis.symbolic.runtime.values.key import Key
from sidewinder.analysis.symbolic.runtime.values.symbolic_type import SymbolicType
from sidewinder.analysis.symbolic.runtime.values.symbolic_value import SymbolicValue


class HeapObject:
id: int
heap_map: dict[Key, SymbolicValue]
type: SymbolicType
14 changes: 14 additions & 0 deletions src/sidewinder/analysis/symbolic/runtime/values/symbolic_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from __future__ import annotations

from typing import TypeAlias

from sidewinder.analysis.symbolic.runtime.values.effector import Effector
from sidewinder.analysis.symbolic.runtime.values.heap_object import HeapObject
from sidewinder.analysis.symbolic.runtime.values.primitive import Primitive


SymbolicValue: TypeAlias = (
Primitive
| HeapObject
| Effector
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@
import ast
from typing import Dict, List, Any, Union, overload

from analysis.transform.errors import SidewinderIllegalStateError
from analysis.transform.transformer_assign import SidewinderAssignTransformerMixin
from analysis.transform.transformer_base import SidewinderTransformerBase, T
from analysis.transform.transformer_classes import SidewinderClassTransformerMixin
from analysis.transform.transformer_context import TransformerContext
from analysis.transform.transformer_control_flow_breaker import SidewinderControlFlowBreakerTransformerMixin
from analysis.transform.transformer_expr import SidewinderExprTransformerMixin
from analysis.transform.transformer_for import SidewinderForTransformerMixin
from analysis.transform.transformer_functions import SidewinderFunctionTransformerMixin
from analysis.transform.transformer_helpers import SidewinderTransformerHelpers
from analysis.transform.transformer_if import SidewinderIfTransformerMixin
from analysis.transform.transformer_modules import SidewinderModuleTransformerMixin
from analysis.transform.transformer_try import SidewinderTryTransformerMixin
from analysis.transform.transformer_while import SidewinderWhileTransformerMixin
from analysis.transform.transformer_with import SidewinderWithTransformerMixin
from analysis.symbolic.hook import SidewinderHookNames
from sidewinder.analysis.transform.errors import SidewinderIllegalStateError
from sidewinder.analysis.transform.transformer_assign import SidewinderAssignTransformerMixin
from sidewinder.analysis.transform.transformer_base import SidewinderTransformerBase, T
from sidewinder.analysis.transform.transformer_classes import SidewinderClassTransformerMixin
from sidewinder.analysis.transform.transformer_context import TransformerContext
from sidewinder.analysis.transform.transformer_control_flow_breaker import SidewinderControlFlowBreakerTransformerMixin
from sidewinder.analysis.transform.transformer_expr import SidewinderExprTransformerMixin
from sidewinder.analysis.transform.transformer_for import SidewinderForTransformerMixin
from sidewinder.analysis.transform.transformer_functions import SidewinderFunctionTransformerMixin
from sidewinder.analysis.transform.transformer_helpers import SidewinderTransformerHelpers
from sidewinder.analysis.transform.transformer_if import SidewinderIfTransformerMixin
from sidewinder.analysis.transform.transformer_modules import SidewinderModuleTransformerMixin
from sidewinder.analysis.transform.transformer_try import SidewinderTryTransformerMixin
from sidewinder.analysis.transform.transformer_while import SidewinderWhileTransformerMixin
from sidewinder.analysis.transform.transformer_with import SidewinderWithTransformerMixin
from sidewinder.analysis.symbolic.hook import SidewinderHookNames


# This is not the transformer which is behind LLMs. This is an AST transformer, which transforms the abstract syntax trees generated by parsing
Expand Down Expand Up @@ -262,8 +262,10 @@ def transform_code(source_code: str) -> str:
# print(i)

test_code = """
def foo(x, *k, **y):
pass
if x:
y = 1
else:
y = 2
"""

# a = [x * 2 for x in range(5)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import ast
import copy

from analysis.transform.transformer_helpers import SidewinderTransformerHelpers
from sidewinder.analysis.transform.transformer_helpers import SidewinderTransformerHelpers


class SidewinderAssignTransformerMixin(SidewinderTransformerHelpers):
def visit_Assign(self, node: ast.Assign) -> None:
def visit_Assign(self, node: ast.Assign) -> list[ast.stmt]:
"""Transform assignment statement - transform value."""
transformed_value = self._visit_expr(node.value)
if len(node.targets) != 1:
raise NotImplementedError(f"Sidewinder currently only supports a single target for assign statements like {ast.unparse(node)}")
to_return = []
for target in node.targets:
self._visit_target(target, transformed_value)
return None
to_return.extend(self._visit_target(target, transformed_value))
return to_return

def visit_AnnAssign(self, node: ast.AnnAssign) -> None:
def visit_AnnAssign(self, node: ast.AnnAssign) -> list[ast.stmt]:
"""Transform annotated assignment statement."""
# Transform the annotation (it's an expr)
node.annotation = self._visit_expr(node.annotation)
# Transform the value if it exists (can be None)
if node.value is not None:
self._visit_target(node.target, self._visit_expr(node.value))
return None
return self._visit_target(node.target, self._visit_expr(node.value))
return []

def visit_AugAssign(self, node: ast.AugAssign) -> None:
def visit_AugAssign(self, node: ast.AugAssign) -> list[ast.stmt]:
op_map = {
ast.Add: 'add',
ast.Sub: 'sub',
Expand Down Expand Up @@ -64,11 +65,13 @@ def visit_AugAssign(self, node: ast.AugAssign) -> None:
)

tmp = self._fresh_temp()
self.current_context.append_stmt(
to_return = []
to_return.append(
ast.Assign(
targets=[ast.Name(id=tmp, ctx=ast.Store())],
value=rhs_value,
lineno=0, col_offset=0,
)
)
self._visit_target(node.target, ast.Name(id=tmp, ctx=ast.Load()))
to_return.extend(self._visit_target(node.target, ast.Name(id=tmp, ctx=ast.Load())))
return to_return
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ast
from typing import TypeVar, TypeAlias, overload, Union, Any

from analysis.transform.transformer_context import TransformerContext
from sidewinder.analysis.transform.transformer_context import TransformerContext

T = TypeVar('T', bound=ast.expr)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ast
from typing import Any

from analysis.transform.transformer_helpers import SidewinderTransformerHelpers
from sidewinder.analysis.transform.transformer_helpers import SidewinderTransformerHelpers

class SidewinderClassTransformerMixin(SidewinderTransformerHelpers):
def visit_ClassDef(self, node: ast.ClassDef) -> Any:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import ast
from typing import Any, Union

from analysis.transform.transformer_helpers import SidewinderTransformerHelpers
from analysis.symbolic.hook import SidewinderHookNames
from sidewinder.analysis.transform.transformer_helpers import SidewinderTransformerHelpers
from sidewinder.analysis.symbolic.hook import SidewinderHookNames

class SidewinderControlFlowBreakerTransformerMixin(SidewinderTransformerHelpers):
def visit_Return(self, node: ast.Return) -> Any:
Expand Down
Loading
Loading