Форум сайта python.su
0
В общем, у меня очень расплывчатый и обширный вопрос, поэтому начну с use-case, хотя мне в принципе интересно разобраться в механике реализации системы импортов и создания объектов в реалтайме.
UseCase:
я все еще пишу “транслятор кода\препроцессор” (надеюсь на дня закончить) для проприеритарной среды разработки.
Т.к. основная претензия к текущему положению вещей у меня в отсутствии возможностей для инкапсуляции и полном отсутствии инструментов модульных тестов, иду не по пути парсинга исходников, а поддерживаю полностью живые объекты, чтобы можно было гонять тесты на питоне, не заходя в среду назначения.
Поэтому генерация кода идет по принципу логирования.
Допустим, при запуске вне процесса компиляции (в тестах), этот код ведет себя вполне по-человечьи:
arrY = kArrInt(name='arrY', sequence=[1, 2, 3, 6]) y = kInt(name='y') break_indicies = [0, 2, 3, 3, 3] with For(arr=self.arrX) as seq: for idx, val in enumerate(seq): self.x <<= val with For(arr=arrY) as seq_y: for idx2, val2 in enumerate(seq_y): with If(self.x == val2): check() y <<= val2 with self.subTest(): self.assertEqual( idx2, break_indicies[idx]) with Else(): check() Break()
inc($_for_loop_curr_idx)
%_for_loop_idx[$_for_loop_curr_idx] := 0
while(%_for_loop_idx[$_for_loop_curr_idx] < 5)
$x := %arrX[%_for_loop_idx[$_for_loop_curr_idx]]
inc($_for_loop_curr_idx)
%_for_loop_idx[$_for_loop_curr_idx] := 0
while(%_for_loop_idx[$_for_loop_curr_idx] < 4)
if($x = %arrY[%_for_loop_idx[$_for_loop_curr_idx]])
$y := %arrY[%_for_loop_idx[$_for_loop_curr_idx]]
else
%_for_loop_idx[$_for_loop_curr_idx] := 4
end if
inc(%_for_loop_idx[$_for_loop_curr_idx])
end while
dec($_for_loop_curr_idx)
inc(%_for_loop_idx[$_for_loop_curr_idx])
end while
dec($_for_loop_curr_idx)
@func def method(self, arg=kOut(int)): self.assertEqual( arg.name(), '%_stack_functions_int_arr[0 + %_stack_functions_int_idx' + '[$_stack_functions_int_pointer]]') arg <<= self.int def test_funcs(self): @func def foo(loc: kArg(int, 5)=arr): with For(arr=loc) as seq: for item in seq: self.method(item) foo() # test for excluding from generation without # "calling" it @func def bar(var: int): self.method() bar(1, inline=True) generated_exec = KspObject.generate_all_executables() self.maxDiff = None self.assertEqual( unpack_lines(generated_exec), executables.format(method=Function.get_func_name(self.method), foo=Function.get_func_name(foo)))
init_lines = \ '''on init foo_line bar_line cb body is 4 end on''' release_lines = \ '''on release release end on''' class TestWrapers(DevTest): def setUp(self): Output().refresh() self.var = 4 def cb(self): Output().put(f'cb body is {self.var}') self.var += 1 def runTest(self): @init def foo(): Output().put('foo_line') @init def bar(): Output().put('bar_line') init(self.cb) self.assertEqual(self.var, 4) self.assertEqual( unpack_lines(InitCallback.generate_body()), init_lines) self.assertEqual(self.var, 5) @release def rls(): Output().put('release') self.assertEqual( unpack_lines(ReleaseCallback.generate_body()), release_lines) rls() self.assertEqual(Output().pop(), 'release')
Офлайн
0
приплыли.
Оказывается, DevTest в таком импорте
path = os.path.abspath(os.path.dirname(__file__)) + '/..' sys.path.append(path) path = os.path.abspath(os.path.dirname(__file__)) sys.path.append(path) from mytests import DevTest
from pyksp.compiler.tests.mytests import DevTest
Офлайн
253
Levitanus
И как дальше жить?
LevitanusОчевидно что избавиться от расплывчатости.
очень расплывчатый и обширный вопрос
Офлайн
186
> я все еще пишу “транслятор кода\препроцессор” (надеюсь на дня закончить) для проприеритарной среды разработки.
Что за среда?
Офлайн
0
doza_andя вот так вот ссылку на мануалы брошу, в одном в оглавлении есть раздел “что это за птица”, а второй - актуальный референс по языку
Что за среда разработки?
doza_andс питона на KSP (язык, на котором пишутся скрипты в среде)
транслятор с какого языка на какой?
doza_andпотому что без нормального препроцессора писать на KSP – боль ужасная.
Зачем тут вообще кодогенерация?
doza_andВообще изначально – потому что тот кодогенератор, которым комьюнити польуется сейчас – написан на питоне. Хотел сначала форкнуть его и допиливать под себя, а в процессе решил вообще от него отказаться, и писать с нуля, и без парсинга.
Каким боком тут питон появился?
doza_andда. Только объекты модуля создаются при импорте, в чем и была суть вопроса.
Объекты в питоне и большинстве языков почти всегда в реалтайме создаются, чего тут удивительного?
Офлайн
186
> я вот так вот ссылку на мануалы брошу
Твои мануалы написаны на не понятном языке.
Офлайн
0
Rodegastэмм… вроде обычный технический англицкий)
Твои мануалы написаны на не понятном языке.
Офлайн
221
Levitanusпросто товарищ Rodegast везде где можно бьет кулаком в грудь и кричит что английский не нужен, поэтому не обращай внимания.
эмм… вроде обычный технический англицкий)
Офлайн
0
JOHN_16
P.S. мммм NI

JOHN_16ой, я сколько ржал над идеей, что надо учить китайский, бо все на нем говорить будем) А теперь реально надо за полгода осилить)
английский не нужен
Отредактировано Levitanus (Сен. 6, 2018 16:15:28)
Офлайн
0
короче, пришел я к такому грязноватому решению:
module: simple_test
class Test: count = 0
from simple_test import Test class Script1: Test.count += 1 print(Test.count)
from simple_test import Test class Script2: Test.count += 1 print(Test.count)
from simple_test2 import Script1 from simple_test3 import Script2 from simple_test import Test import importlib import importlib.util Test.count = 0 class Runner: def __init__(self, cls): spec = importlib.util.find_spec(cls.__module__) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) a = Runner(Script1) b = Runner(Script2)
1 2 1 2 [Finished in 0.1s]
Офлайн