Pdf-Files: Fehler beim import von pyPdf

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
ElSids
User
Beiträge: 16
Registriert: Montag 25. Juni 2007, 13:15
Wohnort: Corciano/Italien

Meine Absicht war, den reinen Text von bisweilen sehr kompliziert aufgebauten Pdf-Files (technische Datenblätter, technische Produktdarstellungen, Handbücher von Maschinen usw.) auszuziehen.
Zu diesem Zweck wollte ich pyPdf benutzen, das soviel ich verstanden habe, schon etwas älter ist.

Wie der Name im Titel schon sagt, erhalte ich jedoch beim import von pyPdf folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Documents and Settings/ElCid/Documenti/ovus/snippets/pdf_test.py", line 3, in <module>
    import pyPdf
  File "C:\Python26\Lib\site-packages\pyPdf\__init__.py", line 1, in <module>
    from pdf import PdfFileReader, PdfFileWriter
  File "C:\Python26\Lib\site-packages\pyPdf\pdf.py", line 52, in <module>
    from sets import ImmutableSet
  File "C:\Python26\lib\sets.py", line 85, in <module>
    stacklevel=2)
  File "C:\Python26\lib\warnings.py", line 29, in _show_warning
    file.write(formatwarning(message, category, filename, lineno, line))
TypeError: idle_formatwarning_subproc() takes exactly 4 arguments (5 given)
Betriebssystem: WindowsXP
Python 2.6
pyPdf installiert über pyPdf-1.12.win32.exe (Win32 installer)

In anderen Foren wird als Grund angegeben, dass Python 2.6 bei depreced Modulen diese Warnung ausgibt, die keine Warnung ist, sondern ein error. Da andere allerding mit dem Modul arbeiten (und auch Fragen zu diesem Modul stellten), frage ich mich, wieso ich diese Fehlermeldung erhalte, ob es anderen genauso ergangen ist und wie man dieses beseitigen kann.

Herzlichen Dank für etwaige Hilfestellungen
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Das sieht mir nach einem IDLE Problem aus!
Versuch mal dein Skript über die Kommandozeile zu starten.
ElSids
User
Beiträge: 16
Registriert: Montag 25. Juni 2007, 13:15
Wohnort: Corciano/Italien

Dass es sich um ein Problem in der IDLE handeln könnte, habe ich mehrfach gelesen.

Lasse ich die Datei pdf_test.py, einfach bestehend aus:

Code: Alles auswählen

# -*- coding: UTF-8 -*-

import pyPdf

input1 = pyPdf.PdfFileReader
print "Hallo"
in PythonWin starten, so erhalte ich eine DeprecationWarning:

Code: Alles auswählen

>>> C:\Python26\lib\site-packages\pyPdf\pdf.py:52: DeprecationWarning: the sets module is deprecated
  from sets import ImmutableSet
>>> Hallo
Das Modul "sets" läd in Zeile 83 folgendes Modul:

Code: Alles auswählen

import warnings
warnings.warn("the sets module is deprecated", DeprecationWarning,
                stacklevel=2)
Eine wage Vermutung hat mich den stacklevel auf 0 setzen lassen, was denn auch prompt zu:

Code: Alles auswählen

C:\Python26\lib\sets.py:85: DeprecationWarning: functions overriding warnings.showwarning() must support the 'line' argument
  stacklevel=0)
Hallo
führte. Nur, an diesem Punkt weiß ich nicht weiter. Mein nettes "Hallo" wurde mit einer Warnung ausgedruckt. Jedoch lässt mich diese Warnung vermuten, dass es sich bei pypdf um "Alteisen" ohne Zukunft handelt, oder wie kann ich diese Warnung anders verstehen?
An diesem Punkt stellt sich die Frage, ob es nicht besser wäre, gleich zu wechseln, nur was (ReportLab)? Oder begnüge ich mich weiterhin mit copy and paste?

Jede Empfehlung ist willkommen.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Ich deute den StackTrace so, dass IDLE mit einer DeprecationWarning nicht umgehen kann und deshalb die Exception auslöst.

Eine DeprecationWarning ist IMO kein Grund, um auf ein Modul zu verzichten, allerdings kenne ich mich auf diesem Gebiet auch nicht aus um jetzt sinnvolle Alternativen vorschlagen zu können.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Du könntest natürlichim PyPDF-Code immutableset durch frozenset ersetzen, dann umgehst du die Warnung.

Vllt. die Lösung deines Problems: http://bugs.python.org/issue4043

Wobei das ja eigentlich vor mehr als einem Jahr bereits gefixed wurde.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

SchneiderWeisse hat geschrieben:Vllt. die Lösung deines Problems: http://bugs.python.org/issue4043

Wobei das ja eigentlich vor mehr als einem Jahr bereits gefixed wurde.
Das kuemmert sich aber nur um die IDLE-Seite des Problems. Der OP hat ja auch von der Kommandozeile das Problem.

Ist das denn ueberhaupt die neuste Version von PyPDF? (Ich kenne es nicht.)
ElSids
User
Beiträge: 16
Registriert: Montag 25. Juni 2007, 13:15
Wohnort: Corciano/Italien

Den Bug-Report kannte ich, ebenso wie den Loesungsvorschlag. Jedoch wie SchneiderWeisse bereits sagte, aendert dies nichts an dem Problem. Die DeprecationWarning bleibt bestehen.

Ich denke ganz einfach, dass das Programm "zu alt" ist. Die neueste Version datiert vom
The latest release of pyPdf is version 1.12, released on September 2nd, 2008.
Das Programm selbst ist zu finden unter:
http://pybrary.net/pyPdf/

Ein Anwendungsbeispiel:

Code: Alles auswählen

from pyPdf import PdfFileWriter, PdfFileReader

output = PdfFileWriter()
input1 = PdfFileReader(file("document1.pdf", "rb"))

# print the title of document1.pdf
print "title = %s" % (input1.getDocumentInfo().title)

# add page 1 from input1 to output document, unchanged
output.addPage(input1.getPage(0))

# add page 2 from input1, but rotated clockwise 90 degrees
output.addPage(input1.getPage(1).rotateClockwise(90))

# add page 3 from input1, rotated the other way:
output.addPage(input1.getPage(2).rotateCounterClockwise(90))
# alt: output.addPage(input1.getPage(2).rotateClockwise(270))

# add page 4 from input1, but first add a watermark from another pdf:
page4 = input1.getPage(3)
watermark = PdfFileReader(file("watermark.pdf", "rb"))
page4.mergePage(watermark.getPage(0))

# add page 5 from input1, but crop it to half size:
page5 = input1.getPage(4)
page5.mediaBox.upperRight = (
    page5.mediaBox.getUpperRight_x() / 2,
    page5.mediaBox.getUpperRight_y() / 2
)
output.addPage(page5)

# print how many pages input1 has:
print "document1.pdf has %s pages." % input1.getNumPages()

# finally, write "output" to document-output.pdf
outputStream = file("document-output.pdf", "wb")
output.write(outputStream)
outputStream.close()
Danke fuer die Hinweise. Ich denke, ich werde mich nach etwas anderem umsehen muessen.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Also ich habe vor einiger Zeit auch mal damit rumgespielt und musste nur die paar Zeilen ändern und ich war frei von den deprecation-warnings... Irgendwie glaube ich einfach, dass irgendwas mit deiner Installation oder sonstigem nicht stimmt. Es wäre grundsätzlich mal nicht schlecht, wenn du den Code zeigst, der dieses Problem hervorruft und dazu die passende Fehlermeldung.
ElSids
User
Beiträge: 16
Registriert: Montag 25. Juni 2007, 13:15
Wohnort: Corciano/Italien

Wahrscheinlich war das "Programm" so klein, dass man es durchaus uebersehen konnte. Es ist weiter oben angegeben:

Code: Alles auswählen

# -*- coding: UTF-8 -*-

import pyPdf

input1 = pyPdf.PdfFileReader
print "Hallo"

>>> C:\Python26\lib\site-packages\pyPdf\pdf.py:52: DeprecationWarning: the sets module is deprecated
  from sets import ImmutableSet
>>> Hallo
Den im Bug-Report vorgeschlagene Loesungsweg:
This error is caused by line 27 in run.py:

Code: Alles auswählen

def idle_formatwarning_subproc(message, category, filename, lineno):
needs to be changed to --

Code: Alles auswählen

def idle_formatwarning_subproc(message, category, filename, lineno, 
line=None):
so that the function signature matches that of warnings.formatwarning
habe ich befolgt. Dennoch bleibt die Warnung.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

ElSids hat geschrieben:habe ich befolgt. Dennoch bleibt die Warnung.
Jop, das war auch der Fix für IDLE.

Um die Deprecationwarning auszuschalten, musst du die pdf.py editieren. Dazu im Modul alle "ImmutableSet" mit "frozenset" ersetzen und den Import raus. Das müsste eigentlich reichen.
Mach zur Sicherheit aber vorher ein Backup ;)
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

ms4py hat geschrieben: Um die Deprecationwarning auszuschalten, musst du die pdf.py editieren. Dazu im Modul alle "ImmutableSet" mit "frozenset" ersetzen und den Import raus. Das müsste eigentlich reichen.
Mach zur Sicherheit aber vorher ein Backup ;)
Da musst du nichts weiter machen, als

Code: Alles auswählen

ImmutableSet, Set = frozenset, set
anstelle von "from sets import"
Andererseits ist das nur eine Warnung, die hat keinen Einfluss darauf, wie (gut) dein Programm funktioniert.

hth, Jörg
Wir haben schon 10% vom 21. Jahrhundert hinter uns!
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

b.esser-wisser hat geschrieben:

Code: Alles auswählen

ImmutableSet, Set = frozenset, set
Jap, das ist b.esser ;)
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
ElSids
User
Beiträge: 16
Registriert: Montag 25. Juni 2007, 13:15
Wohnort: Corciano/Italien

Danke für die Tipps. Ich habe sowohl den deinen Ratschlag, ms4py, als auch deinen, b.esser-wisser umgesetzt.

Tatsächlich ergibt dann ein einfaches:

Code: Alles auswählen

 from pyPdf import PdfFileReader
 print "Hello"
keine Warnmeldung mehr aus, sondern grüßt erwartungsgemäß mit "Hallo".

Allerdings zeigt sich in der Praxis sofort ein anderes Problem, das dann mit dem Programm als solchem zusammenhängt.
Bei

Code: Alles auswählen

 from pyPdf import PdfFileReader
 input1 = PdfFileReader(file("Beispiel Datei.pdf", "rb"))
unterbricht das Programm mit folgender Fehlermeldung:

Code: Alles auswählen

Warning (from warnings module):
  File "C:\Python26\lib\site-packages\pyPdf\generic.py", line 216
    int.__init__(self, value)
DeprecationWarning: object.__init__() takes no parameters

Warning (from warnings module):
  File "C:\Python26\lib\site-packages\pyPdf\generic.py", line 406
    str.__init__(self, data)
DeprecationWarning: object.__init__() takes no parameters
,

wobei ich mich dabei an die ersten Zeilen des auf der pyPdf-Seite angegebenen Beispiels halte.
An diesem Punkt weiß ich nicht, ob es weitere Mühe lohnt, das Programm weiter zu sezieren, um auch noch die letzte Unklarheit aus dem Weg zu räumen.
Im Allgemeinen bin ich durchaus bereit, mich mit Programmen länger zu beschäftigen, wenn sich in Zukunft ein nützliches Ergebnis absehen lässt, und wenn ich es mit meinen eher beschränkten Programmierkenntnissen erreichen kann.
Von daher möchte ich mich nicht in einer Sackgasse verrennen und anderer (hilfsbereiter) Leute Zeit rauben.

ElSids
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Was sagt dir diese Warnung: Schau in den Files in angegebener Zeile nach und korrigier das, die Fehlermeldung ist doch mehr als klar.
BlackJack

Wobei es ja nur Warnungen sind. Da wird sich ja wohl hoffentlich der Autor von dem Modul früher oder später drum kümmern.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Hallo,

da ich mit diesem Moduil seit längerem arbeite, kann ich sagen, dass es bei mir (Python 2.6) tadellos und warnungslos funktioniert.
Ich habe auch noch keine brauchbare Alternative gefunden.....
Ich habe einiges geändert und stell das ganze mal hier rein:

http://rapidshare.com/files/364969659/p ... d.zip.html
MD5: 0CE0BC9D0052A505044FCBF824928C5C

Gruß Mathi
abaum
User
Beiträge: 18
Registriert: Freitag 12. Januar 2007, 21:53
Kontaktdaten:

Im Repository wurde der Fehler bereits ausgebessert, allerdings gab es kein Release dazu. Die URL: https://github.com/mfenniak/pyPdf/commits/
Antworten