Skip to content
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

Merged
merged 13 commits into from
Jul 15, 2024

Conversation

konstantin-kalinin-wizn-tech
Copy link
Collaborator


# Add header
js_lines = []
js_lines.append(f"import {{ MAContainer }} from '{magritte_js_import_prefix}descriptions/MAContainer.js';")
Copy link
Owner

@Assargadon Assargadon Jul 9, 2024

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();')
Copy link
Owner

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).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот это лучше


def register_description(self, aDescription: MADescription):
"""
Should be called inside register_description only.
Copy link
Owner

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):
Copy link
Owner

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),
Copy link
Owner

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)
Copy link
Owner

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)
Copy link
Owner

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):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Судя по коду - это универсальный метакласс для синглтонов, а не только для провайдеров.
Красивое решение!

Может стОит его назвать MAMetaSingleton или даже MetaSingleton ?
Он-то может обеспечить синглтонность любому классу, не только провайдеру.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

С синглетонностью там другая потенциальная бурильня, а именно параметры в конструкторах провайдера, типа validateModels.

@Assargadon Assargadon merged commit 596dec4 into python_magritte Jul 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants