src/reportlab/lib/utils.py
author robin <robin@reportlab.com>
Tue, 07 Mar 2017 10:00:34 +0000
changeset 4330 617ffa6bbdc8
parent 4295 926ce83af2d7
child 4336 d39c63b164bc
permissions -rw-r--r--
changes for release 3.4.0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4330
617ffa6bbdc8 changes for release 3.4.0
robin <robin@reportlab.com>
parents: 4295
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2017
494
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 474
diff changeset
     2
#see license.txt for license details
2625
71abbda1f58c reportlab.lib: break out rltempfile.py to avoid rl_accel imports
rgbecker
parents: 2565
diff changeset
     3
# $URI:$
4252
fe660f227cac changes for release 3.3.0
robin
parents: 4241
diff changeset
     4
__version__='3.3.0'
3029
eded59f94021 adding docstrings to lib
andy
parents: 3028
diff changeset
     5
__doc__='''Gazillions of miscellaneous internal utility functions'''
562
6c9408ec3302 Minor neglectable changes.
dinu_gherman
parents: 519
diff changeset
     6
3971
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
     7
import os, sys, imp, time, types
3850
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
     8
from base64 import decodestring as base64_decodestring, encodestring as base64_encodestring
3820
47edc5ad9dc6 move utils.py builtins defs to __init__.py
robin
parents: 3817
diff changeset
     9
from reportlab import isPy3
2499
11bc8441ec51 legends.py: fix 2.1 compatibility problem
rgbecker
parents: 2497
diff changeset
    10
from reportlab.lib.logger import warnOnce
3781
df8b57380768 import from reportlab.lib.lib.rl_accel
robin
parents: 3765
diff changeset
    11
from reportlab.lib.rltempfile import get_rl_tempfile, get_rl_tempdir, _rl_getuid
3180
349e9644fce8 reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents: 3171
diff changeset
    12
3796
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
    13
try:
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
    14
    import cPickle as pickle
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
    15
except ImportError:
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
    16
    import pickle
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
    17
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
    18
try:
3796
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
    19
    from hashlib import md5
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
    20
except ImportError:
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
    21
    import md5
2902
f15ac27dc73f reportlab: add in RGBA functionality for sensible images
rgbecker
parents: 2838
diff changeset
    22
4237
47d6aa9c4b7b add isPyPy boolean to reportlab.lib.utils
robin
parents: 4181
diff changeset
    23
try:
47d6aa9c4b7b add isPyPy boolean to reportlab.lib.utils
robin
parents: 4181
diff changeset
    24
    import platform
47d6aa9c4b7b add isPyPy boolean to reportlab.lib.utils
robin
parents: 4181
diff changeset
    25
    isPyPy = platform.python_implementation()=='PyPy'
47d6aa9c4b7b add isPyPy boolean to reportlab.lib.utils
robin
parents: 4181
diff changeset
    26
except:
47d6aa9c4b7b add isPyPy boolean to reportlab.lib.utils
robin
parents: 4181
diff changeset
    27
    isPyPy = False
47d6aa9c4b7b add isPyPy boolean to reportlab.lib.utils
robin
parents: 4181
diff changeset
    28
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    29
def isFunction(v):
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    30
    return type(v) == type(isFunction)
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    31
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    32
class c:
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    33
    def m(self): pass
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    34
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    35
def isMethod(v,mt=type(c.m)):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    36
    return type(v) == mt
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    37
del c
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    38
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    39
def isModule(v):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    40
    return type(v) == type(sys)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    41
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    42
def isSeq(v,_st=(tuple,list)):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    43
    return isinstance(v,_st)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    44
3834
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    45
def isNative(v):
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    46
    return isinstance(v, str)
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    47
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    48
#isStr is supposed to be for arbitrary stringType
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    49
#isBytes for bytes strings only
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    50
#isUnicode for proper unicode
3765
a7e7cd6e0003 renderPM.py now works to produce a pmout at least
robin
parents: 3741
diff changeset
    51
if isPy3:
4076
777af896ef28 utils.py: fix up isNonPrimitiveType for None
robin
parents: 4067
diff changeset
    52
    _rl_NoneType=type(None)
3920
50a1ff0c640a utils.py: added unicodeT bytesT strTypes
robin
parents: 3911
diff changeset
    53
    bytesT = bytes
50a1ff0c640a utils.py: added unicodeT bytesT strTypes
robin
parents: 3911
diff changeset
    54
    unicodeT = str
50a1ff0c640a utils.py: added unicodeT bytesT strTypes
robin
parents: 3911
diff changeset
    55
    strTypes = (str,bytes)
3796
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
    56
    def _digester(s):
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
    57
        return md5(s if isBytes(s) else s.encode('utf8')).hexdigest()
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
    58
3911
8f0da55a18ba utils.py: add enc args to converters
robin
parents: 3899
diff changeset
    59
    def asBytes(v,enc='utf8'):
8f0da55a18ba utils.py: add enc args to converters
robin
parents: 3899
diff changeset
    60
        return v if isinstance(v,bytes) else v.encode(enc)
3834
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    61
3911
8f0da55a18ba utils.py: add enc args to converters
robin
parents: 3899
diff changeset
    62
    def asUnicode(v,enc='utf8'):
8f0da55a18ba utils.py: add enc args to converters
robin
parents: 3899
diff changeset
    63
        return v if isinstance(v,str) else v.decode(enc)
3849
8ff9b1fb92cd utils.py: fix isUnicode, rename fileName2Utf8-->fileName2FSEnc
robin
parents: 3838
diff changeset
    64
4022
97f0a5833711 utils.py: added asUnicodeEx
robin
parents: 4016
diff changeset
    65
    def asUnicodeEx(v,enc='utf8'):
97f0a5833711 utils.py: added asUnicodeEx
robin
parents: 4016
diff changeset
    66
        return v if isinstance(v,str) else v.decode(enc) if isinstance(v,bytes) else str(v)
97f0a5833711 utils.py: added asUnicodeEx
robin
parents: 4016
diff changeset
    67
4016
59d017e4c80a utils.py: add enc(oding) argument to asNative
robin
parents: 4008
diff changeset
    68
    def asNative(v,enc='utf8'):
59d017e4c80a utils.py: add enc(oding) argument to asNative
robin
parents: 4008
diff changeset
    69
        return asUnicode(v,enc=enc)
3834
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    70
4004
ebd460ef8d2f rename utils.py UniChr --> uniChr
robin
parents: 3998
diff changeset
    71
    uniChr = chr
3838
1ccb599057b1 utils.py: added int2Byte
robin
parents: 3834
diff changeset
    72
1ccb599057b1 utils.py: added int2Byte
robin
parents: 3834
diff changeset
    73
    def int2Byte(i):
1ccb599057b1 utils.py: added int2Byte
robin
parents: 3834
diff changeset
    74
        return bytes([i])
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    75
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    76
    def isStr(v):
3834
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
    77
        return isinstance(v, (str,bytes))
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    78
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    79
    def isBytes(v):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    80
        return isinstance(v, bytes)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    81
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    82
    def isUnicode(v):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    83
        return isinstance(v, str)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    84
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
    85
    def isClass(v):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    86
        return isinstance(v, type)
3964
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
    87
3971
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
    88
    def isNonPrimitiveInstance(x):
4076
777af896ef28 utils.py: fix up isNonPrimitiveType for None
robin
parents: 4067
diff changeset
    89
        return not isinstance(x,(float,int,type,tuple,list,dict,str,bytes,complex,bool,slice,_rl_NoneType,
3971
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
    90
            types.FunctionType,types.LambdaType,types.CodeType,
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
    91
            types.MappingProxyType,types.SimpleNamespace,
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
    92
            types.GeneratorType,types.MethodType,types.BuiltinFunctionType,
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
    93
            types.BuiltinMethodType,types.ModuleType,types.TracebackType,
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
    94
            types.FrameType,types.GetSetDescriptorType,types.MemberDescriptorType))
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
    95
3964
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
    96
    def instantiated(v):
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
    97
        return not isinstance(v,type)
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
    98
3802
f94f11bbccea utils.py: added ascii_lowercase
robin
parents: 3796
diff changeset
    99
    from string import ascii_letters, ascii_uppercase, ascii_lowercase
3814
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   100
3880
79d10ac7de19 utils.py: add getStringIO
robin
parents: 3874
diff changeset
   101
    from io import BytesIO, StringIO
3814
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   102
    def getBytesIO(buf=None):
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   103
        '''unified StringIO instance interface'''
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   104
        if buf:
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   105
            return BytesIO(buf)
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   106
        return BytesIO()
3899
58aa34ad7b37 utils.py: added _bytesIOType and used in ImageReader
robin
parents: 3895
diff changeset
   107
    _bytesIOType = BytesIO 
3814
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   108
3880
79d10ac7de19 utils.py: add getStringIO
robin
parents: 3874
diff changeset
   109
    def getStringIO(buf=None):
79d10ac7de19 utils.py: add getStringIO
robin
parents: 3874
diff changeset
   110
        '''unified StringIO instance interface'''
79d10ac7de19 utils.py: add getStringIO
robin
parents: 3874
diff changeset
   111
        if buf:
79d10ac7de19 utils.py: add getStringIO
robin
parents: 3874
diff changeset
   112
            return StringIO(buf)
79d10ac7de19 utils.py: add getStringIO
robin
parents: 3874
diff changeset
   113
        return StringIO()
79d10ac7de19 utils.py: add getStringIO
robin
parents: 3874
diff changeset
   114
3814
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   115
    def bytestr(x,enc='utf8'):
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   116
        if isinstance(x,str):
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   117
            return x.encode(enc)
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   118
        elif isinstance(x,bytes):
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   119
            return x
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   120
        else:
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   121
            return str(x).encode(enc)
3850
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
   122
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
   123
    def encode_label(args):
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
   124
        return base64_encodestring(pickle.dumps(args)).strip().decode('latin1')
3850
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
   125
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
   126
    def decode_label(label):
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
   127
        return pickle.loads(base64_decodestring(label.encode('latin1')))
3859
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   128
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   129
    def rawUnicode(s):
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   130
        '''converts first 256 unicodes 1-1'''
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   131
        return s.decode('latin1') if not isinstance(s,str) else s
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   132
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   133
    def rawBytes(s):
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   134
        '''converts first 256 unicodes 1-1'''
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   135
        return s.encode('latin1') if isinstance(s,str) else s
3870
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   136
    import builtins
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   137
    rl_exec = getattr(builtins,'exec')
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   138
    del builtins
3874
1c3e56cd3a65 utils.py: fix char2int to handle python3's insanity
robin
parents: 3870
diff changeset
   139
    def char2int(s):
1c3e56cd3a65 utils.py: fix char2int to handle python3's insanity
robin
parents: 3870
diff changeset
   140
        return  s if isinstance(s,int) else ord(s if isinstance(s,str) else s.decode('latin1'))
3895
eac0863c605c utils.py: added an rl_reraise function and fix annotateException
robin
parents: 3880
diff changeset
   141
    def rl_reraise(t, v, b=None):
eac0863c605c utils.py: added an rl_reraise function and fix annotateException
robin
parents: 3880
diff changeset
   142
        if v.__traceback__ is not b:
eac0863c605c utils.py: added an rl_reraise function and fix annotateException
robin
parents: 3880
diff changeset
   143
            raise v.with_traceback(b)
eac0863c605c utils.py: added an rl_reraise function and fix annotateException
robin
parents: 3880
diff changeset
   144
        raise v
4005
b7dee7fcd927 utils.py: move xrange hack to reportlab.__init__, add rl_add_builtins utility
robin
parents: 4004
diff changeset
   145
    def rl_add_builtins(**kwd):
b7dee7fcd927 utils.py: move xrange hack to reportlab.__init__, add rl_add_builtins utility
robin
parents: 4004
diff changeset
   146
        import builtins
b7dee7fcd927 utils.py: move xrange hack to reportlab.__init__, add rl_add_builtins utility
robin
parents: 4004
diff changeset
   147
        for k,v in kwd.items():
b7dee7fcd927 utils.py: move xrange hack to reportlab.__init__, add rl_add_builtins utility
robin
parents: 4004
diff changeset
   148
            setattr(builtins,k,v)
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   149
else:
3920
50a1ff0c640a utils.py: added unicodeT bytesT strTypes
robin
parents: 3911
diff changeset
   150
    bytesT = str
50a1ff0c640a utils.py: added unicodeT bytesT strTypes
robin
parents: 3911
diff changeset
   151
    unicodeT = unicode
50a1ff0c640a utils.py: added unicodeT bytesT strTypes
robin
parents: 3911
diff changeset
   152
    strTypes = basestring
3796
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
   153
    if sys.hexversion >= 0x02000000:
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
   154
        def _digester(s):
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
   155
            return md5(s).hexdigest()
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
   156
    else:
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
   157
        # hexdigest not available in 1.5
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
   158
        def _digester(s):
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
   159
            return join(["%02x" % ord(x) for x in md5(s).digest()], '')
3834
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
   160
3911
8f0da55a18ba utils.py: add enc args to converters
robin
parents: 3899
diff changeset
   161
    def asBytes(v,enc='utf8'):
8f0da55a18ba utils.py: add enc args to converters
robin
parents: 3899
diff changeset
   162
        return v if isinstance(v,str) else v.encode(enc)
3834
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
   163
4016
59d017e4c80a utils.py: add enc(oding) argument to asNative
robin
parents: 4008
diff changeset
   164
    def asNative(v,enc='utf8'):
59d017e4c80a utils.py: add enc(oding) argument to asNative
robin
parents: 4008
diff changeset
   165
        return asBytes(v,enc=enc)
3834
3c5d76a16369 utils.py: added extra functions for cross python handling
robin
parents: 3823
diff changeset
   166
4004
ebd460ef8d2f rename utils.py UniChr --> uniChr
robin
parents: 3998
diff changeset
   167
    def uniChr(v):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   168
        return unichr(v)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   169
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   170
    def isStr(v):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   171
        return isinstance(v, basestring)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   172
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   173
    def isBytes(v):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   174
        return isinstance(v, str)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   175
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   176
    def isUnicode(v):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   177
        return isinstance(v, unicode)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   178
3911
8f0da55a18ba utils.py: add enc args to converters
robin
parents: 3899
diff changeset
   179
    def asUnicode(v,enc='utf8'):
8f0da55a18ba utils.py: add enc args to converters
robin
parents: 3899
diff changeset
   180
        return v if isinstance(v,unicode) else v.decode(enc)
3849
8ff9b1fb92cd utils.py: fix isUnicode, rename fileName2Utf8-->fileName2FSEnc
robin
parents: 3838
diff changeset
   181
4022
97f0a5833711 utils.py: added asUnicodeEx
robin
parents: 4016
diff changeset
   182
    def asUnicodeEx(v,enc='utf8'):
4064
2a7f47b3d12c asUnicodeEx should use unicode where possible, version --> 3.1.1
robin
parents: 4022
diff changeset
   183
        return v if isinstance(v,unicode) else v.decode(enc) if isinstance(v,str) else  unicode(v)
4022
97f0a5833711 utils.py: added asUnicodeEx
robin
parents: 4016
diff changeset
   184
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   185
    def isClass(v):
3964
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
   186
        return isinstance(v,(types.ClassType,type))
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
   187
3971
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
   188
    def isNonPrimitiveInstance(x):
4076
777af896ef28 utils.py: fix up isNonPrimitiveType for None
robin
parents: 4067
diff changeset
   189
        return isinstance(x,types.InstanceType) or not isinstance(x,(float,int,long,type,tuple,list,dict,bool,unicode,str,buffer,complex,slice,types.NoneType,
3971
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
   190
                    types.FunctionType,types.LambdaType,types.CodeType,types.GeneratorType,
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
   191
                    types.ClassType,types.UnboundMethodType,types.MethodType,types.BuiltinFunctionType,
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
   192
                    types.BuiltinMethodType,types.ModuleType,types.FileType,types.XRangeType,
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
   193
                    types.TracebackType,types.FrameType,types.EllipsisType,types.DictProxyType,
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
   194
                    types.NotImplementedType,types.GetSetDescriptorType,types.MemberDescriptorType
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
   195
                    ))
8b8a6f38ec6f utils.py: added isNonPrimitiveInstance
robin
parents: 3970
diff changeset
   196
3964
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
   197
    def instantiated(v):
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
   198
        return not isinstance(v,type) and hasattr(v,'__class__')
1b710422cf1a utils.py: improve isClass, added instantiated
robin
parents: 3963
diff changeset
   199
3970
28e73decd79f utils.py, codecharts.py: eliminate int2byte in favour of int2Byte
robin
parents: 3964
diff changeset
   200
    int2Byte = chr
28e73decd79f utils.py, codecharts.py: eliminate int2byte in favour of int2Byte
robin
parents: 3964
diff changeset
   201
3814
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   202
    from StringIO import StringIO
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   203
    def getBytesIO(buf=None):
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   204
        '''unified StringIO instance interface'''
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   205
        if buf:
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   206
            return StringIO(buf)
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   207
        return StringIO()
3880
79d10ac7de19 utils.py: add getStringIO
robin
parents: 3874
diff changeset
   208
    getStringIO = getBytesIO
3899
58aa34ad7b37 utils.py: added _bytesIOType and used in ImageReader
robin
parents: 3895
diff changeset
   209
    _bytesIOType = StringIO 
3814
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   210
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   211
    def bytestr(x,enc='utf8'):
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   212
        if isinstance(x,unicode):
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   213
            return x.encode(enc)
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   214
        elif isinstance(x,str):
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   215
            return x
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   216
        else:
e207649ca52d pdfdoc.py: move utf8str -->utils.py renamed as bytestr
robin
parents: 3802
diff changeset
   217
            return str(x).encode(enc)
3820
47edc5ad9dc6 move utils.py builtins defs to __init__.py
robin
parents: 3817
diff changeset
   218
    from string import letters as ascii_letters, uppercase as ascii_uppercase, lowercase as ascii_lowercase
3729
48064ab0f287 make utils.py look nicer
rptlab
parents: 3725
diff changeset
   219
3850
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
   220
    def encode_label(args):
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
   221
        return base64_encodestring(pickle.dumps(args)).strip()
3850
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
   222
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
   223
    def decode_label(label):
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
   224
        return pickle.loads(base64_decodestring(label))
3850
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3849
diff changeset
   225
3859
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   226
    def rawUnicode(s):
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   227
        '''converts first 256 unicodes 1-1'''
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   228
        return s.decode('latin1') if not isinstance(s,unicode) else s
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   229
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   230
    def rawBytes(s):
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   231
        '''converts first 256 unicodes 1-1'''
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   232
        return s.encode('latin1') if isinstance(s,unicode) else s
654fe44eeb5c utils.py: added char2Int, rawUnicode, rawBytes
robin
parents: 3850
diff changeset
   233
3870
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   234
    def rl_exec(obj, G=None, L=None):
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   235
        if G is None:
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   236
            frame = sys._getframe(1)
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   237
            G = frame.f_globals
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   238
            if L is None:
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   239
                L = frame.f_locals
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   240
            del frame
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   241
        elif L is None:
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   242
            L = G
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   243
        exec("""exec obj in G, L""")
3895
eac0863c605c utils.py: added an rl_reraise function and fix annotateException
robin
parents: 3880
diff changeset
   244
    rl_exec("""def rl_reraise(t, v, b=None):\n\traise t, v, b\n""")
3870
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   245
3874
1c3e56cd3a65 utils.py: fix char2int to handle python3's insanity
robin
parents: 3870
diff changeset
   246
    char2int = ord
4005
b7dee7fcd927 utils.py: move xrange hack to reportlab.__init__, add rl_add_builtins utility
robin
parents: 4004
diff changeset
   247
    def rl_add_builtins(**kwd):
b7dee7fcd927 utils.py: move xrange hack to reportlab.__init__, add rl_add_builtins utility
robin
parents: 4004
diff changeset
   248
        import __builtin__
b7dee7fcd927 utils.py: move xrange hack to reportlab.__init__, add rl_add_builtins utility
robin
parents: 4004
diff changeset
   249
        for k,v in kwd.items():
b7dee7fcd927 utils.py: move xrange hack to reportlab.__init__, add rl_add_builtins utility
robin
parents: 4004
diff changeset
   250
            setattr(__builtin__,k,v)
3874
1c3e56cd3a65 utils.py: fix char2int to handle python3's insanity
robin
parents: 3870
diff changeset
   251
3963
d01c8bc26566 utils.py: added function zipImported
robin
parents: 3926
diff changeset
   252
def zipImported(ldr=None):
d01c8bc26566 utils.py: added function zipImported
robin
parents: 3926
diff changeset
   253
    try:
d01c8bc26566 utils.py: added function zipImported
robin
parents: 3926
diff changeset
   254
        if not ldr:
d01c8bc26566 utils.py: added function zipImported
robin
parents: 3926
diff changeset
   255
            ldr = sys._getframe(1).f_globals['__loader__']
d01c8bc26566 utils.py: added function zipImported
robin
parents: 3926
diff changeset
   256
        from zipimport import zipimporter
4295
926ce83af2d7 attempt to ensure zipImported has some files or returns None
robin
parents: 4288
diff changeset
   257
        return ldr if isinstance(ldr,zipimporter) and len(ldr._files) else None
3963
d01c8bc26566 utils.py: added function zipImported
robin
parents: 3926
diff changeset
   258
    except:
d01c8bc26566 utils.py: added function zipImported
robin
parents: 3926
diff changeset
   259
        return None
d01c8bc26566 utils.py: added function zipImported
robin
parents: 3926
diff changeset
   260
2215
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   261
def _findFiles(dirList,ext='.ttf'):
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   262
    from os.path import isfile, isdir, join as path_join
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   263
    from os import listdir
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   264
    ext = ext.lower()
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   265
    R = []
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   266
    A = R.append
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   267
    for D in dirList:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   268
        if not isdir(D): continue
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   269
        for fn in listdir(D):
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   270
            fn = path_join(D,fn)
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   271
            if isfile(fn) and (not ext or fn.lower().endswith(ext)): A(fn)
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   272
    return R
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   273
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   274
class CIDict(dict):
3328
4d7f836cd947 reportlab: fix 2to3 warnings
rgbecker
parents: 3327
diff changeset
   275
    def __init__(self,*args,**kwds):
4d7f836cd947 reportlab: fix 2to3 warnings
rgbecker
parents: 3327
diff changeset
   276
        for a in args: self.update(a)
4d7f836cd947 reportlab: fix 2to3 warnings
rgbecker
parents: 3327
diff changeset
   277
        self.update(kwds)
2215
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   278
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   279
    def update(self,D):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   280
        for k,v in D.items(): self[k] = v
2215
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   281
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   282
    def __setitem__(self,k,v):
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   283
        try:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   284
            k = k.lower()
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   285
        except:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   286
            pass
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   287
        dict.__setitem__(self,k,v)
2215
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   288
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   289
    def __getitem__(self,k):
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   290
        try:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   291
            k = k.lower()
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   292
        except:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   293
            pass
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   294
        return dict.__getitem__(self,k)
2215
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   295
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   296
    def __delitem__(self,k):
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   297
        try:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   298
            k = k.lower()
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   299
        except:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   300
            pass
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   301
        return dict.__delitem__(self,k)
2215
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   302
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   303
    def get(self,k,dv=None):
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   304
        try:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   305
            return self[k]
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   306
        except KeyError:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   307
            return dv
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   308
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3291
diff changeset
   309
    def __contains__(self,k):
2215
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   310
        try:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   311
            self[k]
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   312
            return True
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   313
        except:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   314
            return False
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   315
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   316
    def pop(self,k,*a):
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   317
        try:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   318
            k = k.lower()
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   319
        except:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   320
            pass
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   321
        return dict.pop(*((self,k)+a))
2215
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   322
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   323
    def setdefault(self,k,*a):
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   324
        try:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   325
            k = k.lower()
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   326
        except:
e86aad9766c7 Added _findFiles & CIDict
rgbecker
parents: 2200
diff changeset
   327
            pass
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   328
        return dict.setdefault(*((self,k)+a))
1837
a3920893b1b8 Back in synch, diagnostic function for distro type added
andy_robinson
parents: 1835
diff changeset
   329
1902
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   330
if os.name == 'mac':
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   331
    #with the Mac, we need to tag the file in a special
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   332
    #way so the system knows it is a PDF file.
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   333
    #This supplied by Joe Strout
2057
22e7a13fa031 Fixed so that file creator and types are now correctly set on the Mac again
rptlab
parents: 2053
diff changeset
   334
    import macfs, macostools
2007
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   335
    _KNOWN_MAC_EXT = {
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   336
        'BMP' : ('ogle','BMP '),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   337
        'EPS' : ('ogle','EPSF'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   338
        'EPSF': ('ogle','EPSF'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   339
        'GIF' : ('ogle','GIFf'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   340
        'JPG' : ('ogle','JPEG'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   341
        'JPEG': ('ogle','JPEG'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   342
        'PCT' : ('ttxt','PICT'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   343
        'PICT': ('ttxt','PICT'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   344
        'PNG' : ('ogle','PNGf'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   345
        'PPM' : ('ogle','.PPM'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   346
        'TIF' : ('ogle','TIFF'),
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   347
        'TIFF': ('ogle','TIFF'),
2051
50350756e12c Added HTML to the Mac markfilename routine - HTML files should now 'know'
johnprecedo
parents: 2045
diff changeset
   348
        'PDF' : ('CARO','PDF '),
2057
22e7a13fa031 Fixed so that file creator and types are now correctly set on the Mac again
rptlab
parents: 2053
diff changeset
   349
        'HTML': ('MSIE','TEXT'),
2007
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   350
        }
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   351
    def markfilename(filename,creatorcode=None,filetype=None,ext='PDF'):
1902
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   352
        try:
2007
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   353
            if creatorcode is None or filetype is None and ext is not None:
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   354
                try:
3134
e403094e7c98 utils.py: removed old string usages
rgbecker
parents: 3122
diff changeset
   355
                    creatorcode, filetype = _KNOWN_MAC_EXT[ext.upper()]
2007
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   356
                except:
2759dd179707 Added John's mac type dict to markfilename
rgbecker
parents: 1999
diff changeset
   357
                    return
1902
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   358
            macfs.FSSpec(filename).SetCreatorType(creatorcode,filetype)
2051
50350756e12c Added HTML to the Mac markfilename routine - HTML files should now 'know'
johnprecedo
parents: 2045
diff changeset
   359
            macostools.touched(filename)
1902
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   360
        except:
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   361
            pass
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   362
else:
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   363
    def markfilename(filename,creatorcode=None,filetype=None):
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   364
        pass
3dc6869b1b47 Moved markfilename from pdfdoc
rgbecker
parents: 1837
diff changeset
   365
2244
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   366
import reportlab
2251
afa4604d1a15 We prefer absolute RL DIR
rgbecker
parents: 2247
diff changeset
   367
__RL_DIR=os.path.dirname(reportlab.__file__)    #possibly relative
afa4604d1a15 We prefer absolute RL DIR
rgbecker
parents: 2247
diff changeset
   368
_RL_DIR=os.path.isabs(__RL_DIR) and __RL_DIR or os.path.abspath(__RL_DIR)
2244
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   369
del reportlab
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   370
2225
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   371
#Attempt to detect if this copy of reportlab is running in a
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   372
#file system (as opposed to mostly running in a zip or McMillan
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   373
#archive or Jar file).  This is used by test cases, so that
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   374
#we can write test cases that don't get activated in frozen form.
2244
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   375
try:
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   376
    __file__
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   377
except:
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   378
    __file__ = sys.argv[0]
2305
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   379
import glob, fnmatch
2244
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   380
try:
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   381
    __rl_loader__ = __loader__
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   382
    _isFSD = not __rl_loader__
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   383
    if not zipImported(ldr=__rl_loader__):
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   384
        raise NotImplementedError("can't handle compact distro type %r" % __rl_loader__)
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   385
    _archive = os.path.normcase(os.path.normpath(__rl_loader__.archive))
2327
c40a1b477f3f Forgot to check the exactly equal case for _startswith_rl
rgbecker
parents: 2313
diff changeset
   386
    _archivepfx = _archive + os.sep
2484
590938600027 utils.py: use normpath in _archive etc etc
rgbecker
parents: 2482
diff changeset
   387
    _archivedir = os.path.dirname(_archive)
2327
c40a1b477f3f Forgot to check the exactly equal case for _startswith_rl
rgbecker
parents: 2313
diff changeset
   388
    _archivedirpfx = _archivedir + os.sep
2305
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   389
    _archivepfxlen = len(_archivepfx)
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   390
    _archivedirpfxlen = len(_archivedirpfx)
2352
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   391
    def __startswith_rl(fn,
2484
590938600027 utils.py: use normpath in _archive etc etc
rgbecker
parents: 2482
diff changeset
   392
                    _archivepfx=_archivepfx,
590938600027 utils.py: use normpath in _archive etc etc
rgbecker
parents: 2482
diff changeset
   393
                    _archivedirpfx=_archivedirpfx,
590938600027 utils.py: use normpath in _archive etc etc
rgbecker
parents: 2482
diff changeset
   394
                    _archive=_archive,
590938600027 utils.py: use normpath in _archive etc etc
rgbecker
parents: 2482
diff changeset
   395
                    _archivedir=_archivedir,
2352
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   396
                    os_path_normpath=os.path.normpath,
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   397
                    os_path_normcase=os.path.normcase,
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   398
                    os_getcwd=os.getcwd,
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   399
                    os_sep=os.sep,
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   400
                    os_sep_len = len(os.sep)):
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   401
        '''if the name starts with a known prefix strip it off'''
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   402
        fn = os_path_normpath(fn.replace('/',os_sep))
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   403
        nfn = os_path_normcase(fn)
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   404
        if nfn in (_archivedir,_archive): return 1,''
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   405
        if nfn.startswith(_archivepfx): return 1,fn[_archivepfxlen:]
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   406
        if nfn.startswith(_archivedirpfx): return 1,fn[_archivedirpfxlen:]
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   407
        cwd = os_path_normcase(os_getcwd())
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   408
        n = len(cwd)
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   409
        if nfn.startswith(cwd):
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   410
            if fn[n:].startswith(os_sep): return 1, fn[n+os_sep_len:]
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   411
            if n==len(fn): return 1,''
c8bf2490acc9 Another know location
rgbecker
parents: 2340
diff changeset
   412
        return not os.path.isabs(fn),fn
2305
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   413
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   414
    def _startswith_rl(fn):
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   415
        return __startswith_rl(fn)[1]
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   416
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   417
    def rl_glob(pattern,glob=glob.glob,fnmatch=fnmatch.fnmatch, _RL_DIR=_RL_DIR,pjoin=os.path.join):
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   418
        c, pfn = __startswith_rl(pattern)
2307
a1f106a7bed8 More compact distro changes
rgbecker
parents: 2305
diff changeset
   419
        r = glob(pfn)
2305
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   420
        if c or r==[]:
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   421
            r += list(map(lambda x,D=_archivepfx,pjoin=pjoin: pjoin(_archivepfx,x),list(filter(lambda x,pfn=pfn,fnmatch=fnmatch: fnmatch(x,pfn),list(__rl_loader__._files.keys())))))
2305
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   422
        return r
2244
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   423
except:
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   424
    _isFSD = os.path.isfile(__file__)   #slight risk of wrong path
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   425
    __rl_loader__ = None
2305
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   426
    def _startswith_rl(fn):
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   427
        return fn
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   428
    def rl_glob(pattern,glob=glob.glob):
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   429
        return glob(pattern)
3dbfbe55e9ff Use more advanced __loader__ friendly code
rgbecker
parents: 2302
diff changeset
   430
del glob, fnmatch
2244
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   431
_isFSSD = _isFSD and os.path.isfile(os.path.splitext(__file__)[0] +'.py')
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   432
1837
a3920893b1b8 Back in synch, diagnostic function for distro type added
andy_robinson
parents: 1835
diff changeset
   433
def isFileSystemDistro():
2225
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   434
    '''return truth if a file system distribution'''
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   435
    return _isFSD
1837
a3920893b1b8 Back in synch, diagnostic function for distro type added
andy_robinson
parents: 1835
diff changeset
   436
a3920893b1b8 Back in synch, diagnostic function for distro type added
andy_robinson
parents: 1835
diff changeset
   437
def isCompactDistro():
2225
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   438
    '''return truth if not a file system distribution'''
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   439
    return not _isFSD
1837
a3920893b1b8 Back in synch, diagnostic function for distro type added
andy_robinson
parents: 1835
diff changeset
   440
a3920893b1b8 Back in synch, diagnostic function for distro type added
andy_robinson
parents: 1835
diff changeset
   441
def isSourceDistro():
2225
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   442
    '''return truth if a source file system distribution'''
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   443
    return _isFSSD
1143
46a5ec2d3d2c Better import error checking
rgbecker
parents: 998
diff changeset
   444
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   445
def recursiveImport(modulename, baseDir=None, noCWD=0, debug=0):
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   446
    """Dynamically imports possible packagized module, or raises ImportError"""
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   447
    normalize = lambda x: os.path.normcase(os.path.abspath(os.path.normpath(x)))
3823
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   448
    path = [normalize(p) for p in sys.path]
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   449
    if baseDir:
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   450
        if not isSeq(baseDir):
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   451
            tp = [baseDir]
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   452
        else:
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   453
            tp = filter(None,list(baseDir))
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   454
        for p in tp:
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   455
            p = normalize(p)
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   456
            if p not in path: path.insert(0,p)
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   457
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   458
    if noCWD:
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   459
        for p in ('','.',normalize('.')):
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   460
            while p in path:
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   461
                if debug: print('removed "%s" from path' % p)
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   462
                path.remove(p)
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   463
    elif '.' not in path:
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   464
            path.insert(0,'.')
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   465
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   466
    if debug:
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   467
        import pprint
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   468
        pp = pprint.pprint
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   469
        print('path=')
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   470
        pp(path)
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   471
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   472
    #make import errors a bit more informative
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   473
    opath = sys.path
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   474
    try:
3823
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   475
        try:
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   476
            sys.path = path
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   477
            NS = {}
3870
69afc7d70daa utils.py: add rl_exec portable function
robin
parents: 3859
diff changeset
   478
            rl_exec('import %s as m' % modulename,NS)
3823
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   479
            return NS['m']
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   480
        except ImportError:
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   481
            sys.path = opath
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   482
            msg = "Could not import '%s'" % modulename
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   483
            if baseDir:
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   484
                msg = msg + " under %s" % baseDir
4008
56ed06a5498b utils.py: recursiveImport now uses annotateException
robin
parents: 4005
diff changeset
   485
            annotateException(msg)
3823
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   486
        except:
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   487
            e = sys.exc_info()
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   488
            msg = "Exception raised while importing '%s': %s" % (modulename, e[1])
4008
56ed06a5498b utils.py: recursiveImport now uses annotateException
robin
parents: 4005
diff changeset
   489
            annotateException(msg)
3823
c8133d91487a fix utils tests and small changes to recursiveImport
robin
parents: 3820
diff changeset
   490
    finally:
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   491
        sys.path = opath
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   492
1821
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   493
def recursiveGetAttr(obj, name):
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   494
    "Can call down into e.g. object1.object2[4].attr"
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   495
    return eval(name, obj.__dict__)
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   496
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   497
def recursiveSetAttr(obj, name, value):
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   498
    "Can call down into e.g. object1.object2[4].attr = value"
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   499
    #get the thing above last.
3134
e403094e7c98 utils.py: removed old string usages
rgbecker
parents: 3122
diff changeset
   500
    tokens = name.split('.')
1821
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   501
    if len(tokens) == 1:
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   502
        setattr(obj, name, value)
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2160
diff changeset
   503
    else:
3134
e403094e7c98 utils.py: removed old string usages
rgbecker
parents: 3122
diff changeset
   504
        most = '.'.join(tokens[:-1])
1821
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   505
        last = tokens[-1]
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   506
        parent = recursiveGetAttr(obj, most)
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   507
        setattr(parent, last, value)
7854ddd0fc30 Fixed recursive import, setting and gettign attributes
andy_robinson
parents: 1683
diff changeset
   508
674
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 562
diff changeset
   509
def import_zlib():
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   510
    try:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   511
        import zlib
2053
2a962a30dc46 Removed checkImportError
rgbecker
parents: 2051
diff changeset
   512
    except ImportError:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   513
        zlib = None
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   514
        from reportlab.rl_config import ZLIB_WARNINGS
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   515
        if ZLIB_WARNINGS: warnOnce('zlib not available')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   516
    return zlib
674
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 562
diff changeset
   517
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   518
# Image Capability Detection.  Set a flag haveImages
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   519
# to tell us if either PIL or Java imaging libraries present.
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   520
# define PIL_Image as either None, or an alias for the PIL.Image
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   521
# module, as there are 2 ways to import it
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   522
if sys.platform[0:4] == 'java':
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   523
    try:
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   524
        import javax.imageio
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   525
        import java.awt.image
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   526
        haveImages = 1
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   527
    except:
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   528
        haveImages = 0
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   529
else:
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   530
    try:
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   531
        from PIL import Image
2053
2a962a30dc46 Removed checkImportError
rgbecker
parents: 2051
diff changeset
   532
    except ImportError:
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   533
        try:
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   534
            import Image
2053
2a962a30dc46 Removed checkImportError
rgbecker
parents: 2051
diff changeset
   535
        except ImportError:
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   536
            Image = None
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   537
    haveImages = Image is not None
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   538
1375
cb8e4098def5 Added ArgvDictValue and getArgvDict
rgbecker
parents: 1153
diff changeset
   539
class ArgvDictValue:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   540
    '''A type to allow clients of getArgvDict to specify a conversion function'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   541
    def __init__(self,value,func):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   542
        self.value = value
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   543
        self.func = func
1375
cb8e4098def5 Added ArgvDictValue and getArgvDict
rgbecker
parents: 1153
diff changeset
   544
cb8e4098def5 Added ArgvDictValue and getArgvDict
rgbecker
parents: 1153
diff changeset
   545
def getArgvDict(**kw):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   546
    ''' Builds a dictionary from its keyword arguments with overrides from sys.argv.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   547
        Attempts to be smart about conversions, but the value can be an instance
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   548
        of ArgDictValue to allow specifying a conversion function.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   549
    '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   550
    def handleValue(v,av,func):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   551
        if func:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   552
            v = func(av)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   553
        else:
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   554
            if isStr(v):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   555
                v = av
3180
349e9644fce8 reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents: 3171
diff changeset
   556
            elif isinstance(v,float):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   557
                v = float(av)
3180
349e9644fce8 reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents: 3171
diff changeset
   558
            elif isinstance(v,int):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   559
                v = int(av)
3180
349e9644fce8 reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents: 3171
diff changeset
   560
            elif isinstance(v,list):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   561
                v = list(eval(av))
3180
349e9644fce8 reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents: 3171
diff changeset
   562
            elif isinstance(v,tuple):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   563
                v = tuple(eval(av))
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   564
            else:
3180
349e9644fce8 reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents: 3171
diff changeset
   565
                raise TypeError("Can't convert string %r to %s" % (av,type(v)))
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   566
        return v
1387
715edbf17c7a Improved argv stuff
rgbecker
parents: 1375
diff changeset
   567
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   568
    A = sys.argv[1:]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   569
    R = {}
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   570
    for k, v in kw.items():
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   571
        if isinstance(v,ArgvDictValue):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   572
            v, func = v.value, v.func
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   573
        else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   574
            func = None
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   575
        handled = 0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   576
        ke = k+'='
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   577
        for a in A:
3134
e403094e7c98 utils.py: removed old string usages
rgbecker
parents: 3122
diff changeset
   578
            if a.find(ke)==0:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   579
                av = a[len(ke):]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   580
                A.remove(a)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   581
                R[k] = handleValue(v,av,func)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   582
                handled = 1
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   583
                break
1387
715edbf17c7a Improved argv stuff
rgbecker
parents: 1375
diff changeset
   584
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   585
        if not handled: R[k] = handleValue(v,v,func)
1387
715edbf17c7a Improved argv stuff
rgbecker
parents: 1375
diff changeset
   586
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   587
    return R
1375
cb8e4098def5 Added ArgvDictValue and getArgvDict
rgbecker
parents: 1153
diff changeset
   588
452
6bb011a0d63e Initial version of D Yoo's pyHnj
rgbecker
parents: 448
diff changeset
   589
def getHyphenater(hDict=None):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   590
    try:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   591
        from reportlab.lib.pyHnj import Hyphen
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   592
        if hDict is None: hDict=os.path.join(os.path.dirname(__file__),'hyphen.mashed')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   593
        return Hyphen(hDict)
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
   594
    except ImportError as errMsg:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   595
        if str(errMsg)!='No module named pyHnj': raise
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   596
        return None
452
6bb011a0d63e Initial version of D Yoo's pyHnj
rgbecker
parents: 448
diff changeset
   597
448
cb0c4d97e29b Added _className func
rgbecker
parents: 413
diff changeset
   598
def _className(self):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   599
    '''Return a shortened class name'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   600
    try:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   601
        name = self.__class__.__name__
3134
e403094e7c98 utils.py: removed old string usages
rgbecker
parents: 3122
diff changeset
   602
        i=name.rfind('.')
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   603
        if i>=0: return name[i+1:]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   604
        return name
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   605
    except AttributeError:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   606
        return str(self)
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
   607
2309
47243845ef50 Attempt to fix open_for_read again
rgbecker
parents: 2307
diff changeset
   608
def open_for_read_by_name(name,mode='b'):
47243845ef50 Attempt to fix open_for_read again
rgbecker
parents: 2307
diff changeset
   609
    if 'r' not in mode: mode = 'r'+mode
47243845ef50 Attempt to fix open_for_read again
rgbecker
parents: 2307
diff changeset
   610
    try:
47243845ef50 Attempt to fix open_for_read again
rgbecker
parents: 2307
diff changeset
   611
        return open(name,mode)
47243845ef50 Attempt to fix open_for_read again
rgbecker
parents: 2307
diff changeset
   612
    except IOError:
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   613
        if _isFSD or __rl_loader__ is None: raise
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   614
        #we have a __rl_loader__, perhaps the filename starts with
2313
e823a147f0b5 Another rework of the open for read code
rgbecker
parents: 2309
diff changeset
   615
        #the dirname(reportlab.__file__) or is relative
e823a147f0b5 Another rework of the open for read code
rgbecker
parents: 2309
diff changeset
   616
        name = _startswith_rl(name)
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   617
        s = __rl_loader__.get_data(name)
2313
e823a147f0b5 Another rework of the open for read code
rgbecker
parents: 2309
diff changeset
   618
        if 'b' not in mode and os.linesep!='\n': s = s.replace(os.linesep,'\n')
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   619
        return getBytesIO(s)
2309
47243845ef50 Attempt to fix open_for_read again
rgbecker
parents: 2307
diff changeset
   620
4091
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   621
if not isPy3:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   622
    import urllib2, urllib
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   623
    urlopen=urllib2.urlopen
4091
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   624
    def datareader(url,opener=urllib.URLopener().open):
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   625
        return opener(url).read()
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   626
    del urllib, urllib2
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   627
else:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   628
    from urllib.request import urlopen
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   629
    from urllib.parse import unquote
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   630
    import base64
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   631
    #copied here from urllib.URLopener.open_data because
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   632
    # 1) they want to remove it
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   633
    # 2) the existing one is borken
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   634
    def datareader(url, unquote=unquote, decodebytes=base64.decodebytes):
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   635
        """Use "data" URL."""
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   636
        # ignore POSTed data
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   637
        #
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   638
        # syntax of data URLs:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   639
        # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   640
        # mediatype := [ type "/" subtype ] *( ";" parameter )
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   641
        # data      := *urlchar
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   642
        # parameter := attribute "=" value
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   643
        try:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   644
            typ, data = url.split(',', 1)
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   645
        except ValueError:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   646
            raise IOError('data error', 'bad data URL')
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   647
        if not typ:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   648
            typ = 'text/plain;charset=US-ASCII'
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   649
        semi = typ.rfind(';')
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   650
        if semi >= 0 and '=' not in typ[semi:]:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   651
            encoding = typ[semi+1:]
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   652
            typ = typ[:semi]
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   653
        else:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   654
            encoding = ''
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   655
        if encoding == 'base64':
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   656
            # XXX is this encoding/decoding ok?
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   657
            data = decodebytes(data.encode('ascii'))
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   658
        else:
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   659
            data = unquote(data).encode('latin-1')
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   660
        return data
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   661
    del unquote, base64
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   662
4091
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   663
def open_for_read(name,mode='b', urlopen=urlopen, datareader=datareader):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   664
    '''attempt to open a file or URL for reading'''
2229
99cb312c5269 Fix transparency & jpeg behaviour
rgbecker
parents: 2227
diff changeset
   665
    if hasattr(name,'read'): return name
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   666
    try:
2313
e823a147f0b5 Another rework of the open for read code
rgbecker
parents: 2309
diff changeset
   667
        return open_for_read_by_name(name,mode)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   668
    except:
2313
e823a147f0b5 Another rework of the open for read code
rgbecker
parents: 2309
diff changeset
   669
        try:
4265
4c95cb54c4bd allow DATA: scheme in open for read
robin
parents: 4252
diff changeset
   670
            return getBytesIO(datareader(name) if name[:5].lower()=='data:' else urlopen(name).read())
2313
e823a147f0b5 Another rework of the open for read code
rgbecker
parents: 2309
diff changeset
   671
        except:
e823a147f0b5 Another rework of the open for read code
rgbecker
parents: 2309
diff changeset
   672
            raise IOError('Cannot open resource "%s"' % name)
4091
2ee37be22e45 utils.py: allow data: scheme in open_for_read and test in test_lib_utils; bump version to 3.1.11
robin
parents: 4086
diff changeset
   673
del urlopen, datareader
1575
7d2360bdfc4d Added open_for_read
rgbecker
parents: 1561
diff changeset
   674
2225
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   675
def open_and_read(name,mode='b'):
4124
94f5a3bea734 utils.py: try to eliminate dangling resources in open_and_read, version bump to 3.1.26
robin
parents: 4103
diff changeset
   676
    f = open_for_read(name,mode)
94f5a3bea734 utils.py: try to eliminate dangling resources in open_and_read, version bump to 3.1.26
robin
parents: 4103
diff changeset
   677
    if name is not f and hasattr(f,'__exit__'):
94f5a3bea734 utils.py: try to eliminate dangling resources in open_and_read, version bump to 3.1.26
robin
parents: 4103
diff changeset
   678
        with f:
94f5a3bea734 utils.py: try to eliminate dangling resources in open_and_read, version bump to 3.1.26
robin
parents: 4103
diff changeset
   679
            return f.read()
94f5a3bea734 utils.py: try to eliminate dangling resources in open_and_read, version bump to 3.1.26
robin
parents: 4103
diff changeset
   680
    else:
94f5a3bea734 utils.py: try to eliminate dangling resources in open_and_read, version bump to 3.1.26
robin
parents: 4103
diff changeset
   681
        return f.read()
2225
783cbac215e5 Improve the fs distro check
rgbecker
parents: 2215
diff changeset
   682
2247
256cea0756a9 Added open_and_readlines
rgbecker
parents: 2244
diff changeset
   683
def open_and_readlines(name,mode='t'):
256cea0756a9 Added open_and_readlines
rgbecker
parents: 2244
diff changeset
   684
    return open_and_read(name,mode).split('\n')
256cea0756a9 Added open_and_readlines
rgbecker
parents: 2244
diff changeset
   685
2240
068e2487e780 Added rl_isfile
rgbecker
parents: 2231
diff changeset
   686
def rl_isfile(fn,os_path_isfile=os.path.isfile):
068e2487e780 Added rl_isfile
rgbecker
parents: 2231
diff changeset
   687
    if hasattr(fn,'read'): return True
068e2487e780 Added rl_isfile
rgbecker
parents: 2231
diff changeset
   688
    if os_path_isfile(fn): return True
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   689
    if _isFSD or __rl_loader__ is None: return False
2244
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   690
    fn = _startswith_rl(fn)
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   691
    return fn in list(__rl_loader__._files.keys())
2240
068e2487e780 Added rl_isfile
rgbecker
parents: 2231
diff changeset
   692
2339
4b1dae4bd1a8 More changes related to compact distro path recognition
rgbecker
parents: 2332
diff changeset
   693
def rl_isdir(pn,os_path_isdir=os.path.isdir,os_path_normpath=os.path.normpath):
2244
58148991bc4d Improvements for compact running
rgbecker
parents: 2240
diff changeset
   694
    if os_path_isdir(pn): return True
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   695
    if _isFSD or __rl_loader__ is None: return False
2354
c20a2fe18b0e reportlab.lib.utils fix rl_isdir
rgbecker
parents: 2352
diff changeset
   696
    pn = _startswith_rl(os_path_normpath(pn))
c20a2fe18b0e reportlab.lib.utils fix rl_isdir
rgbecker
parents: 2352
diff changeset
   697
    if not pn.endswith(os.sep): pn += os.sep
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   698
    return len(list(filter(lambda x,pn=pn: x.startswith(pn),list(__rl_loader__._files.keys()))))>0
2240
068e2487e780 Added rl_isfile
rgbecker
parents: 2231
diff changeset
   699
2794
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   700
def rl_listdir(pn,os_path_isdir=os.path.isdir,os_path_normpath=os.path.normpath,os_listdir=os.listdir):
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   701
    if os_path_isdir(pn) or _isFSD or __rl_loader__ is None: return os_listdir(pn)
2794
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   702
    pn = _startswith_rl(os_path_normpath(pn))
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   703
    if not pn.endswith(os.sep): pn += os.sep
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   704
    return [x[len(pn):] for x in __rl_loader__._files.keys() if x.startswith(pn)]
2794
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   705
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   706
def rl_getmtime(pn,os_path_isfile=os.path.isfile,os_path_normpath=os.path.normpath,os_path_getmtime=os.path.getmtime,time_mktime=time.mktime):
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   707
    if os_path_isfile(pn) or _isFSD or __rl_loader__ is None: return os_path_getmtime(pn)
2794
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   708
    p = _startswith_rl(os_path_normpath(pn))
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   709
    try:
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   710
        e = __rl_loader__._files[p]
2794
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   711
    except KeyError:
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   712
        return os_path_getmtime(pn)
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   713
    s = e[5]
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   714
    d = e[6]
3569
b4bb97f6ed72 reportlab: utils.py fix rl_getmtime
rgbecker
parents: 3517
diff changeset
   715
    return time_mktime((((d>>9)&0x7f)+1980,(d>>5)&0xf,d&0x1f,(s>>11)&0x1f,(s>>5)&0x3f,(s&0x1f)<<1,0,0,0))
2794
6539e5dc77b8 add support for fontfinder in zip distribution
rgbecker
parents: 2764
diff changeset
   716
2301
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   717
def rl_get_module(name,dir):
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3291
diff changeset
   718
    if name in sys.modules:
2301
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   719
        om = sys.modules[name]
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   720
        del sys.modules[name]
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   721
    else:
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   722
        om = None
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   723
    try:
2302
240a26f9ee8f rl_get_module now seems to work as intended
rgbecker
parents: 2301
diff changeset
   724
        f = None
2301
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   725
        try:
2302
240a26f9ee8f rl_get_module now seems to work as intended
rgbecker
parents: 2301
diff changeset
   726
            f, p, desc= imp.find_module(name,[dir])
2301
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   727
            return imp.load_module(name,f,p,desc)
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   728
        except:
2307
a1f106a7bed8 More compact distro changes
rgbecker
parents: 2305
diff changeset
   729
            if isCompactDistro():
2301
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   730
                #attempt a load from inside the zip archive
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   731
                import zipimport
2307
a1f106a7bed8 More compact distro changes
rgbecker
parents: 2305
diff changeset
   732
                dir = _startswith_rl(dir)
2356
4a71278dd82d Minor fixes to lib.utils.rl_get_module
rgbecker
parents: 2354
diff changeset
   733
                dir = (dir=='.' or not dir) and _archive or os.path.join(_archive,dir.replace('/',os.sep))
2327
c40a1b477f3f Forgot to check the exactly equal case for _startswith_rl
rgbecker
parents: 2313
diff changeset
   734
                zi = zipimport.zipimporter(dir)
2301
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   735
                return zi.load_module(name)
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   736
            raise ImportError('%s[%s]' % (name,dir))
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   737
    finally:
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   738
        if om: sys.modules[name] = om
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   739
        del om
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   740
        if f: f.close()
3df8c1c14c0e rl_get_module added
rgbecker
parents: 2300
diff changeset
   741
2487
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   742
def _isPILImage(im):
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   743
    try:
3291
bd18d83b4a0d utils.py: hack fix for load problem in PIL 1.1.7
rgbecker
parents: 3253
diff changeset
   744
        return isinstance(im,Image.Image)
3465
21c2d12661b9 utils.py: fix exception class and use annotateException
rgbecker
parents: 3437
diff changeset
   745
    except AttributeError:
2487
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   746
        return 0
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   747
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   748
class ImageReader(object):
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   749
    "Wraps up either PIL or Java to get data from bitmaps"
2952
8a51cf037687 reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents: 2942
diff changeset
   750
    _cache={}
3355
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   751
    def __init__(self, fileName,ident=None):
2487
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   752
        if isinstance(fileName,ImageReader):
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   753
            self.__dict__ = fileName.__dict__   #borgize
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   754
            return
3355
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   755
        self._ident = ident
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   756
        #start wih lots of null private fields, to be populated by
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   757
        #the relevant engine.
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   758
        self.fileName = fileName
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   759
        self._image = None
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   760
        self._width = None
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   761
        self._height = None
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   762
        self._transparent = None
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   763
        self._data = None
2487
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   764
        if _isPILImage(fileName):
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   765
            self._image = fileName
2902
f15ac27dc73f reportlab: add in RGBA functionality for sensible images
rgbecker
parents: 2838
diff changeset
   766
            self.fp = getattr(fileName,'fp',None)
2487
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   767
            try:
2720
2c04d204766d utils.py: attempt to fix fileName from PIL images
rgbecker
parents: 2716
diff changeset
   768
                self.fileName = self._image.fileName
2487
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   769
            except AttributeError:
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   770
                self.fileName = 'PILIMAGE_%d' % id(self)
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   771
        else:
2556
d7c3c6b74053 utils.py: annotate ImageReader read errors
rgbecker
parents: 2502
diff changeset
   772
            try:
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   773
                from reportlab.rl_config import imageReaderFlags
2556
d7c3c6b74053 utils.py: annotate ImageReader read errors
rgbecker
parents: 2502
diff changeset
   774
                self.fp = open_for_read(fileName,'b')
3899
58aa34ad7b37 utils.py: added _bytesIOType and used in ImageReader
robin
parents: 3895
diff changeset
   775
                if isinstance(self.fp,_bytesIOType): imageReaderFlags=0 #avoid messing with already internal files
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   776
                if imageReaderFlags>0:  #interning
2952
8a51cf037687 reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents: 2942
diff changeset
   777
                    data = self.fp.read()
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   778
                    if imageReaderFlags&2:  #autoclose
2952
8a51cf037687 reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents: 2942
diff changeset
   779
                        try:
8a51cf037687 reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents: 2942
diff changeset
   780
                            self.fp.close()
8a51cf037687 reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents: 2942
diff changeset
   781
                        except:
8a51cf037687 reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents: 2942
diff changeset
   782
                            pass
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   783
                    if imageReaderFlags&4:  #cache the data
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   784
                        if not self._cache:
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   785
                            from rl_config import register_reset
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   786
                            register_reset(self._cache.clear)
3796
c9a86549dee7 utils.py, codecharts.py: add and use int2byte function
robin
parents: 3788
diff changeset
   787
                        data=self._cache.setdefault(_digester(data),data)
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   788
                    self.fp=getBytesIO(data)
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
   789
                elif imageReaderFlags==-1 and isinstance(fileName,str):
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   790
                    #try Ralf Schmitt's re-opening technique of avoiding too many open files
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   791
                    self.fp.close()
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   792
                    del self.fp #will become a property in the next statement
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   793
                    self.__class__=LazyImageReader
2953
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   794
                if haveImages:
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   795
                    #detect which library we are using and open the image
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   796
                    if not self._image:
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   797
                        self._image = self._read_image(self.fp)
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   798
                    if getattr(self._image,'format',None)=='JPEG': self.jpeg_fh = self._jpeg_fh
2953
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   799
                else:
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   800
                    from reportlab.pdfbase.pdfutils import readJPEGInfo
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   801
                    try:
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   802
                        self._width,self._height,c=readJPEGInfo(self.fp)
2952
8a51cf037687 reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents: 2942
diff changeset
   803
                    except:
3465
21c2d12661b9 utils.py: fix exception class and use annotateException
rgbecker
parents: 3437
diff changeset
   804
                        annotateException('\nImaging Library not available, unable to import bitmaps only jpegs\nfileName=%r identity=%s'%(fileName,self.identity()))
2953
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   805
                    self.jpeg_fh = self._jpeg_fh
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   806
                    self._data = self.fp.read()
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   807
                    self._dataA=None
59f221d6007c reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents: 2952
diff changeset
   808
                    self.fp.seek(0)
2556
d7c3c6b74053 utils.py: annotate ImageReader read errors
rgbecker
parents: 2502
diff changeset
   809
            except:
3355
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   810
                annotateException('\nfileName=%r identity=%s'%(fileName,self.identity()))
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   811
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   812
    def identity(self):
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   813
        '''try to return information that will identify the instance'''
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   814
        fn = self.fileName
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
   815
        if not isStr(fn):
3355
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   816
            fn = getattr(getattr(self,'fp',None),'name',None)
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   817
        ident = self._ident
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   818
        return '[%s@%s%s%s]' % (self.__class__.__name__,hex(id(self)),ident and (' ident=%r' % ident) or '',fn and (' filename=%r' % fn) or '')
2556
d7c3c6b74053 utils.py: annotate ImageReader read errors
rgbecker
parents: 2502
diff changeset
   819
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   820
    def _read_image(self,fp):
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   821
        if sys.platform[0:4] == 'java':
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   822
            from javax.imageio import ImageIO
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   823
            return ImageIO.read(fp)
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   824
        else:
3291
bd18d83b4a0d utils.py: hack fix for load problem in PIL 1.1.7
rgbecker
parents: 3253
diff changeset
   825
            return Image.open(fp)
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   826
2487
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   827
    def _jpeg_fh(self):
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   828
        fp = self.fp
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   829
        fp.seek(0)
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   830
        return fp
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   831
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   832
    def jpeg_fh(self):
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   833
        return None
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   834
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   835
    def getSize(self):
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   836
        if (self._width is None or self._height is None):
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   837
            if sys.platform[0:4] == 'java':
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   838
                self._width = self._image.getWidth()
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   839
                self._height = self._image.getHeight()
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   840
            else:
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   841
                self._width, self._height = self._image.size
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   842
        return (self._width, self._height)
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2160
diff changeset
   843
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   844
    def getRGBData(self):
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   845
        "Return byte array of RGB data as string"
3355
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   846
        try:
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   847
            if self._data is None:
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   848
                self._dataA = None
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   849
                if sys.platform[0:4] == 'java':
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   850
                    import jarray
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   851
                    from java.awt.image import PixelGrabber
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   852
                    width, height = self.getSize()
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   853
                    buffer = jarray.zeros(width*height, 'i')
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   854
                    pg = PixelGrabber(self._image, 0,0,width,height,buffer,0,width)
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   855
                    pg.grabPixels()
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   856
                    # there must be a way to do this with a cast not a byte-level loop,
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   857
                    # I just haven't found it yet...
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   858
                    pixels = []
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   859
                    a = pixels.append
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   860
                    for i in range(len(buffer)):
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   861
                        rgb = buffer[i]
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   862
                        a(chr((rgb>>16)&0xff))
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   863
                        a(chr((rgb>>8)&0xff))
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   864
                        a(chr(rgb&0xff))
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   865
                    self._data = ''.join(pixels)
2902
f15ac27dc73f reportlab: add in RGBA functionality for sensible images
rgbecker
parents: 2838
diff changeset
   866
                    self.mode = 'RGB'
3355
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   867
                else:
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   868
                    im = self._image
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   869
                    mode = self.mode = im.mode
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   870
                    if mode=='RGBA':
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   871
                        if Image.VERSION.startswith('1.1.7'): im.load()
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   872
                        self._dataA = ImageReader(im.split()[3])
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   873
                        im = im.convert('RGB')
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   874
                        self.mode = 'RGB'
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   875
                    elif mode not in ('L','RGB','CMYK'):
4086
7df61e325601 utils.py: ImageReader handle png indexed with transparency specially
robin
parents: 4076
diff changeset
   876
                        if im.format=='PNG' and im.mode=='P' and 'transparency' in im.info:
7df61e325601 utils.py: ImageReader handle png indexed with transparency specially
robin
parents: 4076
diff changeset
   877
                            im = im.convert('RGBA')
7df61e325601 utils.py: ImageReader handle png indexed with transparency specially
robin
parents: 4076
diff changeset
   878
                            self._dataA = ImageReader(im.split()[3])
7df61e325601 utils.py: ImageReader handle png indexed with transparency specially
robin
parents: 4076
diff changeset
   879
                            im = im.convert('RGB')
7df61e325601 utils.py: ImageReader handle png indexed with transparency specially
robin
parents: 4076
diff changeset
   880
                        else:
7df61e325601 utils.py: ImageReader handle png indexed with transparency specially
robin
parents: 4076
diff changeset
   881
                            im = im.convert('RGB')
3355
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   882
                        self.mode = 'RGB'
4103
c5c1e06aa8fc attempt to pacify pillow tostring warnings reported by Kale Franz @ bitbucket.org
robin
parents: 4091
diff changeset
   883
                    self._data = (im.tobytes if hasattr(im, 'tobytes') else im.tostring)()  #make pillow and PIL both happy, for now
3355
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   884
            return self._data
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   885
        except:
cc00d31bc99e utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents: 3349
diff changeset
   886
            annotateException('\nidentity=%s'%self.identity())
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   887
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   888
    def getImageData(self):
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   889
        width, height = self.getSize()
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   890
        return width, height, self.getRGBData()
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   891
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   892
    def getTransparent(self):
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   893
        if sys.platform[0:4] == 'java':
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   894
            return None
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   895
        else:
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3291
diff changeset
   896
            if "transparency" in self._image.info:
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   897
                transparency = self._image.info["transparency"] * 3
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   898
                palette = self._image.palette
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   899
                try:
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   900
                    palette = palette.palette
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   901
                except:
3926
c88ad2be5834 utils.py: acoid errors when using greyscale images
robin
parents: 3920
diff changeset
   902
                    try:
c88ad2be5834 utils.py: acoid errors when using greyscale images
robin
parents: 3920
diff changeset
   903
                        palette = palette.data
c88ad2be5834 utils.py: acoid errors when using greyscale images
robin
parents: 3920
diff changeset
   904
                    except:
c88ad2be5834 utils.py: acoid errors when using greyscale images
robin
parents: 3920
diff changeset
   905
                        return None
3765
a7e7cd6e0003 renderPM.py now works to produce a pmout at least
robin
parents: 3741
diff changeset
   906
                if isPy3:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   907
                    return palette[transparency:transparency+3]
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   908
                else:
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   909
                    return [ord(c) for c in palette[transparency:transparency+3]]
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   910
            else:
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   911
                return None
cc042609c62e hack to ImageReader
rgbecker
parents: 2044
diff changeset
   912
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   913
class LazyImageReader(ImageReader): 
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   914
    def fp(self): 
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   915
        return open_for_read(self.fileName, 'b') 
3083
95f7752b0284 reportlab: remove 2.3/2.4 blockers
rgbecker
parents: 3029
diff changeset
   916
    fp=property(fp) 
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   917
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   918
    def _image(self):
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   919
        return self._read_image(self.fp)
3083
95f7752b0284 reportlab: remove 2.3/2.4 blockers
rgbecker
parents: 3029
diff changeset
   920
    _image=property(_image) 
2954
5ec6485e810a reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents: 2953
diff changeset
   921
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   922
def getImageData(imageFileName):
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   923
    "Get width, height and RGB pixels from image file.  Wraps Java/PIL"
2487
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   924
    try:
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   925
        return imageFileName.getImageData()
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   926
    except AttributeError:
a51bf871b709 reportlab: better support for PIL image
rgbecker
parents: 2484
diff changeset
   927
        return ImageReader(imageFileName).getImageData()
2044
3be472f4a6dd Various work on abstracting out images, plus outstanding patches
andy_robinson
parents: 2007
diff changeset
   928
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
   929
class DebugMemo:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   930
    '''Intended as a simple report back encapsulator
1545
966ccacc4c7d Changes to DebugMemo.__doc__
rgbecker
parents: 1543
diff changeset
   931
3028
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   932
    Typical usages:
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   933
        
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   934
    1. To record error data::
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   935
        
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   936
        dbg = DebugMemo(fn='dbgmemo.dbg',myVar=value)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   937
        dbg.add(anotherPayload='aaaa',andagain='bbb')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   938
        dbg.dump()
1543
3681c7d8898d Slight formatting improvements & added payload method
rgbecker
parents: 1538
diff changeset
   939
3028
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   940
    2. To show the recorded info::
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   941
        
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   942
        dbg = DebugMemo(fn='dbgmemo.dbg',mode='r')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   943
        dbg.load()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   944
        dbg.show()
1543
3681c7d8898d Slight formatting improvements & added payload method
rgbecker
parents: 1538
diff changeset
   945
3028
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   946
    3. To re-use recorded information::
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   947
        
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   948
        dbg = DebugMemo(fn='dbgmemo.dbg',mode='r')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   949
            dbg.load()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   950
        myTestFunc(dbg.payload('myVar'),dbg.payload('andagain'))
1545
966ccacc4c7d Changes to DebugMemo.__doc__
rgbecker
parents: 1543
diff changeset
   951
3028
082f5208644e docstring modifications to adhere to restructuredtext
damian
parents: 2964
diff changeset
   952
    In addition to the payload variables the dump records many useful bits
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   953
    of information which are also printed in the show() method.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   954
    '''
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   955
    def __init__(self,fn='rl_dbgmemo.dbg',mode='w',getScript=1,modules=(),capture_traceback=1, stdout=None, **kw):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   956
        import time, socket
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   957
        self.fn = fn
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   958
        if not stdout: 
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   959
            self.stdout = sys.stdout
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   960
        else:
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   961
            if hasattr(stdout,'write'):
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   962
                self.stdout = stdout
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   963
            else:
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   964
                self.stdout = open(stdout,'w')
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   965
        if mode!='w': return
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   966
        self.store = store = {}
2296
8f5419265559 Added capture_traceback=1 to DebugMemo init
rgbecker
parents: 2279
diff changeset
   967
        if capture_traceback and sys.exc_info() != (None,None,None):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   968
            import traceback
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   969
            s = getBytesIO()
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   970
            traceback.print_exc(None,s)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   971
            store['__traceback'] = s.getvalue()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   972
        cwd=os.getcwd()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   973
        lcwd = os.listdir(cwd)
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   974
        pcwd = os.path.dirname(cwd)
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   975
        lpcwd = pcwd and os.listdir(pcwd) or '???'
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   976
        exed = os.path.abspath(os.path.dirname(sys.argv[0]))
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   977
        project_version='???'
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   978
        md=None
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   979
        try:
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   980
            import marshal
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
   981
            md=marshal.loads(__rl_loader__.get_data('meta_data.mar'))
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   982
            project_version=md['project_version']
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   983
        except:
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   984
            pass
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   985
        env = os.environ
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
   986
        K=list(env.keys())
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
   987
        K.sort()
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   988
        store.update({  'gmt': time.asctime(time.gmtime(time.time())),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   989
                        'platform': sys.platform,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   990
                        'version': sys.version,
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   991
                        'hexversion': hex(sys.hexversion),
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   992
                        'executable': sys.executable,
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
   993
                        'exec_prefix': sys.exec_prefix,
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   994
                        'prefix': sys.prefix,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   995
                        'path': sys.path,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   996
                        'argv': sys.argv,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   997
                        'cwd': cwd,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   998
                        'hostname': socket.gethostname(),
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
   999
                        'lcwd': lcwd,
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1000
                        'lpcwd': lpcwd,
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1001
                        'byteorder': sys.byteorder,
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1002
                        'maxint': getattr(sys,'maxunicode','????'),
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1003
                        'api_version': getattr(sys,'api_version','????'),
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1004
                        'version_info': getattr(sys,'version_info','????'),
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1005
                        'winver': getattr(sys,'winver','????'),
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1006
                        'environment': '\n\t\t\t'.join(['']+['%s=%r' % (k,env[k]) for k in K]),
4288
320d4d0667cf attempt to fix __loader__ issues in pyinstaller; version-->3.319
robin
parents: 4265
diff changeset
  1007
                        '__rl_loader__': repr(__rl_loader__),
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1008
                        'project_meta_data': md,
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1009
                        'project_version': project_version,
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1010
                        })
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1011
        for M,A in (
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1012
                (sys,('getwindowsversion','getfilesystemencoding')),
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1013
                (os,('uname', 'ctermid', 'getgid', 'getuid', 'getegid',
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1014
                    'geteuid', 'getlogin', 'getgroups', 'getpgrp', 'getpid', 'getppid',
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1015
                    )),
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1016
                ):
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1017
            for a in A:
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1018
                if hasattr(M,a):
2300
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1019
                    try:
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1020
                        store[a] = getattr(M,a)()
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1021
                    except:
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1022
                        pass
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1023
        if exed!=cwd:
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1024
            try:
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1025
                store.update({'exed': exed, 'lexed': os.listdir(exed),})
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1026
            except:
3896af138a75 Attempt to robustify the memo
rgbecker
parents: 2297
diff changeset
  1027
                pass
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1028
        if getScript:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1029
            fn = os.path.abspath(sys.argv[0])
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1030
            if os.path.isfile(fn):
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1031
                try:
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1032
                    store['__script'] = (fn,open(fn,'r').read())
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1033
                except:
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1034
                    pass
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1035
        module_versions = {}
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1036
        for n,m in sys.modules.items():
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1037
            if n=='reportlab' or n=='rlextra' or n[:10]=='reportlab.' or n[:8]=='rlextra.':
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1038
                v = [getattr(m,x,None) for x in ('__version__','__path__','__file__')]
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
  1039
                if [_f for _f in v if _f]:
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
  1040
                    v = [v[0]] + [_f for _f in v[1:] if _f]
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1041
                    module_versions[n] = tuple(v)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1042
        store['__module_versions'] = module_versions
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1043
        self.store['__payload'] = {}
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1044
        self._add(kw)
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1045
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1046
    def _add(self,D):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1047
        payload = self.store['__payload']
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1048
        for k, v in D.items():
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1049
            payload[k] = v
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1050
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1051
    def add(self,**kw):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1052
        self._add(kw)
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1053
2942
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1054
    def _dump(self,f):
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1055
        try:
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1056
            pos=f.tell()
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
  1057
            pickle.dump(self.store,f)
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1058
        except:
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1059
            S=self.store.copy()
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1060
            ff=getBytesIO()
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
  1061
            for k,v in S.items():
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1062
                try:
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
  1063
                    pickle.dump({k:v},ff)
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1064
                except:
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1065
                    S[k] = '<unpicklable object %r>' % v
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1066
            f.seek(pos,0)
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
  1067
            pickle.dump(S,f)
2942
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1068
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1069
    def dump(self):
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1070
        f = open(self.fn,'wb')
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1071
        try:
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1072
            self._dump(f)
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1073
        finally:
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1074
            f.close()
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1075
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1076
    def dumps(self):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1077
        f = getBytesIO()
2942
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1078
        self._dump(f)
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1079
        return f.getvalue()
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1080
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1081
    def _load(self,f):
4181
0a8d6687fde6 reportlab.lib.utils imports cPickle or pickle
robin
parents: 4124
diff changeset
  1082
        self.store = pickle.load(f)
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1083
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1084
    def load(self):
2942
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1085
        f = open(self.fn,'rb')
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1086
        try:
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1087
            self._load(f)
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1088
        finally:
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1089
            f.close()
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1090
e6e20484c315 reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents: 2929
diff changeset
  1091
    def loads(self,s):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1092
        self._load(getBytesIO(s))
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1093
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1094
    def _show_module_versions(self,k,v):
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1095
        self._writeln(k[2:])
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
  1096
        K = list(v.keys())
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1097
        K.sort()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1098
        for k in K:
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1099
            vk = vk0 = v[k]
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1100
            if isinstance(vk,tuple): vk0 = vk[0]
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1101
            try:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1102
                __import__(k)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1103
                m = sys.modules[k]
3205
c65681e50856 utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents: 3180
diff changeset
  1104
                d = getattr(m,'__version__',None)==vk0 and 'SAME' or 'DIFFERENT'
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1105
            except:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1106
                m = None
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1107
                d = '??????unknown??????'
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1108
            self._writeln('  %s = %s (%s)' % (k,vk,d))
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1109
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1110
    def _banner(self,k,what):
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1111
        self._writeln('###################%s %s##################' % (what,k[2:]))
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1112
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1113
    def _start(self,k):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1114
        self._banner(k,'Start  ')
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1115
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1116
    def _finish(self,k):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1117
        self._banner(k,'Finish ')
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1118
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1119
    def _show_lines(self,k,v):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1120
        self._start(k)
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1121
        self._writeln(v)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1122
        self._finish(k)
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1123
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1124
    def _show_file(self,k,v):
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1125
        k = '%s %s' % (k,os.path.basename(v[0]))
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1126
        self._show_lines(k,v[1])
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1127
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1128
    def _show_payload(self,k,v):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1129
        if v:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1130
            import pprint
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1131
            self._start(k)
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1132
            pprint.pprint(v,self.stdout)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1133
            self._finish(k)
1538
faefcdc303a9 Added DebugMemo stuff
rgbecker
parents: 1537
diff changeset
  1134
3122
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1135
    def _show_extensions(self):
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1136
        for mn in ('_rl_accel','_renderPM','sgmlop','pyRXP','pyRXPU','_imaging','Image'):
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1137
            try:
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1138
                A = [mn].append
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1139
                __import__(mn)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
  1140
                m = sys.modules[mn]
3122
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1141
                A(m.__file__)
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1142
                for vn in ('__version__','VERSION','_version','version'):
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1143
                    if hasattr(m,vn):
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1144
                        A('%s=%r' % (vn,getattr(m,vn)))
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1145
            except:
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1146
                A('not found')
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1147
            self._writeln(' '+' '.join(A.__self__))
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1148
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1149
    specials = {'__module_versions': _show_module_versions,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1150
                '__payload': _show_payload,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1151
                '__traceback': _show_lines,
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1152
                '__script': _show_file,
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1153
                }
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1154
    def show(self):
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
  1155
        K = list(self.store.keys())
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1156
        K.sort()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1157
        for k in K:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
  1158
            if k not in list(self.specials.keys()): self._writeln('%-15s = %s' % (k,self.store[k]))
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1159
        for k in K:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3687
diff changeset
  1160
            if k in list(self.specials.keys()): self.specials[k](self,k,self.store[k])
3122
19218a7fd0e7 utils.py: add DebugMemo._show_extensions
rgbecker
parents: 3083
diff changeset
  1161
        self._show_extensions()
1543
3681c7d8898d Slight formatting improvements & added payload method
rgbecker
parents: 1538
diff changeset
  1162
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1163
    def payload(self,name):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1164
        return self.store['__payload'][name]
1561
1b10f25e76df Add DebugMemo __g/setitem__
rgbecker
parents: 1545
diff changeset
  1165
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1166
    def __setitem__(self,name,value):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1167
        self.store['__payload'][name] = value
1561
1b10f25e76df Add DebugMemo __g/setitem__
rgbecker
parents: 1545
diff changeset
  1168
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1650
diff changeset
  1169
    def __getitem__(self,name):
1833
135322abc191 Fix recursivImport for case when baseDir is a sequence
rgbecker
parents: 1821
diff changeset
  1170
        return self.store['__payload'][name]
2297
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1171
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1172
    def _writeln(self,msg):
7c706ac8a6b7 Added some more stuff and script name to DebugMemo output
rgbecker
parents: 2296
diff changeset
  1173
        self.stdout.write(msg+'\n')
2365
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1174
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1175
def _flatten(L,a):
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1176
    for x in L:
3731
b233dd0577ff another round of changes mostly type related
rptlab
parents: 3729
diff changeset
  1177
        if isSeq(x): _flatten(x,a)
2365
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1178
        else: a(x)
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1179
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1180
def flatten(L):
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1181
    '''recursively flatten the list or tuple L'''
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1182
    R = []
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1183
    _flatten(L,R.append)
cda528e430aa reportlab/lib/utils.py: added flatten utility function
rgbecker
parents: 2356
diff changeset
  1184
    return R
2406
311191cddb33 reportlab lib utils.py: add find_locals
rgbecker
parents: 2365
diff changeset
  1185
311191cddb33 reportlab lib utils.py: add find_locals
rgbecker
parents: 2365
diff changeset
  1186
def find_locals(func,depth=0):
311191cddb33 reportlab lib utils.py: add find_locals
rgbecker
parents: 2365
diff changeset
  1187
    '''apply func to the locals at each stack frame till func returns a non false value'''
311191cddb33 reportlab lib utils.py: add find_locals
rgbecker
parents: 2365
diff changeset
  1188
    while 1:
311191cddb33 reportlab lib utils.py: add find_locals
rgbecker
parents: 2365
diff changeset
  1189
        _ = func(sys._getframe(depth).f_locals)
311191cddb33 reportlab lib utils.py: add find_locals
rgbecker
parents: 2365
diff changeset
  1190
        if _: return _
311191cddb33 reportlab lib utils.py: add find_locals
rgbecker
parents: 2365
diff changeset
  1191
        depth += 1
2454
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1192
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1193
class _FmtSelfDict:
2479
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1194
    def __init__(self,obj,overrideArgs):
2454
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1195
        self.obj = obj
2479
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1196
        self._overrideArgs = overrideArgs
2454
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1197
    def __getitem__(self,k):
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1198
        try:
2479
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1199
            return self._overrideArgs[k]
2454
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1200
        except KeyError:
2479
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1201
            try:
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1202
                return self.obj.__dict__[k]
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1203
            except KeyError:
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1204
                return getattr(self.obj,k)
2454
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1205
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1206
class FmtSelfDict:
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1207
    '''mixin to provide the _fmt method'''
2479
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1208
    def _fmt(self,fmt,**overrideArgs):
ea93388b723d Allow overriding parameters in _fmt utility method
jjlee
parents: 2459
diff changeset
  1209
        D = _FmtSelfDict(self, overrideArgs)
2454
8cc3d50b0703 utils.py: added FmtSelfDict class
rgbecker
parents: 2448
diff changeset
  1210
        return fmt % D
2715
5cdfb604dff2 reportlab/lib/utils.py: added simplSplit func
rgbecker
parents: 2706
diff changeset
  1211
2716
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1212
def _simpleSplit(txt,mW,SW):
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1213
    L = []
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1214
    ws = SW(' ')
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1215
    O = []
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1216
    w = -ws
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1217
    for t in txt.split():
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1218
        lt = SW(t)
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1219
        if w+ws+lt<=mW or O==[]:
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1220
            O.append(t)
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1221
            w = w + ws + lt
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1222
        else:
3134
e403094e7c98 utils.py: removed old string usages
rgbecker
parents: 3122
diff changeset
  1223
            L.append(' '.join(O))
2716
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1224
            O = [t]
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1225
            w = lt
3134
e403094e7c98 utils.py: removed old string usages
rgbecker
parents: 3122
diff changeset
  1226
    if O!=[]: L.append(' '.join(O))
2716
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1227
    return L
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1228
2715
5cdfb604dff2 reportlab/lib/utils.py: added simplSplit func
rgbecker
parents: 2706
diff changeset
  1229
def simpleSplit(text,fontName,fontSize,maxWidth):
2716
6f35525eaffb reportlab/lib/utils.py: fix circular import
rgbecker
parents: 2715
diff changeset
  1230
    from reportlab.pdfbase.pdfmetrics import stringWidth
3998
114ef1ead9fb utils.py: fix some functions to be bytes|unicode --> unicode
robin
parents: 3971
diff changeset
  1231
    lines = asUnicode(text).split(u'\n')
2715
5cdfb604dff2 reportlab/lib/utils.py: added simplSplit func
rgbecker
parents: 2706
diff changeset
  1232
    SW = lambda text, fN=fontName, fS=fontSize: stringWidth(text, fN, fS)
5cdfb604dff2 reportlab/lib/utils.py: added simplSplit func
rgbecker
parents: 2706
diff changeset
  1233
    if maxWidth:
5cdfb604dff2 reportlab/lib/utils.py: added simplSplit func
rgbecker
parents: 2706
diff changeset
  1234
        L = []
5cdfb604dff2 reportlab/lib/utils.py: added simplSplit func
rgbecker
parents: 2706
diff changeset
  1235
        for l in lines:
4241
d75df65a5ce5 fix bug in reportlab.lib.utils.simpleSplit reported by Chris Buergi <cb@enerweb.ch>; version -->3.2.12
robin
parents: 4237
diff changeset
  1236
            L.extend(_simpleSplit(l,maxWidth,SW))
2715
5cdfb604dff2 reportlab/lib/utils.py: added simplSplit func
rgbecker
parents: 2706
diff changeset
  1237
        lines = L
5cdfb604dff2 reportlab/lib/utils.py: added simplSplit func
rgbecker
parents: 2706
diff changeset
  1238
    return lines
2764