Re: Nesting Custom Errors in Classes

2019-07-23 Thread Cameron Simpson

On 24Jul2019 11:47, DL Neil  wrote:

On 24/07/19 10:07 AM, Cameron Simpson wrote:

On 24Jul2019 07:21, DL Neil  wrote:

...

Get some linting tools. They're great for catching this kind of error.


SublimeText has SublimeLinter and PycodeStyle installed, but I'm still 
familiarising myself with ST. Nothing is reported.


Any advice/correction/improvement would be most welcome...


Hmm. I'd expect a linter to catch this:

 # forgot FooException
 from foo import FooClass
 def f():
   raise FooException

Can you test that with a small script at your end (with real imports and 
names of course)?


I lint from the command line with this script:

 https://bitbucket.org/cameron_simpson/css/src/tip/bin-cs/lint

which runs a few Python linters for Python.

WRT SublimeText, PycodeStyle likely only checks style (I've now shifted 
to an automatic formatter for this) and SublimeLinter's PythonLinter 
page is... silent; it looks like a base class for other actual linters.  
You might need to do some more digging. Maybe you need some addition 
lint stuff for SublimeText.


The tricky bit with dynamic language like Python is that some naming 
errors (missed imports) aren't apparent until the code passes through 
that path. Linters can cover a lot of this with static analysis.


Exactly!
(PyTest and coverage tools were no help - they import correctly (and 
test adequately), but I didn't open those (separate) modules to notice 
the multiple import-s)


Hope springs eternal ... there must be a better way???


A good linter is usually decent at complaining about code using names 
that aren't defined (not imports, not otherwise defined such as a 
function or a variable assignment).


(well yes, not wishing to 'flog a dead horse' (nor any horse for that 
matter) I'm pleased at the (lack of negative) response to my allied 
question about nested classes, which would solve the original problem)


There's nothing "wrong" with it. It is uncommon. But like a lot of 
things, the value (or cost/pitfalls) come with how things are to be 
used.


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Nesting Custom Errors in Classes

2019-07-23 Thread DL Neil

On 24/07/19 10:07 AM, Cameron Simpson wrote:

On 24Jul2019 07:21, DL Neil  wrote:

...

Get some linting tools. They're great for catching this kind of error.


SublimeText has SublimeLinter and PycodeStyle installed, but I'm still 
familiarising myself with ST. Nothing is reported.


Any advice/correction/improvement would be most welcome...


The tricky bit with dynamic language like Python is that some naming 
errors (missed imports) aren't apparent until the code passes through 
that path. Linters can cover a lot of this with static analysis.


Exactly!
(PyTest and coverage tools were no help - they import correctly (and 
test adequately), but I didn't open those (separate) modules to notice 
the multiple import-s)


Hope springs eternal ... there must be a better way???

(well yes, not wishing to 'flog a dead horse' (nor any horse for that 
matter) I'm pleased at the (lack of negative) response to my allied 
question about nested classes, which would solve the original problem)


--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Nesting Custom Errors in Classes

2019-07-23 Thread Cameron Simpson

On 24Jul2019 07:21, DL Neil  wrote:
Accordingly, the idea that there would be a ClassyThing() but it might 
be quite different from another ClassyThing() just makes me shudder!

(sorry, I guess it's that sheltered upbringing ... again!)


It needn't be very different on the outside. The whole point of object 
oriented programme is to present things with the same external API but 
different internal implementations, or managing a different thing with 
common characteristics.


I have use nested classes when the nested class is strongly associated 
with the enclosing class, like your classname.exceptionname example. 
I'd put it inside the outer class entirely to express that 
association.


...and, because the (?old) boy can't be relied upon to remember to 
import both, nesting saves-the-day!


Get some linting tools. They're great for catching this kind of error.

The tricky bit with dynamic language like Python is that some naming 
errors (missed imports) aren't apparent until the code passes through 
that path. Linters can cover a lot of this with static analysis.


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Nesting Custom Errors in Classes

2019-07-23 Thread DL Neil

On 23/07/19 11:55 PM, Cameron Simpson wrote:

On 23Jul2019 14:54, DL Neil  wrote:

Do you use nested classes?
Python manages nested classes.

I've NEVER seen such 'in the wild'.
(but perhaps I lead a sheltered life?)


So sheltered :-)


Well, over here there aren't the venomous creatures you live amongst on 
'west island'...




In my experience it's uncommon. I've done it a few times.

"Nested" classes aren't anything very special; they're no more than yet 
another name defined inside a class, like a method, or a "constant". Look:



Thanks for the explanation. I've absorbed the concept, but back in the 
?good, old days it was common practice to alter code programmatically, 
ie whilst the pgm was running. The perils of not quite knowing what the 
code 'is' and thus what it should be doing for us, constitute a 
debugging nightmare. (but hey, even flicking toggle-switches on the 
front of an IBM System/360 to load binary data into a specified memory 
address, seemed like 'great power' - at the time *cue SpiderMan quote)


Accordingly, the idea that there would be a ClassyThing() but it might 
be quite different from another ClassyThing() just makes me shudder!

(sorry, I guess it's that sheltered upbringing ... again!)

As you say...

Personally, I haven't done the above. But I have made subclasses where 
the subclass overrides a constant, like DEFAULT_FOO_MAX earlier. Then 
accessing self.DEFAULT_FOO_MAX finds the appropriate constant.


And on thinking about it, while I haven't explicitly nested classes, I 
have passed in a class to the init method, for example an indexclass. 
I've a package which support several backend hash indices, such as gdbm, 
and I pass in the target index class. So a class as a parameterisable or 
inheritable thing isn't nonsensical.


I have use nested classes when the nested class is strongly associated 
with the enclosing class, like your classname.exceptionname example. I'd 
put it inside the outer class entirely to express that association.


...and, because the (?old) boy can't be relied upon to remember to 
import both, nesting saves-the-day!


--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Nesting Custom Errors in Classes

2019-07-23 Thread Rob Gaddi

On 7/22/19 7:54 PM, DL Neil wrote:

Do you use nested classes?

[following-on from the earlier, "Namespaces: memory vs 'pollution'" discussion 
thread, wherein a certain 'someone' remembered to from ... import ... as ... an 
'action' class but forgot to also import the related custom error class! The 
original quest was for a wild-card import device. This discussion may obviate 
continuing the quest and/or needing to remember...]



Python manages nested classes.

I've NEVER seen such 'in the wild'.
(but perhaps I lead a sheltered life?)


What are proposed as use-cases for such a technique?
- other languages may not offer decent "inheritance", and this is an alternative 
method/hack

- the class is a 'class factory', generating/returning an object
? any others


Why not use it as an "encapsulation" device?
(please be gentle - reminder: I am too old to have been an OO-native!)


* stub definitions

 >>> class PythonEnvironment():
... class PythonVersionError( EnvironmentError ):
... pass
... def iscompatible( self ):
     ''' Ensure that the Python in-use will support
     all of the facilities employed by the application.
     '''
... # stub to simulate failure
... raise self.PythonVersionError
...

(code would require an import or from ... import ...)
 >>> pe = PythonEnvironment()


* its basic application becomes:-

 >>> pe.iscompatible()
Traceback (most recent call last):
   File "", line 1, in 
   File "", line 6, in compatibility
__main__.PythonVersionError


* somewhat more realistic use:-

 >>> try:
... pe.iscompatible()
... except PythonEnvironment.PythonVersionError:
... print( "Trapped! -> informative errmsg" )
...
Trapped! -> informative errmsg


With this construct, one only has to import the 'outer' class, rather than both 
the class AND its ancillary error class!



Why haven't I seen it before? Can you see anything 'wrong' with this picture?


I've used them sometimes for basic encapsulation principles without really 
gaining anything.  I use inheritance of nested classes in my 
https://pypi.org/project/indexedproperty/ project, where subclasses of 
IndexedProperty have a _Trampoline inner class subclassed from Trampoline that 
can be redefined as needed, but that's a bit of an obscure use case.


--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order.  See above to fix.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Nesting Custom Errors in Classes

2019-07-23 Thread Cameron Simpson

On 23Jul2019 14:54, DL Neil  wrote:

Do you use nested classes?
Python manages nested classes.

I've NEVER seen such 'in the wild'.
(but perhaps I lead a sheltered life?)


So sheltered :-)

In my experience it's uncommon. I've done it a few times.

"Nested" classes aren't anything very special; they're no more than yet 
another name defined inside a class, like a method, or a "constant".  
Look:


 class Foo:

   DEFAULT_FOO_MAX = 10

   def __init__(...):
 ...

   class SpecialThing:
 ...

They're all just various names in the class space.

I would do it if SpecialThing wasn't meaningful outside of the class 
i.e. didn't really have a standalone use.


Aside from not polluting the top level namespace with names that aren't 
useful on their own (which is kind of irrelevant since people tend to 
"from foo import name", so the _number_ of available names isn't very 
important)...


One potential benefit to to associating the inner class with the outer 
class is the inheritance chain. Look:


 class Foo:

   class ClassyThing:
 ...

   def frob(self, it):
 for i in it:
   x = self.ClassyThing(i)
   x.do_something_classy(...)

 class Bah(Foo):

   class ClassyThing:
 ...

 f = Foo()
 f.frob([1,2,3])

 b = Bah()
 b.frob([1,2,3])

Foo and Bah have a common method "frob", but f.frob will generate and 
use Foo.ClassyThing objects while b.frob will generate Bah.ClassyThing 
objects. Same code.


Personally, I haven't done the above. But I have made subclasses where 
the subclass overrides a constant, like DEFAULT_FOO_MAX earlier. Then 
accessing self.DEFAULT_FOO_MAX finds the appropriate constant.


And on thinking about it, while I haven't explicitly nested classes, I 
have passed in a class to the init method, for example an indexclass.  
I've a package which support several backend hash indices, such as gdbm, 
and I pass in the target index class. So a class as a parameterisable or 
inheritable thing isn't nonsensical.


I have use nested classes when the nested class is strongly associated 
with the enclosing class, like your classname.exceptionname example. I'd 
put it inside the outer class entirely to express that association.


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list