Question on ABC classes

Julio Di Egidio julio at diegidio.name
Thu Oct 29 22:03:34 EDT 2020


On Sunday, 25 October 2020 20:55:26 UTC+1, Peter J. Holzer  wrote:
> On 2020-10-22 23:35:21 -0700, Julio Di Egidio wrote:
> > On Friday, 23 October 2020 07:36:39 UTC+2, Greg Ewing  wrote:
> > > On 23/10/20 2:13 pm, Julio Di Egidio wrote:
> > > > I am now thinking whether I could achieve the "standard"
> > > > behaviour via another approach, say with decorators, somehow
> > > > intercepting calls to __new__... maybe.
> > > 
> > > I'm inclined to step back and ask -- why do you care about this?
> > > 
> > > Would it actually do any harm if someone instantiated your
> > > base class? If not, then it's probably not worth going out
> > > of your way to prevent it.
> > 
> > This is the first little library I try to put together
> > in Python, and it was natural for me to hit it with all
> > the relevant decorations as well as type annotations in
> > order to expose *strict* contracts, plus hopefully have
> > intellisense work all over the place.
> 
> I think you are trying to use Python in a way contrary to its nature.
> Python is a dynamically typed language. Its variables don't have types,
> only its objects. And basically everything can be changed at runtime ...

Consider this example:

def abs(x):
  return math.sqrt(x.re**2 + x.im**2)

That of course fails if we pass an object not of the correct
(duck) type.  But the exception is raised by math.sqrt, which,
properly speaking, beside considerations on usability, is a
private detail of the implementation of abs.

The point is more about what the function semantically
represents and to which point the implementation fulfils
that promise/contract.  What is that "abs" really supposed
to provide?  Let's say: << 'abs', given a "complex number"
(duck-typed or not), returns its "real number" magnitude >>.
And that's it, not just the doc but really what *type* of
computation it is, and then the mathematics we can apply
to types.

And an effect is that, by constraining the domains (and
codomains) of functions, we make verification of correctness,
the need for defensive coding, as well as for plain testing,
less onerous by orders of magnitude.

So, at least for a function in a public interface, we *must*
add validation (and the doc string):

def abs(x):
  """...as above..."""
  if not isinstance(x, ComplexNumber):
    raise TypeError(...)
  return math.sqrt(x.re**2 + x.im**2)

and then why not rather write:

@typechecked
def abs(x: ComplexNumber) -> RealNumber:
  return math.sqrt(x.re**2 + x.im**2)

i.e. checked by the tools statically and/or at runtime,
with, for easy intellisense, the default doc string that
comes from the signature?

More generally, I do think dynamic typing leads to interesting
patterns of reuse, but I think "unconstrained" is a red herring:
ab initio there is a *requirement* to fulfil.

> It now has type annotations, but they are ignored both by the compiler
> and at run-time. They are only for the benefit of linting tools like
> mypy and editor features like intellisense.

For the chronicle, I have meanwhile switched from pylint to
mypy (in VSCode) and things have improved dramatically, from
configurability to intellisense to static type checking working
pretty well.  I have meanwhile also realised that the built-in
solutions (the typing module and so on) as well as the tools
supporting them (including those for runtime validation) are
still quite young, so instead of venting frustration (and I
must say so far I think the typing module is a mess), as I
have done in the OP, I should be patient, rather possibly
give a hand...

> > and the whole lot, indeed why even subclass ABC?
> 
> Good question. In six years of programming Python, I've never used ABC.
> But then I came from another dynamically typed language to Python.

Back in the day we had a laugh when intellisense was invented...
but now, with the eco-info-system booming with everything and the
contrary of everything (to put it charitably), I think it's about
(formal, as much as possible) verifiability and correctness.

Anyway. my 2c.  Sorry for the long post and thanks for the feedback.

Julio


More information about the Python-list mailing list