Skip to content

Commit

Permalink
Merge pull request #1243 from CityOfZion/CU-86dt9vrac
Browse files Browse the repository at this point in the history
#86dt9vrac - Test the new import structure for storage
  • Loading branch information
luc10921 authored Apr 29, 2024
2 parents a9273f6 + 96ac8b2 commit 1ebbe22
Show file tree
Hide file tree
Showing 143 changed files with 1,158 additions and 253 deletions.
20 changes: 20 additions & 0 deletions boa3/builtin/interop/storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@
'find',
]

from deprecation import deprecated

from boa3.builtin.interop.iterator import Iterator
from boa3.builtin.interop.storage.findoptions import FindOptions
from boa3.builtin.interop.storage.storagecontext import StorageContext
from boa3.builtin.interop.storage.storagemap import StorageMap
from boa3.builtin.type import UInt160, UInt256, ECPoint


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_context() -> StorageContext:
"""
Gets current storage context.
Expand All @@ -42,6 +45,7 @@ def get_context() -> StorageContext:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get(key: bytes, context: StorageContext = get_context()) -> bytes:
"""
Gets a value from the persistent store based on the given key.
Expand All @@ -63,6 +67,7 @@ def get(key: bytes, context: StorageContext = get_context()) -> bytes:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_int(key: bytes, context: StorageContext = get_context()) -> int:
"""
Gets a value as integer from the persistent store based on the given key.
Expand All @@ -85,6 +90,7 @@ def get_int(key: bytes, context: StorageContext = get_context()) -> int:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_bool(key: bytes, context: StorageContext = get_context()) -> bool:
"""
Gets a value as boolean from the persistent store based on the given key.
Expand All @@ -107,6 +113,7 @@ def get_bool(key: bytes, context: StorageContext = get_context()) -> bool:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_str(key: bytes, context: StorageContext = get_context()) -> str:
"""
Gets a value as string from the persistent store based on the given key.
Expand All @@ -129,6 +136,7 @@ def get_str(key: bytes, context: StorageContext = get_context()) -> str:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_uint160(key: bytes, context: StorageContext = get_context()) -> UInt160:
"""
Gets a value as UInt160 from the persistent store based on the given key.
Expand All @@ -151,6 +159,7 @@ def get_uint160(key: bytes, context: StorageContext = get_context()) -> UInt160:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_uint256(key: bytes, context: StorageContext = get_context()) -> UInt256:
"""
Gets a value as UInt256 from the persistent store based on the given key.
Expand All @@ -173,6 +182,7 @@ def get_uint256(key: bytes, context: StorageContext = get_context()) -> UInt256:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_ecpoint(key: bytes, context: StorageContext = get_context()) -> ECPoint:
"""
Gets a value as ECPoint from the persistent store based on the given key.
Expand All @@ -195,6 +205,7 @@ def get_ecpoint(key: bytes, context: StorageContext = get_context()) -> ECPoint:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_read_only_context() -> StorageContext:
"""
Gets current read only storage context.
Expand All @@ -208,6 +219,7 @@ def get_read_only_context() -> StorageContext:
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put(key: bytes, value: bytes, context: StorageContext = get_context()):
"""
Inserts a given bytes value in the key-value format into the persistent storage.
Expand All @@ -225,6 +237,7 @@ def put(key: bytes, value: bytes, context: StorageContext = get_context()):
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_int(key: bytes, value: int, context: StorageContext = get_context()):
"""
Inserts a given integer value in the key-value format into the persistent storage.
Expand All @@ -243,6 +256,7 @@ def put_int(key: bytes, value: int, context: StorageContext = get_context()):
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_bool(key: bytes, value: bool, context: StorageContext = get_context()):
"""
Inserts a given boolean value in the key-value format into the persistent storage.
Expand All @@ -261,6 +275,7 @@ def put_bool(key: bytes, value: bool, context: StorageContext = get_context()):
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_str(key: bytes, value: str, context: StorageContext = get_context()):
"""
Inserts a given str value in the key-value format into the persistent storage.
Expand All @@ -279,6 +294,7 @@ def put_str(key: bytes, value: str, context: StorageContext = get_context()):
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_uint160(key: bytes, value: UInt160, context: StorageContext = get_context()):
"""
Inserts a given UInt160 value in the key-value format into the persistent storage.
Expand All @@ -297,6 +313,7 @@ def put_uint160(key: bytes, value: UInt160, context: StorageContext = get_contex
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_uint256(key: bytes, value: UInt256, context: StorageContext = get_context()):
"""
Inserts a given UInt256 value in the key-value format into the persistent storage.
Expand All @@ -315,6 +332,7 @@ def put_uint256(key: bytes, value: UInt256, context: StorageContext = get_contex
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_ecpoint(key: bytes, value: ECPoint, context: StorageContext = get_context()):
"""
Inserts a given ECPoint value in the key-value format into the persistent storage.
Expand All @@ -333,6 +351,7 @@ def put_ecpoint(key: bytes, value: ECPoint, context: StorageContext = get_contex
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def delete(key: bytes, context: StorageContext = get_context()):
"""
Removes a given key from the persistent storage if exists.
Expand All @@ -350,6 +369,7 @@ def delete(key: bytes, context: StorageContext = get_context()):
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def find(prefix: bytes,
context: StorageContext = get_context(),
options: FindOptions = FindOptions.NONE) -> Iterator:
Expand Down
3 changes: 3 additions & 0 deletions boa3/builtin/interop/storage/storagecontext.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

__all__ = ['StorageContext']

from deprecation import deprecated

from boa3.builtin.interop.storage.storagemap import StorageMap


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
class StorageContext:
"""
The storage context used to read and write data in smart contracts.
Expand Down
3 changes: 3 additions & 0 deletions boa3/builtin/interop/storage/storagemap.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
__all__ = ['StorageMap']

from deprecation import deprecated


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
class StorageMap:
"""
The key-value storage for the specific prefix in the given storage context.
Expand Down
2 changes: 1 addition & 1 deletion boa3/internal/analyser/analyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def analyse(path: str, log: bool = False, fail_fast: bool = False,
CompiledMetadata.set_current_metadata(analyser.metadata)

if compiler_entry:
from boa3.internal.model.imports.builtin import CompilerBuiltin
from boa3.internal.model.imports.compilerbuiltin import CompilerBuiltin
CompilerBuiltin.update_with_analyser(analyser)

# fill symbol table
Expand Down
2 changes: 1 addition & 1 deletion boa3/internal/analyser/astanalyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def get_symbol(self, symbol_id: str,

if is_internal:
from boa3.internal.model import imports
found_symbol = imports.builtin.get_internal_symbol(symbol_id)
found_symbol = imports.compilerbuiltin.get_internal_symbol(symbol_id)
if isinstance(found_symbol, ISymbol):
return found_symbol

Expand Down
12 changes: 10 additions & 2 deletions boa3/internal/analyser/importanalyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ def __init__(self, import_target: str, root_folder: str,
self.is_namespace_package: bool = False
self.recursive_import: bool = False
self._import_identifier: str = import_target

self._get_from_entry: bool = get_entry and (os.path.isfile(import_target) or os.path.isdir(import_target))

from boa3.internal.model.imports.package import Package
self._package: Package | None = None
from boa3.internal.analyser.analyser import Analyser
self._imported_files: dict[str, Analyser] = (already_imported_modules
if isinstance(already_imported_modules, dict)
Expand Down Expand Up @@ -92,6 +95,10 @@ def __init__(self, import_target: str, root_folder: str,
def tree(self) -> ast.AST:
return self._tree

@property
def is_import_deprecated(self) -> bool:
return self._package.is_deprecated if self._package is not None else False

def export_symbols(self, identifiers: list[str] = None) -> dict[str, ISymbol]:
"""
Gets a dictionary that maps each exported symbol with its identifier
Expand Down Expand Up @@ -125,7 +132,7 @@ def update_external_analysed_files(self, external_files: dict):
def _find_package(self, module_origin: str, origin_file: str | None = None):
path: list[str] = module_origin.split(os.sep)

package = imports.builtin.get_package(self._import_identifier)
package = imports.compilerbuiltin.get_package(self._import_identifier)
if hasattr(package, 'symbols'):
if hasattr(package, 'inner_packages'):
# when have symbol and packages with the same id, prioritize symbol
Expand All @@ -134,13 +141,14 @@ def _find_package(self, module_origin: str, origin_file: str | None = None):
else:
self.symbols = package.symbols

self._package = package
self.can_be_imported = True
self.is_builtin_import = True
return

if (os.path.commonpath([self.path, constants.BOA_PACKAGE_PATH]) != constants.BOA_PACKAGE_PATH or
('boa3' in path and constants.PATH_SEPARATOR.join(path[path.index('boa3'):]).startswith('boa3/builtin'))):
# doesn't analyse boa3.builtin packages that aren't included in the imports.builtin as an user module
# doesn't analyse boa3.builtin packages that aren't included in the imports.compilerbuiltin as an user module
import re

inside_python_folder = any(re.search(r'python(\d\.?)*', folder.lower()) for folder in path)
Expand Down
10 changes: 10 additions & 0 deletions boa3/internal/analyser/moduleanalyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,16 @@ def _analyse_module_to_import(self, origin_node: ast.AST, target: str) -> Import
self._log_unresolved_import(origin_node, target)

else:
if analyser.is_import_deprecated:
location_tip = analyser._package.new_location if analyser._package is not None else None
self._log_warning(
CompilerWarning.DeprecatedSymbol(
origin_node.lineno,
origin_node.col_offset,
analyser._import_identifier,
location_tip
)
)
analyser.update_external_analysed_files(self._analysed_files)
return analyser

Expand Down
22 changes: 17 additions & 5 deletions boa3/internal/analyser/typeanalyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from boa3.internal.exception import CompilerError, CompilerWarning
from boa3.internal.model.attribute import Attribute
from boa3.internal.model.builtin.builtin import Builtin
from boa3.internal.model.builtin.builtincallable import IBuiltinCallable
from boa3.internal.model.builtin.method.builtinmethod import IBuiltinMethod
from boa3.internal.model.callable import Callable
from boa3.internal.model.expression import IExpression
Expand Down Expand Up @@ -1187,17 +1188,28 @@ def visit_Call(self, call: ast.Call):
:param call: the python ast function call node
:return: the result type of the called function
"""
is_internal_call = hasattr(call, 'is_internal_call') and call.is_internal_call

if isinstance(call.func, ast.Name):
callable_id: str = call.func.id
is_internal = hasattr(call, 'is_internal_call') and call.is_internal_call
callable_target = self.get_symbol(callable_id, is_internal)
elif isinstance(call.func, ast.Lambda):
self._log_error(
CompilerError.NotSupportedOperation(call.func.lineno, call.func.col_offset, 'lambda function')
)
else:
if isinstance(call.func, ast.Lambda):
self._log_error(
CompilerError.NotSupportedOperation(call.func.lineno, call.func.col_offset, 'lambda function')
)
callable_id, callable_target = self.get_callable_and_update_args(call) # type: str, ISymbol

if callable_target is not None and callable_target.is_deprecated and not is_internal_call:
self._log_warning(
CompilerWarning.DeprecatedSymbol(
call.lineno,
call.col_offset,
callable_id,
callable_target.new_location if isinstance(callable_target, IBuiltinCallable) else None
)
)
callable_target = self.validate_builtin_callable(callable_id, callable_target, call.args)

if not isinstance(callable_target, Callable):
Expand Down Expand Up @@ -1253,7 +1265,7 @@ def visit_Call(self, call: ast.Call):
origin_type_id = cast_types[0].identifier
cast_type_id = cast_types[1].identifier

if not hasattr(call, 'is_internal_call') or not call.is_internal_call:
if not is_internal_call:
self._log_warning(
CompilerWarning.TypeCasting(call.lineno, call.col_offset,
origin_type_id=origin_type_id,
Expand Down
2 changes: 1 addition & 1 deletion boa3/internal/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def _internal_compile(self, path: str, root_folder: str = None, env: str = None,
self._entry_smart_contract = os.path.splitext(filename)[0]

from boa3.internal.compiler.compiledmetadata import CompiledMetadata
from boa3.internal.model.imports.builtin import CompilerBuiltin
from boa3.internal.model.imports.compilerbuiltin import CompilerBuiltin
CompilerBuiltin.reset()
CompiledMetadata.reset()

Expand Down
8 changes: 6 additions & 2 deletions boa3/internal/exception/CompilerWarning.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,18 @@ class DeprecatedSymbol(CompilerWarning):
A warning raised when a deprecated symbol is used.
"""

def __init__(self, line: int, col: int, symbol_id: str):
def __init__(self, line: int, col: int, symbol_id: str, alternative_id: str = None):
self.symbol_id: str = symbol_id
self.alternative_symbol: str | None = alternative_id
super().__init__(line, col)

@property
def _warning_message(self) -> str | None:
if self.symbol_id is not None:
return f'Using deprecated feature: {self.symbol_id}'
msg = f"Using deprecated symbol: '{self.symbol_id}'."
if self.alternative_symbol is not None:
msg += f" Use '{self.alternative_symbol}' instead."
return msg


class InvalidArgument(CompilerWarning):
Expand Down
11 changes: 8 additions & 3 deletions boa3/internal/model/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ class Attribute(IExpression):
:ivar attr_symbol: the found symbol for the attribute
"""

def __init__(self, value: ast.AST | IExpression | Package, attr_name: str,
attr_symbol: ISymbol | None = None, origin: ast.AST | None = None):
super().__init__(origin)
def __init__(self,
value: ast.AST | IExpression | Package,
attr_name: str,
attr_symbol: ISymbol | None = None,
origin: ast.AST | None = None,
deprecated: bool = False
):
super().__init__(origin, deprecated)

self.value: ast.AST | IExpression | Package = value
self.attr_name: str = attr_name
Expand Down
Loading

0 comments on commit 1ebbe22

Please sign in to comment.