Skip to content

Commit

Permalink
fix: python linting errors (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan M Salamanca authored Sep 20, 2024
1 parent a08129b commit eac74c2
Show file tree
Hide file tree
Showing 24 changed files with 571 additions and 245 deletions.
11 changes: 5 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install . .'[test]'
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
# TODO: Disable linting until it is fixed.
# - name: Lint with pylint
# run: |
# pylint nada_dsl/
pip install . .'[test]' .'[lint]'
- name: Lint with pylint
run: |
pylint nada_dsl/
- name: Test with pytest
run: |
pytest
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Release workflow
# - When there is a push to 'main', it detects if the local version has changed and is higher than the remote (PyPI) version.
# - Generates a new nada-dsl release, signes it and pushes it to PyPI when a PR is merged that updates the version number in pyproject.toml.
# - Generates a new nada-dsl Github release

name: Create a new release

Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DS_Store
.coverage

.vscode/
*.pyc
__pycache__
*.egg-info
Expand All @@ -17,4 +17,4 @@ nada_dsl/version.py

# IntelliJ IDEA
*.iml
.idea
.idea
8 changes: 4 additions & 4 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ ignore=CVS
# ignore-list. The regex matches against paths and can be in Posix or Windows
# format. Because '\\' represents the directory delimiter on Windows systems,
# it can't be used as an escape character.
ignore-paths=
ignore-paths=nada_dsl/version.py

# Files or directories matching the regular expression patterns are skipped.
# The regex matches against base names, not paths. The default value ignores
# Emacs file locks
ignore-patterns=^\.#
ignore-patterns=(.)*_test\.py,^\.#

# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
Expand Down Expand Up @@ -337,7 +337,7 @@ indent-after-paren=4
indent-string=' '

# Maximum number of characters on a single line.
max-line-length=100
max-line-length=120

# Maximum number of lines in a module.
max-module-lines=1000
Expand Down Expand Up @@ -430,7 +430,7 @@ disable=raw-checker-failed,
deprecated-pragma,
use-symbolic-message-instead,
use-implicit-booleaness-not-comparison-to-string,
use-implicit-booleaness-not-comparison-to-zero
use-implicit-booleaness-not-comparison-to-zero,W0223,W0718,R0903,R0913,R0801,R0401,W0231

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down
2 changes: 1 addition & 1 deletion docs/_source/nada_dsl.circuit_io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ nada\_dsl.circuit\_io



.. automodule:: nada_dsl.circuit_io
.. automodule:: nada_dsl.program_io
:members:
:undoc-members:
:show-inheritance:
2 changes: 1 addition & 1 deletion docs/toc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
_source/nada_dsl.source_ref.rst
_source/nada_dsl.nada_types.rst
_source/nada_dsl.operations.rst
_source/nada_dsl.circuit_io.rst
_source/nada_dsl.program_io.rst
_source/nada_dsl.compile.rst
_source/nada_dsl.compiler_frontend.rst
4 changes: 2 additions & 2 deletions nada_dsl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from nada_dsl.source_ref import *
from nada_dsl.nada_types.scalar_types import *
from nada_dsl.nada_types.generics import *
from nada_dsl.nada_types.function import *
from nada_dsl.nada_types.collections import *
from nada_dsl.circuit_io import *
from nada_dsl.nada_types.function import *
from nada_dsl.program_io import *
from nada_dsl.compiler_frontend import nada_compile
7 changes: 4 additions & 3 deletions nada_dsl/ast_util.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
""" AST utilities."""

from abc import ABC, abstractmethod
from abc import ABC
from dataclasses import dataclass
import hashlib
from typing import Callable, Dict, List
from typing import Dict, List
from sortedcontainers import SortedDict
from nada_dsl.nada_types import NadaTypeRepr, Party
from nada_dsl.source_ref import SourceRef
Expand Down Expand Up @@ -179,6 +179,7 @@ def __init__(
self.literal_name = hashlib.md5(
(str(self.value) + str(self.ty)).encode("UTF-8")
).hexdigest()
super().__init__(id=self.id, source_ref=self.source_ref, ty=self.ty)

def to_mir(self):
return {
Expand Down Expand Up @@ -337,7 +338,7 @@ def __hash__(self) -> int:
return self.id


# TODO This is partially implemented
# Partially implemented
@dataclass
class CastASTOperation(ASTOperation):
"""AST Representation of a Cast operation."""
Expand Down
22 changes: 13 additions & 9 deletions nada_dsl/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import traceback
import importlib.util
from nada_dsl.compiler_frontend import nada_compile
from nada_dsl.errors import MissingEntryPointError, MissingProgramArgumentError
from nada_dsl.timer import add_timer, timer


Expand All @@ -21,7 +22,7 @@ class CompilerOutput:


@add_timer(timer_name="nada_dsl.compile.compile")
def compile(script_path: str) -> CompilerOutput:
def compile_script(script_path: str) -> CompilerOutput:
"""Compiles a NADA program
Args:
Expand All @@ -41,10 +42,10 @@ def compile(script_path: str) -> CompilerOutput:

try:
main = getattr(script, "nada_main")
except:
raise Exception(
except Exception as exc:
raise MissingEntryPointError(
"'nada_dsl' entrypoint function is missing in program " + script_name
)
) from exc
outputs = main()
compile_output = nada_compile(outputs)
return CompilerOutput(compile_output)
Expand All @@ -64,7 +65,7 @@ def compile_string(script: str) -> CompilerOutput:
temp_name = "temp_program"
spec = importlib.util.spec_from_loader(temp_name, loader=None)
module = importlib.util.module_from_spec(spec)
exec(decoded_program, module.__dict__)
exec(decoded_program, module.__dict__) # pylint:disable=W0122
sys.modules[temp_name] = module
globals()[temp_name] = module

Expand Down Expand Up @@ -92,17 +93,20 @@ def print_output(out: CompilerOutput):
timer.enable()
args_length = len(sys.argv)
if args_length < 2:
raise Exception("expected program as argument")
raise MissingProgramArgumentError("expected program as argument")
if args_length == 2:
output = compile(sys.argv[1])
output = compile_script(sys.argv[1])
print_output(output)
if args_length == 3 and sys.argv[1] == "-s":
output = compile_string(sys.argv[2])
print_output(output)

except Exception as ex:
tb = traceback.format_exc()
output = {"result": "Failure", "reason": str(ex), "traceback": str(tb)}
output = {
"result": "Failure",
"reason": str(ex),
"traceback": str(traceback.format_exc()),
}
print(json.dumps(output))

finally:
Expand Down
8 changes: 6 additions & 2 deletions nada_dsl/compile_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
import json
import pytest
from nada_dsl.ast_util import AST_OPERATIONS
from nada_dsl.compile import compile, compile_string
from nada_dsl.compile import compile_script, compile_string
from nada_dsl.compiler_frontend import FUNCTIONS, INPUTS, PARTIES


@pytest.fixture(autouse=True)
def clean_inputs():
PARTIES.clear()
Expand All @@ -18,14 +19,17 @@ def clean_inputs():
AST_OPERATIONS.clear()
yield


def get_test_programs_folder():
file_path = os.path.realpath(__file__)
this_directory = os.path.dirname(file_path)
if not this_directory.endswith("/"):
this_directory = this_directory + "/"
return this_directory + "../test-programs/"


def test_compile_nada_fn_simple():
mir_str = compile(f"{get_test_programs_folder()}/nada_fn_simple.py").mir
mir_str = compile_script(f"{get_test_programs_folder()}/nada_fn_simple.py").mir
assert mir_str != ""
mir = json.loads(mir_str)
mir_functions = mir["functions"]
Expand Down
19 changes: 10 additions & 9 deletions nada_dsl/compiler_frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
)
from nada_dsl.timer import timer
from nada_dsl.source_ref import SourceRef
from nada_dsl.circuit_io import Output
from nada_dsl.program_io import Output

INPUTS = SortedDict()
PARTIES = SortedDict()
Expand Down Expand Up @@ -206,8 +206,8 @@ def add_input_to_map(operation: InputASTOperation):
and INPUTS[party_name][operation.name][0].id != operation.id
):
raise CompilerException(f"Input is duplicated: {operation.name}")
else:
INPUTS[party_name][operation.name] = (operation, operation.ty)

INPUTS[party_name][operation.name] = (operation, operation.ty)
return operation.to_mir()


Expand Down Expand Up @@ -285,7 +285,7 @@ def process_operation(
It ignores nada function arguments as they should not be present in the MIR.
"""

processed_operation = None
if isinstance(
operation,
(
Expand All @@ -298,29 +298,30 @@ def process_operation(
NadaFunctionArgASTOperation,
),
):
return ProcessOperationOutput(operation.to_mir(), None)
processed_operation = ProcessOperationOutput(operation.to_mir(), None)

elif isinstance(operation, InputASTOperation):
add_input_to_map(operation)
return ProcessOperationOutput(operation.to_mir(), None)
processed_operation = ProcessOperationOutput(operation.to_mir(), None)
elif isinstance(operation, LiteralASTOperation):

LITERALS[operation.literal_name] = (str(operation.value), operation.ty)
return ProcessOperationOutput(operation.to_mir(), None)
processed_operation = ProcessOperationOutput(operation.to_mir(), None)
elif isinstance(
operation, (MapASTOperation, ReduceASTOperation, NadaFunctionCallASTOperation)
):
extra_fn = None
if operation.fn not in functions:
extra_fn = AST_OPERATIONS[operation.fn]

return ProcessOperationOutput(operation.to_mir(), extra_fn) # type: ignore
processed_operation = ProcessOperationOutput(operation.to_mir(), extra_fn) # type: ignore
elif isinstance(operation, NadaFunctionASTOperation):
extra_fn = None
if operation.id not in functions:
extra_fn = AST_OPERATIONS[operation.id]
return ProcessOperationOutput({}, extra_fn) # type: ignore
processed_operation = ProcessOperationOutput({}, extra_fn) # type: ignore
else:
raise CompilerException(
f"Compilation of Operation {operation} is not supported"
)
return processed_operation
2 changes: 1 addition & 1 deletion nada_dsl/compiler_frontend_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

# pylint: disable=wildcard-import,unused-wildcard-import
from nada_dsl.nada_types.scalar_types import *
from nada_dsl.circuit_io import Input, Output
from nada_dsl.program_io import Input, Output
from nada_dsl.compiler_frontend import (
nada_dsl_to_nada_mir,
to_input_list,
Expand Down
24 changes: 21 additions & 3 deletions nada_dsl/errors.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
"""
Custom exceptions used in this package.
Nada DSL Exceptions.
"""
class NadaNotAllowedException(Exception):
pass


class NotAllowedException(Exception):
"""Exception for not allowed use cases."""


class InvalidTypeError(Exception):
"""Invalid type error"""


class MissingProgramArgumentError(Exception):
"""Missing program argument"""


class MissingEntryPointError(Exception):
"""Missing nada_main entry point for the program."""


class IncompatibleTypesError(Exception):
"""The types in an operation are not compatible."""
8 changes: 6 additions & 2 deletions nada_dsl/future/operations.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Operations that will be supported in the future."""

from dataclasses import dataclass

from nada_dsl import SourceRef
Expand All @@ -7,6 +9,8 @@

@dataclass
class Cast:
"""Cast operation."""

target: AllTypes
to: AllTypesType
source_ref: SourceRef
Expand All @@ -18,7 +22,7 @@ def __init__(self, target: AllTypes, to: AllTypes, source_ref: SourceRef):
self.source_ref = source_ref

def store_in_ast(self, ty: object):
# We don't need to use ty because the output type is part of the operation.
"""Store object in AST"""
AST_OPERATIONS[self.id] = CastASTOperation(
id=self.id, target=self.target, to=self.to, source_ref=self.source_ref
id=self.id, target=self.target, ty=ty, source_ref=self.source_ref
)
18 changes: 18 additions & 0 deletions nada_dsl/nada_type_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""Tests for NadaType."""

import pytest
from nada_dsl.nada_types import NadaType
from nada_dsl.nada_types.scalar_types import Integer, PublicBoolean, SecretInteger


@pytest.mark.parametrize(
("cls", "expected"),
[
(SecretInteger, "SecretInteger"),
(Integer, "Integer"),
(PublicBoolean, "Boolean"),
],
)
def test_class_to_type(cls: NadaType, expected: str):
"""Tests `NadaType.class_to_type()"""
assert cls.class_to_type() == expected
Loading

0 comments on commit eac74c2

Please sign in to comment.