10-09-2022, 12:45 PM | #31 |
Wizard
Posts: 1,120
Karma: 1954138
Join Date: Aug 2015
Device: Kindle
|
I am getting the following error while trying to show the template tester:
Code:
calibre, version 6.6.1 ERROR: Unhandled exception: <b>AttributeError</b>:'BuiltinAdd' object has no attribute 'is_python' calibre 6.6.1* embedded-python: True Linux-5.15.0-48-generic-x86_64-with-glibc2.35 Linux ('64bit', 'ELF') ('Linux', '5.15.0-48-generic', '#54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022') Python 3.10.1 Interface language: None Successfully initialized third party plugins: Category Tags (0, 2, 7) && Editor Chains (0, 5, 4) && Favourites Menu (1, 2, 0) && Find Duplicates (1, 9, 7) && Goodreads (1, 7, 0) && Import List (1, 8, 4) && Last Modified (0, 8, 4) && Manage Series (1, 4, 0) && Reading List (1, 14, 0) && View Manager (1, 9, 0) Traceback (most recent call last): File "/home/______/calibre-6.6.1/src/calibre/gui2/actions/show_template_tester.py", line 47, in show_template_editor t = TemplateDialog(self.gui, self.previous_text, File "/home/______/calibre-6.6.1/src/calibre/gui2/dialogs/template_dialog.py", line 365, in __init__ self.function_type_string(f, longform=False)), f) File "/home/______/calibre-6.6.1/src/calibre/gui2/dialogs/template_dialog.py", line 710, in function_type_string if self.all_functions[name].is_python: AttributeError: 'BuiltinAdd' object has no attribute 'is_python' |
10-09-2022, 12:56 PM | #32 | |
Grand Sorcerer
Posts: 11,789
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
|
|
Advert | |
|
10-09-2022, 01:07 PM | #33 |
Wizard
Posts: 1,120
Karma: 1954138
Join Date: Aug 2015
Device: Kindle
|
OK. It is working now. So far, so good
|
10-09-2022, 02:12 PM | #34 |
Chalut o/
Posts: 411
Karma: 145324
Join Date: Dec 2017
Device: Kobo
|
Oh, arguments, nice, tanks.
Work good. Well, I'll see what I can do but it looks incredible. Frankly, you make black magic with all that thing of template language. |
10-10-2022, 02:51 AM | #35 |
Chalut o/
Posts: 411
Karma: 145324
Join Date: Dec 2017
Device: Kobo
|
And after a night's sleep, I just realized the inconsistency of using the arguments for python:.
*inhale, sigh* In fact, I think I even misunderstood the purpose of python template (it's an alternative form to Stored, not a 3rd option totally inedite). If you think that deleting them would improve the code, go ahead. Also, I was going to say that syntax highlighting is possible, since "Action Chains" does it in its module editor... but it uses something different (TextEdit from calibre.gui2.tweak_book.editor.text), so no, crap. At least, maybe highlight python: to identify what we are in. ... Maybe an idea, I'm looking at it. EDIT: And, it works. Spoiler:
Last edited by un_pogaz; 10-10-2022 at 06:55 AM. |
Advert | |
|
10-10-2022, 10:13 AM | #36 | ||
Grand Sorcerer
Posts: 11,789
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
All this opens the question "What is the difference between a python template and a python formatter function? Good question. Formatter functions can "see" into the formatter and easily use existing formatter builtin functions, but templates cannot. If I had thought of python templates years ago perhaps I wouldn't have built the user-defined function mechanism. But we have it now and it is used, so it can't go away or be changed. Quote:
I didn't solve the problem of highlighting the mode indicator. EDIT: Attached is template_dialog.py with python syntax highlighting. Last edited by chaley; 10-10-2022 at 10:15 AM. |
||
10-10-2022, 11:58 AM | #37 |
Grand Sorcerer
Posts: 11,789
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
The implementation is in my github repo. I did a pull request and am waiting for feedback from Kovid.
|
10-10-2022, 12:00 PM | #38 |
Grand Sorcerer
Posts: 11,789
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Moderator Notice
Moved to the development forum |
10-10-2022, 01:43 PM | #39 | |
Chalut o/
Posts: 411
Karma: 145324
Join Date: Dec 2017
Device: Kobo
|
What? You can we pass arguments to the GPM?
*look and test* Code:
program: arguments(arg0=0, arg1=1, arg2=2); return strcat(arg0,' | ',arg1,' | ',arg2); Code:
program: _test('gfgfgh', 456) O_o HOLY SH**!!!! But it's killer!! It changes so much all... Oh god. *look the manual* Ugh, I missed it. Well, I need to re-read this page again. Quote:
Last edited by un_pogaz; 10-10-2022 at 01:45 PM. |
|
10-10-2022, 04:34 PM | #40 |
Grand Sorcerer
Posts: 11,789
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
@un_pogaz: thanks for the fixes.
I pushed changes to my repo to solve the "python:|program:" not on line one problem. |
10-11-2022, 11:48 AM | #41 |
Grand Sorcerer
Posts: 11,789
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
@kovid has accepted the changes. However, he made a good suggestion that I will implement, which changes the signature of the evaluate function. He suggests:
Code:
python: def evaluate(book, ctx): The context object is an instance of class defined in calibre.utils.formatter, which I have currently defined as: Code:
class PythonTemplateContext(object): def __init__(self, **kwargs): # Set attributes we already know must exist. self.db = None self.arguments = None self.globals = None # Create/set attributes from the named parameters. Doing it this way we # aren't required to change the signature of __init__ if we add # attributes in the future. However, if a user depends upon the existence # of some attribute and the context creator doesn't supply it then the # user will get an AttributeError exception. for k,v in kwargs.items(): setattr(self, k, v) EDIT: changes are in my repo and submitted to Kovid. Last edited by chaley; 10-11-2022 at 12:18 PM. |
10-11-2022, 12:21 PM | #42 |
Grand Sorcerer
Posts: 11,789
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Here is the example python template from earlier in the thread, updated to use the new signature.
Code:
python: def evaluate(book, context): if book.series is None: return '' ans = set() db = context.db for id_ in db.search_getting_ids(f'series:"={book.series}"', ''): ans.update([v.strip() for v in db.new_api.field_for('author_sort', id_).split('&')]) return ', '.join(v.replace(',', ';') for v in sorted(ans)) Last edited by chaley; 10-11-2022 at 12:24 PM. |
10-11-2022, 12:27 PM | #43 |
Chalut o/
Posts: 411
Karma: 145324
Join Date: Dec 2017
Device: Kobo
|
Yep. Sounds much better.
However, not sure if passing the named argument as an attribute is the best. I'd see more of a ctx.kwargs attribute to being able to process it as you wants. Beyond the minor risk of collision in the future, using attributes means using getattr(ctx, 'name', default) which seems less elegant than ctx.kwargs as a dict, which can be used in a more dynamic way. Unless it is usual in python to pass kwargs arguments as attributes for a class. |
10-11-2022, 12:48 PM | #44 | |
Wizard
Posts: 1,120
Karma: 1954138
Join Date: Aug 2015
Device: Kindle
|
Quote:
|
|
10-11-2022, 12:48 PM | #45 | |
Grand Sorcerer
Posts: 11,789
Karma: 7029971
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
I defined PythonTemplateContext the way I did because I am worried that someone might define a context outside of base calibre (where I can't see it). I don't know why someone would do that, but it is possible. That is why PythonTemplateContext.__init__() uses **kwargs. If and when we add items to the context we pass them to PythonTemplateContext.__init__() as named parameters that are converted to attributes by __init__. This way adding new attributes to the context object won't break the plugin code because __init__'s signature doesn't change. Of course the new attributes won't be there, but that might be OK for the plugin. I put in ctx.attributes() so someone could 'inspect' what attributes are in the context object. |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Python functions in database and calibre 5 | Terisa de morgan | Calibre | 7 | 09-27-2020 02:52 AM |
A little help with template functions in a composite column, please! | mopkin | Library Management | 2 | 11-05-2019 11:07 PM |
Using built-in template functions in a custom template function | ilovejedd | Library Management | 4 | 01-28-2018 12:20 PM |
Rules, templates, and functions for column coloring and composed icons | readin | Library Management | 7 | 08-11-2016 04:41 PM |
template: if one of the tag is something... maybe contains or in_list functions | fxp33 | Calibre | 4 | 07-19-2014 05:18 AM |