mirror of https://github.com/Nonannet/copapy.git
code style fixed and type hints in get_binaries.py fixed
This commit is contained in:
parent
ac98c42761
commit
f97d21e42c
|
|
@ -42,7 +42,7 @@ case RUN_PROG:
|
||||||
rel_entr_point = *(uint32_t*)bytes; bytes += 4;
|
rel_entr_point = *(uint32_t*)bytes; bytes += 4;
|
||||||
printf("RUN_PROG rel_entr_point=%i\n", rel_entr_point);
|
printf("RUN_PROG rel_entr_point=%i\n", rel_entr_point);
|
||||||
entr_point = (int (*)())(executable_memory + rel_entr_point);
|
entr_point = (int (*)())(executable_memory + rel_entr_point);
|
||||||
|
|
||||||
mark_mem_executable(executable_memory, executable_memory_len);
|
mark_mem_executable(executable_memory, executable_memory_len);
|
||||||
int ret = entr_point();
|
int ret = entr_point();
|
||||||
printf("Return value: %i\n", ret);
|
printf("Return value: %i\n", ret);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ def transl_type(t: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
class Node:
|
class Node:
|
||||||
"""A Node represents an computational operation like ADD or other operations
|
"""A Node represents an computational operation like ADD or other operations
|
||||||
like read and write from or to the memory or IOs. In the computation graph
|
like read and write from or to the memory or IOs. In the computation graph
|
||||||
Nodes are connected via Nets.
|
Nodes are connected via Nets.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ def get_nets(*inputs: Iterable[Iterable[Any]]) -> list[Net]:
|
||||||
|
|
||||||
def get_data_layout(variable_list: Iterable[Net], sdb: stencil_database, offset: int = 0) -> tuple[list[tuple[Net, int, int]], int]:
|
def get_data_layout(variable_list: Iterable[Net], sdb: stencil_database, offset: int = 0) -> tuple[list[tuple[Net, int, int]], int]:
|
||||||
"""Get memory layout for the provided variables
|
"""Get memory layout for the provided variables
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
variable_list: Variables to layout
|
variable_list: Variables to layout
|
||||||
sdb: Stencil database for size lookup
|
sdb: Stencil database for size lookup
|
||||||
|
|
@ -184,7 +184,7 @@ def get_data_layout(variable_list: Iterable[Net], sdb: stencil_database, offset:
|
||||||
|
|
||||||
def get_section_layout(section_indexes: Iterable[int], sdb: stencil_database, offset: int = 0) -> tuple[list[tuple[int, int, int]], int]:
|
def get_section_layout(section_indexes: Iterable[int], sdb: stencil_database, offset: int = 0) -> tuple[list[tuple[int, int, int]], int]:
|
||||||
"""Get memory layout for the provided sections
|
"""Get memory layout for the provided sections
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
section_indexes: Sections (by index) to layout
|
section_indexes: Sections (by index) to layout
|
||||||
sdb: Stencil database for size lookup
|
sdb: Stencil database for size lookup
|
||||||
|
|
@ -210,7 +210,7 @@ def get_aux_function_mem_layout(function_names: Iterable[str], sdb: stencil_data
|
||||||
function_names: Function names to layout
|
function_names: Function names to layout
|
||||||
sdb: Stencil database for size lookup
|
sdb: Stencil database for size lookup
|
||||||
offset: Starting offset for layout
|
offset: Starting offset for layout
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Tuple of list of (function_name, start_offset, length) and total length
|
Tuple of list of (function_name, start_offset, length) and total length
|
||||||
"""
|
"""
|
||||||
|
|
@ -320,7 +320,7 @@ def compile_to_dag(node_list: Iterable[Node], sdb: stencil_database) -> tuple[bi
|
||||||
#print(patch.type, patch.addr, binw.Command.PATCH_FUNC, node.name, '->', patch.target_symbol_name)
|
#print(patch.type, patch.addr, binw.Command.PATCH_FUNC, node.name, '->', patch.target_symbol_name)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported: {node.name} {reloc.target_symbol_info} {reloc.target_symbol_name}")
|
raise ValueError(f"Unsupported: {node.name} {reloc.target_symbol_info} {reloc.target_symbol_name}")
|
||||||
|
|
||||||
patch_list.append(patch)
|
patch_list.append(patch)
|
||||||
|
|
||||||
offset += len(data)
|
offset += len(data)
|
||||||
|
|
@ -358,7 +358,7 @@ def compile_to_dag(node_list: Iterable[Node], sdb: stencil_database) -> tuple[bi
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported: {name=} {reloc.target_symbol_info=} {reloc.target_symbol_name=} {reloc.target_section_index}")
|
raise ValueError(f"Unsupported: {name=} {reloc.target_symbol_info=} {reloc.target_symbol_name=} {reloc.target_section_index}")
|
||||||
|
|
||||||
patch_list.append(patch)
|
patch_list.append(patch)
|
||||||
|
|
||||||
#assert False, aux_function_mem_layout
|
#assert False, aux_function_mem_layout
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ def sqrt(x: float | int) -> float: ...
|
||||||
def sqrt(x: variable[Any]) -> variable[float]: ...
|
def sqrt(x: variable[Any]) -> variable[float]: ...
|
||||||
def sqrt(x: NumLike) -> variable[float] | float:
|
def sqrt(x: NumLike) -> variable[float] | float:
|
||||||
"""Square root function
|
"""Square root function
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
x: Input value
|
x: Input value
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Square root of x
|
Square root of x
|
||||||
"""
|
"""
|
||||||
|
|
@ -30,10 +30,10 @@ def sin(x: float | int) -> float: ...
|
||||||
def sin(x: variable[Any]) -> variable[float]: ...
|
def sin(x: variable[Any]) -> variable[float]: ...
|
||||||
def sin(x: NumLike) -> variable[float] | float:
|
def sin(x: NumLike) -> variable[float] | float:
|
||||||
"""Sine function
|
"""Sine function
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
x: Input value
|
x: Input value
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Square root of x
|
Square root of x
|
||||||
"""
|
"""
|
||||||
|
|
@ -47,10 +47,10 @@ def cos(x: float | int) -> float: ...
|
||||||
def cos(x: variable[Any]) -> variable[float]: ...
|
def cos(x: variable[Any]) -> variable[float]: ...
|
||||||
def cos(x: NumLike) -> variable[float] | float:
|
def cos(x: NumLike) -> variable[float] | float:
|
||||||
"""Cosine function
|
"""Cosine function
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
x: Input value
|
x: Input value
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Cosine of x
|
Cosine of x
|
||||||
"""
|
"""
|
||||||
|
|
@ -64,10 +64,10 @@ def tan(x: float | int) -> float: ...
|
||||||
def tan(x: variable[Any]) -> variable[float]: ...
|
def tan(x: variable[Any]) -> variable[float]: ...
|
||||||
def tan(x: NumLike) -> variable[float] | float:
|
def tan(x: NumLike) -> variable[float] | float:
|
||||||
"""Tangent function
|
"""Tangent function
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
x: Input value
|
x: Input value
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Tangent of x
|
Tangent of x
|
||||||
"""
|
"""
|
||||||
|
|
@ -83,10 +83,10 @@ def get_42() -> variable[float]:
|
||||||
|
|
||||||
def abs(x: T) -> T:
|
def abs(x: T) -> T:
|
||||||
"""Absolute value function
|
"""Absolute value function
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
x: Input value
|
x: Input value
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Absolute value of x
|
Absolute value of x
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ class stencil_database():
|
||||||
end_index = symbol.fields['st_size']
|
end_index = symbol.fields['st_size']
|
||||||
|
|
||||||
for reloc in symbol.relocations:
|
for reloc in symbol.relocations:
|
||||||
|
|
||||||
# address to fist byte to patch relative to the start of the symbol
|
# address to fist byte to patch relative to the start of the symbol
|
||||||
patch_offset = reloc.fields['r_offset'] - symbol.fields['st_value'] - start_index
|
patch_offset = reloc.fields['r_offset'] - symbol.fields['st_value'] - start_index
|
||||||
|
|
||||||
|
|
@ -175,7 +175,7 @@ class stencil_database():
|
||||||
patch_offset = pr.fields['r_offset'] - relocation.function_offset - relocation.start + function_offset
|
patch_offset = pr.fields['r_offset'] - relocation.function_offset - relocation.start + function_offset
|
||||||
#print(f"xx {pr.fields['r_offset'] - relocation.function_offset} {relocation.target_symbol_name=} {pr.fields['r_offset']=} {relocation.function_offset=} {relocation.start=} {function_offset=}")
|
#print(f"xx {pr.fields['r_offset'] - relocation.function_offset} {relocation.target_symbol_name=} {pr.fields['r_offset']=} {relocation.function_offset=} {relocation.start=} {function_offset=}")
|
||||||
scale = 1
|
scale = 1
|
||||||
|
|
||||||
if pr.type.endswith('_PLT32') or pr.type.endswith('_PC32'):
|
if pr.type.endswith('_PLT32') or pr.type.endswith('_PC32'):
|
||||||
# S + A - P
|
# S + A - P
|
||||||
mask = 0xFFFFFFFF # 32 bit
|
mask = 0xFFFFFFFF # 32 bit
|
||||||
|
|
@ -233,7 +233,7 @@ class stencil_database():
|
||||||
"""Return recursively all functions called by stencils or by other functions
|
"""Return recursively all functions called by stencils or by other functions
|
||||||
Args:
|
Args:
|
||||||
names: function or stencil names
|
names: function or stencil names
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
set of all sub function names
|
set of all sub function names
|
||||||
"""
|
"""
|
||||||
|
|
@ -266,7 +266,7 @@ class stencil_database():
|
||||||
|
|
||||||
def get_function_code(self, name: str, part: Literal['full', 'start', 'end'] = 'full') -> bytes:
|
def get_function_code(self, name: str, part: Literal['full', 'start', 'end'] = 'full') -> bytes:
|
||||||
"""Returns machine code for a specified function name.
|
"""Returns machine code for a specified function name.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name: function name
|
name: function name
|
||||||
part: part of the function to return ('full', 'start', 'end')
|
part: part of the function to return ('full', 'start', 'end')
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class Target():
|
||||||
"""
|
"""
|
||||||
def __init__(self, arch: str = 'native', optimization: str = 'O3') -> None:
|
def __init__(self, arch: str = 'native', optimization: str = 'O3') -> None:
|
||||||
"""Initialize Target object
|
"""Initialize Target object
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
arch: Target architecture
|
arch: Target architecture
|
||||||
optimization: Optimization level
|
optimization: Optimization level
|
||||||
|
|
@ -30,7 +30,7 @@ class Target():
|
||||||
|
|
||||||
def compile(self, *variables: int | float | variable[int] | variable[float] | variable[bool] | Iterable[int | float | variable[int] | variable[float] | variable[bool]]) -> None:
|
def compile(self, *variables: int | float | variable[int] | variable[float] | variable[bool] | Iterable[int | float | variable[int] | variable[float] | variable[bool]]) -> None:
|
||||||
"""Compiles the code to compute the given variables.
|
"""Compiles the code to compute the given variables.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
variables: Variables to compute
|
variables: Variables to compute
|
||||||
"""
|
"""
|
||||||
|
|
@ -76,7 +76,7 @@ class Target():
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
net: Variable to read
|
net: Variable to read
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Value of the variable
|
Value of the variable
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ uint8_t *executable_memory = NULL;
|
||||||
uint32_t executable_memory_len = 0;
|
uint32_t executable_memory_len = 0;
|
||||||
entry_point_t entr_point = NULL;
|
entry_point_t entr_point = NULL;
|
||||||
int data_offs = 0;
|
int data_offs = 0;
|
||||||
|
|
||||||
void patch(uint8_t *patch_addr, uint32_t patch_mask, int32_t value) {
|
void patch(uint8_t *patch_addr, uint32_t patch_mask, int32_t value) {
|
||||||
uint32_t *val_ptr = (uint32_t*)patch_addr;
|
uint32_t *val_ptr = (uint32_t*)patch_addr;
|
||||||
uint32_t original = *val_ptr;
|
uint32_t original = *val_ptr;
|
||||||
|
|
@ -84,7 +84,7 @@ int parse_commands(uint8_t *bytes) {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
int end_flag = 0;
|
int end_flag = 0;
|
||||||
uint32_t rel_entr_point = 0;
|
uint32_t rel_entr_point = 0;
|
||||||
|
|
||||||
while(!end_flag) {
|
while(!end_flag) {
|
||||||
command = *(uint32_t*)bytes;
|
command = *(uint32_t*)bytes;
|
||||||
bytes += 4;
|
bytes += 4;
|
||||||
|
|
@ -96,14 +96,14 @@ int parse_commands(uint8_t *bytes) {
|
||||||
LOG("ALLOCATE_DATA size=%i mem_addr=%p\n", size, (void*)data_memory);
|
LOG("ALLOCATE_DATA size=%i mem_addr=%p\n", size, (void*)data_memory);
|
||||||
if (!update_data_offs()) end_flag = -4;
|
if (!update_data_offs()) end_flag = -4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COPY_DATA:
|
case COPY_DATA:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
LOG("COPY_DATA offs=%i size=%i\n", offs, size);
|
LOG("COPY_DATA offs=%i size=%i\n", offs, size);
|
||||||
memcpy(data_memory + offs, bytes, size); bytes += size;
|
memcpy(data_memory + offs, bytes, size); bytes += size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ALLOCATE_CODE:
|
case ALLOCATE_CODE:
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
executable_memory = allocate_executable_memory(size);
|
executable_memory = allocate_executable_memory(size);
|
||||||
|
|
@ -112,14 +112,14 @@ int parse_commands(uint8_t *bytes) {
|
||||||
//LOG("# d %i c %i off %i\n", data_memory, executable_memory, data_offs);
|
//LOG("# d %i c %i off %i\n", data_memory, executable_memory, data_offs);
|
||||||
if (!update_data_offs()) end_flag = -4;
|
if (!update_data_offs()) end_flag = -4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COPY_CODE:
|
case COPY_CODE:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
LOG("COPY_CODE offs=%i size=%i\n", offs, size);
|
LOG("COPY_CODE offs=%i size=%i\n", offs, size);
|
||||||
memcpy(executable_memory + offs, bytes, size); bytes += size;
|
memcpy(executable_memory + offs, bytes, size); bytes += size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_FUNC:
|
case PATCH_FUNC:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
patch_mask = *(uint32_t*)bytes; bytes += 4;
|
patch_mask = *(uint32_t*)bytes; bytes += 4;
|
||||||
|
|
@ -129,7 +129,7 @@ int parse_commands(uint8_t *bytes) {
|
||||||
offs, patch_mask, patch_scale, value);
|
offs, patch_mask, patch_scale, value);
|
||||||
patch(executable_memory + offs, patch_mask, value / patch_scale);
|
patch(executable_memory + offs, patch_mask, value / patch_scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_OBJECT:
|
case PATCH_OBJECT:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
patch_mask = *(uint32_t*)bytes; bytes += 4;
|
patch_mask = *(uint32_t*)bytes; bytes += 4;
|
||||||
|
|
@ -166,13 +166,13 @@ int parse_commands(uint8_t *bytes) {
|
||||||
entr_point = (entry_point_t)(executable_memory + rel_entr_point);
|
entr_point = (entry_point_t)(executable_memory + rel_entr_point);
|
||||||
mark_mem_executable(executable_memory, executable_memory_len);
|
mark_mem_executable(executable_memory, executable_memory_len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RUN_PROG:
|
case RUN_PROG:
|
||||||
LOG("RUN_PROG\n");
|
LOG("RUN_PROG\n");
|
||||||
int ret = entr_point();
|
int ret = entr_point();
|
||||||
BLOG("Return value: %i\n", ret);
|
BLOG("Return value: %i\n", ret);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case READ_DATA:
|
case READ_DATA:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
|
|
@ -197,7 +197,7 @@ int parse_commands(uint8_t *bytes) {
|
||||||
LOG("END_COM\n");
|
LOG("END_COM\n");
|
||||||
end_flag = 1;
|
end_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG("Unknown command\n");
|
LOG("Unknown command\n");
|
||||||
end_flag = -1;
|
end_flag = -1;
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ if __name__ == "__main__":
|
||||||
# Scalar arithmetic:
|
# Scalar arithmetic:
|
||||||
types = ['int', 'float']
|
types = ['int', 'float']
|
||||||
ops = ['add', 'sub', 'mul', 'div', 'floordiv', 'gt', 'ge', 'eq', 'ne', 'pow']
|
ops = ['add', 'sub', 'mul', 'div', 'floordiv', 'gt', 'ge', 'eq', 'ne', 'pow']
|
||||||
int_ops = ['bwand', 'bwor', 'bwxor', 'lshift', 'rshift']
|
int_ops = ['bwand', 'bwor', 'bwxor', 'lshift', 'rshift']
|
||||||
|
|
||||||
for t1 in types:
|
for t1 in types:
|
||||||
code += get_result_stubs1(t1)
|
code += get_result_stubs1(t1)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from copapy import variable, NumLike
|
from copapy import NumLike
|
||||||
from copapy.backend import Write, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import copapy as cp
|
import copapy as cp
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from copapy import variable, NumLike
|
from copapy import NumLike
|
||||||
from copapy.backend import Write, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
|
|
@ -26,7 +26,7 @@ def check_for_qemu() -> bool:
|
||||||
command = qemu_command + ['--version']
|
command = qemu_command + ['--version']
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf8', check=False)
|
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf8', check=False)
|
||||||
except:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
return result.returncode == 0
|
return result.returncode == 0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ def test_fine():
|
||||||
cp.sin(c_f),
|
cp.sin(c_f),
|
||||||
cp.cos(c_f),
|
cp.cos(c_f),
|
||||||
cp.tan(c_f)) # , c_i & 3)
|
cp.tan(c_f)) # , c_i & 3)
|
||||||
|
|
||||||
ret_refe = (a_f ** 2,
|
ret_refe = (a_f ** 2,
|
||||||
a_i ** -1,
|
a_i ** -1,
|
||||||
cp.sqrt(a_i),
|
cp.sqrt(a_i),
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,4 @@ def test_readme_example():
|
||||||
assert tg.read_value(e) == pytest.approx(cp.sqrt(0.87), 0.001) # pyright: ignore[reportUnknownMemberType]
|
assert tg.read_value(e) == pytest.approx(cp.sqrt(0.87), 0.001) # pyright: ignore[reportUnknownMemberType]
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_readme_example()
|
test_readme_example()
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import Any
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from urllib.request import urlopen, Request
|
from urllib.request import urlopen, Request
|
||||||
|
|
@ -5,13 +6,13 @@ from urllib.request import urlopen, Request
|
||||||
OWNER = "Nonannet"
|
OWNER = "Nonannet"
|
||||||
REPO = "copapy"
|
REPO = "copapy"
|
||||||
|
|
||||||
def fetch_json(url: str):
|
def fetch_json(url: str) -> Any:
|
||||||
req = Request(url, headers={"User-Agent": "Python"})
|
req = Request(url, headers={"User-Agent": "Python"})
|
||||||
with urlopen(req, timeout=10) as resp:
|
with urlopen(req, timeout=10) as resp:
|
||||||
assert resp.status == 200
|
assert resp.status == 200
|
||||||
return json.load(resp)
|
return json.load(resp)
|
||||||
|
|
||||||
def download_file(url: str, dest_path: str):
|
def download_file(url: str, dest_path: str) -> None:
|
||||||
req = Request(url, headers={"User-Agent": "Python"})
|
req = Request(url, headers={"User-Agent": "Python"})
|
||||||
with urlopen(req, timeout=30) as resp, open(dest_path, "wb") as f:
|
with urlopen(req, timeout=30) as resp, open(dest_path, "wb") as f:
|
||||||
f.write(resp.read())
|
f.write(resp.read())
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
from copapy import variable
|
from copapy import variable
|
||||||
from copapy.backend import Write, compile_to_dag, stencil_db_from_package
|
from copapy.backend import Write, compile_to_dag, stencil_db_from_package
|
||||||
import copapy as cp
|
|
||||||
from copapy._binwrite import Command
|
from copapy._binwrite import Command
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue