-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python-генератор кода JS-дескрипторов на основе MADescriptionProvider #131
Conversation
|
||
# Add header | ||
js_lines = [] | ||
js_lines.append(f"import {{ MAContainer }} from '{magritte_js_import_prefix}descriptions/MAContainer.js';") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Импортов с одной стороны маловато (например, отсутствует MADateAndTimeDescription
, который явно понадобится), а с другой - они захардкожены (и потому есть MAElementDescription
, который абстрактный и, соответственно, не используется в реальных дескрипторах).
Я прошу в процессе транспиляции собрать set из фактически используемых дескрипторов, построить из них какой-нибудь import_lines
и вставить его здесь (предполагая, что имя класса соответствует имени файла, конечно). Так мы вставим именно то, что фактически используется.
- импортировать фактически используемые дескрипторы
js_variable_name = MADescriptionTranspiler_JS._MADescriptorTranspiler_JS_Visitor.variableNameByDescriptionName(description.name, description_names_mapping_to_js) | ||
|
||
# Transpile to JS | ||
descriptor_instantiate_lines.append(f'const {js_variable_name} = new MAContainer();') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не MAContainer
, а тот контейнер, который используется в транспилируемом дескрипторе.
Вдруг там MAPriorityContainer
? Или ещё какой-нибудь, который мы добавим в будущем (и кастомные контейнеры вполне вероятны - я уже обдумывал такую возможность).
В общем, что-то типа str(descriptor.descriptor.kind)
выглядит более логичным, наверное. Или str(descriptor.class)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вот это лучше
def type(self): |
|
||
def register_description(self, aDescription: MADescription): | ||
""" | ||
Should be called inside register_description only. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
не понял смысл этой строки - звучит как призыв к бесконечной рекурсии
self._descriptions_by_model_name[model_name] = aDescription | ||
self._all_descriptions.append(aDescription) | ||
|
||
def instatiate_descriptions(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
насколько я понимаю, в Python абстрактные методы принято обозначать декоратором abstractmethod
из модуля abc
("abstract base class").
Документация: https://docs.python.org/3/library/abc.html
Пример: https://www.geeksforgeeks.org/abstract-classes-in-python/
def visitDescription(self, anObject: MADescription): | ||
super().visitDescription(anObject) | ||
self._options_dict.update({ | ||
'name': self.valueToJsonString(anObject.name), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
стОит в явном виде выделить список импортируемых полей в качестве настройки транспилятора.
У дескрипторов есть метадескрипторы, и в идеале, чтение значений надо бы делать через аксессоры метадескрипторов.
if value is None: | ||
return 'undefined' | ||
else: | ||
return json.dumps(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
У нас же есть специальный визитор для конверсии в json-значения.
Хочется воспользоваться именно им, чтобы, например, вопросы типа "а как сохранять дату, время и таймстемп" инкапсулировать в этом визиторе.
singleton_key = 'singleton' | ||
if singleton_key in kwargs: | ||
singleton = kwargs[singleton_key] | ||
kwargs.pop(singleton_key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pop
возвращает удалённое значение, так что можно совместить с предыдущей строкой
>>> d = {"one":1, "two": 2}
>>> v = d.pop('two')
>>> v
2
>>> d
{'one': 1}
from Magritte.descriptions.MADescription_class import MADescription | ||
|
||
|
||
class MADescriptionProviderMetaSingleton(type): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Судя по коду - это универсальный метакласс для синглтонов, а не только для провайдеров.
Красивое решение!
Может стОит его назвать MAMetaSingleton
или даже MetaSingleton
?
Он-то может обеспечить синглтонность любому классу, не только провайдеру.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
С синглетонностью там другая потенциальная бурильня, а именно параметры в конструкторах провайдера, типа validateModels.
…возможность базовой настройки транспилируемых полей дескрипторов)
Связан с https://git.wizn.tech/nutcracker/nutcracker-backend/-/merge_requests/18