I'm working on a Python script to generate a report in PDF using PyLatex. I set up a class ReportGeneration.
Inside, a table 'overview_table' is defined. When I try to work with table from 2 functions, it gives me the error: AttributeError: args
A small snippet of the init method:
self.doc = Document()
self.doc.documentclass = Command(
'documentclass',
options=['12pt'],
arguments=['article']
)
# Set up preamble (cannot share code)
self.overview_table = self.doc.create(LongTable("| l | l | l |"))
The first function, that works perfectly when called is as follows:
def set_up_overview(self):
with self.doc.create(Section('Overview')):
self.doc.append(Command('centering'))
with self.overview_table as table:
table.add_hline()
table.add_row(bold("Index"), bold("File Name"), bold("Result"))
table.add_hline()
table.end_table_header()
The second function is as follows:
def add_data_to_report(self):
with self.overview_table as overview_table:
overview_table.add_hline()
Calling the second function crashes the program. I've tried searching for similar errors, but the closest I could get was that __enter__
was not defined. I'm not sure how to proceed from there.
The complete error message is
File "/Users/user/IdeaProjects/report/src/reportgen.py", line 46, in add_data_to_report
with self.overview_table as overview_table:
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/contextlib.py", line 133, in __enter__
del self.args, self.kwds, self.func
AttributeError: args
It'll be great help if someone can explain what went wrong. Thanks!
CodePudding user response:
It seems that the pylatex package has used the @contextlib.contextmanager
decorator on the create
method.
@contextmanager
def create(self, child):
"""Add a LaTeX object to current container, context-manager style.
Args
----
child: `~.Container`
An object to be added to the current container
"""
prev_data = self.data
self.data = child.data # This way append works appends to the child
yield child # allows with ... as to be used as well
self.data = prev_data
self.append(child)
As mentioned in the contextlib documentation,
The function being decorated must return a generator-iterator when called. This iterator must yield exactly one value, which will be bound to the targets in the with statement’s as clause, if any.
This means that you can use the returned value from the create function only once in a context as you have done.
I would recommend you do one of
- do everything you want to do with the overview_table inside a single context (that would be inside the initial
set_up_overview
function in your case) - take a look at the pylatex documentation and see if you can use the values they have set using
self.append(child)
in thecreate
method - add the yielded object as an attribute on your class