33
33
from logbook import Logger , FileHandler
34
34
35
35
from qdb .comm import RemoteCommandManager , fmt_msg
36
+ from qdb .config import QdbConfig
36
37
from qdb .errors import QdbUnreachableBreakpoint , QdbQuit , QdbExecutionTimeout
37
38
from qdb .utils import Timeout , default_eval_fn , default_exception_serializer
38
39
@@ -55,74 +56,46 @@ def __new__(cls, *args, **kwargs):
55
56
cls ._instance = super (Qdb , cls ).__new__ (cls , * args , ** kwargs )
56
57
return cls ._instance
57
58
58
- def __init__ (self ,
59
- host = 'localhost' ,
60
- port = 8001 ,
61
- auth_msg = '' ,
62
- default_file = None ,
63
- default_namespace = None ,
64
- eval_fn = None ,
65
- exception_serializer = None ,
66
- skip_fn = None ,
67
- pause_signal = None ,
68
- redirect_output = True ,
69
- retry_attepts = 10 ,
70
- uuid = None ,
71
- cmd_manager = None ,
72
- green = False ,
73
- repr_fn = None ,
74
- log_file = None ,
75
- execution_timeout = None ):
76
- """
77
- Host and port define the address to connect to.
78
- The auth_msg is a message that will be sent with the start event to the
79
- server. This can be used to do server/tracer authentication.
80
- The default_file is a file to use if the file field is ommited from
81
- payloads.
82
- eval_fn is the function to eval code where the user may provide it,
83
- for example in a conditional breakpoint, or in the repl.
84
- skip_fn is simmilar to the skip list feature of Bdb, except that
85
- it should be a function that takes a filename and returns True iff
86
- the debugger should skip this file. These files will be suppressed from
87
- stack traces.
88
- The pause_signal is signal to raise in this program to trigger a pause
89
- command. If this is none, this will default to SIGUSR2.
90
- retry_attempts is the number of times to attempt to connect to the
91
- server before raising a QdbFailedToConnect error.
92
- The repr_fn is a function to use to convert objects to strings to send
93
- then back to the server. By default, this wraps repr by catching
94
- exceptions and reporting them to the user.
95
- The uuid is the identifier on the server for this session. If none is
96
- provided, it will generate a uuid4.
97
- cmd_manager should be a callable that takes a Qdb instance and manages
98
- commands by implementing a next_command method. If none, a new, default
99
- manager will be created that reads commands from the server at
100
- (host, port).
101
- If green is True, this will use gevent safe timeouts, otherwise this
102
- will use signal based timeouts.
103
- repr_fn is the repr function to use when displaying results. If None,
104
- use the builtin repr.
105
- execution_timeout is the amount of time user code has to execute before
106
- being cut short. This is applied to the repl, watchlist and conditional
107
- breakpoints. If None, no timeout is applied.
59
+ def __init__ (self , config = None , merge = False , ** kwargs ):
60
+ """
61
+ See qdb.config for more information about the configuration of
62
+ qdb.
63
+ merge denotes how config and kwargs should be merged.
64
+ QdbConfig.kwargs_first says config will trample kwargs,
65
+ QdbConfig.config_first says kwargs will trample config.
66
+ Otherwise, kwargs and config cannot both be passed.
108
67
"""
109
68
super (Qdb , self ).__init__ ()
110
- self .address = host , port
111
- self .set_default_file (default_file )
112
- self .default_namespace = default_namespace or {}
113
- self .exception_serializer = exception_serializer or \
69
+ if config and kwargs :
70
+ if merge == QdbConfig .kwargs_first :
71
+ first = kwargs
72
+ second = config
73
+ elif merge == QdbConfig .config_first :
74
+ first = config
75
+ second = kwargs
76
+ else :
77
+ raise TypeError ('Cannot pass config and kwargs' )
78
+ config = first .merge (second )
79
+ else :
80
+ config = QdbConfig .get_config (config or kwargs )
81
+
82
+ self .address = config .host , config .port
83
+ self .set_default_file (config .default_file )
84
+ self .default_namespace = config .default_namespace or {}
85
+ self .exception_serializer = config .exception_serializer or \
114
86
default_exception_serializer
115
- self .eval_fn = eval_fn or default_eval_fn
116
- self .green = green
87
+ self .eval_fn = config . eval_fn or default_eval_fn
88
+ self .green = config . green
117
89
self ._file_cache = {}
118
- self .redirect_output = redirect_output
119
- self .retry_attepts = retry_attepts
120
- self .repr_fn = repr_fn
121
- self .skip_fn = skip_fn or (lambda _ : False )
122
- self .pause_signal = pause_signal if pause_signal else signal .SIGUSR2
123
- self .uuid = str (uuid or uuid4 ())
90
+ self .redirect_output = config .redirect_output
91
+ self .retry_attepts = config .retry_attepts
92
+ self .repr_fn = config .repr_fn
93
+ self .skip_fn = config .skip_fn or (lambda _ : False )
94
+ self .pause_signal = config .pause_signal \
95
+ if config .pause_signal else signal .SIGUSR2
96
+ self .uuid = str (config .uuid or uuid4 ())
124
97
self .watchlist = {}
125
- self .execution_timeout = execution_timeout
98
+ self .execution_timeout = config . execution_timeout
126
99
# We need to be able to send stdout back to the user debugging the
127
100
# program. We hold a handle to this in case the program resets stdout.
128
101
if self .redirect_output :
@@ -134,13 +107,11 @@ def __init__(self,
134
107
sys .stderr = self .stderr
135
108
self .forget ()
136
109
self .log_handler = None
137
- if log_file :
138
- self .log_handler = FileHandler (log_file )
110
+ if config . log_file :
111
+ self .log_handler = FileHandler (config . log_file )
139
112
self .log_handler .push_application ()
140
- if not cmd_manager :
141
- cmd_manager = RemoteCommandManager
142
- self .cmd_manager = cmd_manager (self )
143
- self .cmd_manager .start (auth_msg )
113
+ self .cmd_manager = (config .cmd_manager or RemoteCommandManager )(self )
114
+ self .cmd_manager .start (config .auth_msg )
144
115
145
116
def clear_output_buffers (self ):
146
117
"""
0 commit comments