[Tutor] Debug help
Jim
jf_byrnes at comcast.net
Sun Jul 26 17:02:19 EDT 2020
On 7/22/20 6:49 PM, Cameron Simpson wrote:
>>
>> I am finally able to get back to this discussion. Thanks for the great
>> explanation of try/except. I was always confused when people talked
>> about only catch what you expect and can handle. I googled python
>> exceptions and found a list of them. It makes more sense now.
>
> A random google found reference might not be ideal (not to mention that
> programmes can invent their own). Consider these links:
>
> The Builtin Exceptions
> https://docs.python.org/3/library/exceptions.html
>
> Exceptions in the Python execution model
> https://docs.python.org/3/reference/executionmodel.html#exceptions
>
> Errors and Exceptions from the Python Tutorial
> https://docs.python.org/3/tutorial/errors.html
Thanks for the links. I ended up reading through the explanation from
the docs for Python 3.8
>> The error that promoted my question was:
>>
>> uno.RuntimeException: Couldn't convert Date
>> 2020-07-17 134858.5
>> 2020-07-17 134858.5
>> Name: Close, dtype: float64 to a UNO type; caught exception: <class
>> 'AttributeError'>: 'Series' object has no attribute 'getTypes',
>> traceback follows
>>
>> This comes from the module ooSheet, because it was given data in a
>> form it did not expect. Can try/except be used to catch exemptions
>>from an imported module? In this case I would want the program to
>> stop, but I imagine there could be a case where I would want it to
>> continue.
>
> Not easily. Sometimes not at all. This is because the place where
> something could most usefully be done is buried deep in the code. By the
> time the exception reaches you too much follow on logic has been
> skipped, and you won't have whatever data should have been returned. If
> you're getting a series of data from a generator, the generator will
> have exiting with the exception and all the following data will be
> missing, and so forth.
>
> You can of course catch the exception and continue your own local
> control structure eg the next loop iteration.
>
> Your choices depend on how the exception occurred and the internal
> structure of the module you're using.
>
> Have a look at the stack trace - it will identify where the exception
> was raised. This includes the soruce code references!
>
> Options include:
>
> Call something lower level. Suppose you code is calling a function which
> returns spreadsheet like data, some table of values from the stock data.
> Likely that function itself calls lower level things to process the data
> and construct the array. You could do that work yourself, and call some
> per-row function, and catch the exception on a row-by-row basis,
> skipping (and reporting in detail) the bad row.
>
> Pass in a special parser. Some libraries have a degree of extensibility
> in mind, and have a hook for a custom parser, i.e. a functioin to
> convert the raw data into whatever data type you intend to get. If
> there's such a hook, use it. Initially you can find out the default
> parser function, and write a small function which:
> - calls the default with a try/except
> - catches exceptions and reports the exception and the dfata which
> raised it, and return maybe None
>
> For example:
>
> # you'd need to find this, if it exists
> default_parser = module.something
>
> def my_parser(row):
> try:
> return default_parser(row)
> except Exception as e:
> print("default_parser fails on row %r with exception %s" % (row, e))
> return None
>
> data = ticker.fetch(parser=my_parser)
>
> Obviously this requires the module to offer this facility.
>
> Monkey patch! Modify the modul in place.
>
> Monkey patching is where you alter a module after it is loaded. In your
> case, look at the module source code and find the low level function
> which raised the exception. This is available in the stack trace!
>
> Let's suppose the low level thing is module.parse_datum(), to invent a
> name. You can do the custom parser with a monkey patch:
>
> import yf
>
> # you'd need to find this, if it exists
> original_parser = yf.parse_datum
>
> def my_parse_datum(datum):
> try:
> return original_parse_datum(datum)
> except Exception as e:
> print("yf.parse_datum fails on %r with exception %s" % (datum, e))
> # you could parse datum specially here, if you know what to
> # handle
> return None
>
> # monkey patch here:
> yf.parse_datum = my_parse_datum
>
> ...
> yf.Ticker(...)
> ...
>
> Now your special function is in the module where the original parser
> was, and _uses_ the original parse unless it fails.
>
> If nothing else, this provides the data causing the trouble. And you can
> then write your own code to handle just that data when it shows up!
>
Thanks for the explanation.
Regards, Jim
More information about the Tutor
mailing list