Re: type annotation vs working code

2023-10-01 Thread Karsten Hilbert via Python-list
Sorry for having conflated the core of the matter with all
the Borg shenanigans, that's where I found the problem in my
real code, so there :-)

Consider this:

#
class Surprise:
def __init__(self, with_type_annotation=False):
if with_type_annotation:
try:
self.does_not_exist:bool
print('does_not_exist does exist')
except AttributeError:
print('does_not_exist does not exist')
return

try:
self.does_not_exist
print('does_not_exist does exist')
except AttributeError:
print('does_not_exist does not exist')

Surprise(with_type_annotation = False)
Surprise(with_type_annotation = True)
#

Is this how it is supposed to be ?


> ...and so we're addressing the important question: the try-test is for 
> existence, cf for
> some value.
>
> This can also be achieved by using the attribute in a legal expression, eg:
...
> Might this remove the confusion (ref: @Mats):
>
> self.already_initialized:bool == True

Not for me as that would _create_ already_initialized on the
instance. It would not allow me to test for it.

> >Which seems akin constructs for generating compatibility
> >between versions.
>
> versions of ?

Of the language. Sometimes one tests for existence of a given
class in a module and defines said class oneself if it does
not exist. But that's leading astray.

> What is the intent: a class where each instance is aware of every other 
> instance - yet
> the word "Singleton" implies there's only one (cf a dict full of ...)?

The latter.

Regards,
Karsten
--
GPG  40BE 5B0E C98E 1713 AFA6  5BC0 3BEA AC80 7D4F C89B
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: type annotation vs working code

2023-10-01 Thread Chris Angelico via Python-list
On Sun, 1 Oct 2023 at 22:58, Karsten Hilbert via Python-list
 wrote:
>
> Sorry for having conflated the core of the matter with all
> the Borg shenanigans, that's where I found the problem in my
> real code, so there :-)
>
> Consider this:
>
> #
> class Surprise:
> def __init__(self, with_type_annotation=False):
> if with_type_annotation:
> try:
> self.does_not_exist:bool
> print('does_not_exist does exist')
> except AttributeError:
> print('does_not_exist does not exist')
> return
>
> try:
> self.does_not_exist
> print('does_not_exist does exist')
> except AttributeError:
> print('does_not_exist does not exist')
>
> Surprise(with_type_annotation = False)
> Surprise(with_type_annotation = True)
> #
>
> Is this how it is supposed to be ?

The class isn't even significant here. What you're seeing is simply
that an annotation does not evaluate the expression.

https://peps.python.org/pep-0526/

It's basically a coincidence that your two versions appear nearly
identical. They are quite different semantically. Note that annotating
the expression "self.does_not_exist" is not particularly meaningful to
Python, and I've no idea what different type checkers will do with it;
you normally only annotate variables that you own - so, in a function,
that's function-local variables. Instead, class and instance
attributes should be annotated at the class level, which would remove
this apparent similarity.

This is a very good reason NOT to arbitrarily add type hints to code.
Type hints do not inherently improve code, and making changes just for
the sake of adding them risks making semantic changes that you didn't
intend. Python uses a system of gradual typing for very good reason;
you should be able to add hints only to the places where they're
actually useful, leaving the rest of the code untouched.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: type annotation vs working code

2023-10-01 Thread Richard Damon via Python-list
My view of the issue is that the "trick" of "evaluating" a name to see 
if the object has been initialized is just a tad on the "tricky" side, 
and the annotation/value is really incorrect.


The name at the point you are annotating it, isn't really a "bool" 
because a bool will always have either the value "True" or "False", 
while for this variable, you are really testing if it exists or not.


Perhaps a better method would be rather than just using the name and 
catching the exception, use a real already_initialized flag (set to True 
when you initialize), and look it up with getattr() with a default value 
of False.


--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list


Re: type annotation vs working code

2023-10-01 Thread Barry via Python-list



> On 1 Oct 2023, at 19:36, Richard Damon via Python-list 
>  wrote:
> 
> Perhaps a better method would be rather than just using the name and catching 
> the exception, use a real already_initialized flag (set to True when you 
> initialize), and look it up with getattr() with a default value of False.
I would use a class variable not an instance variable.

class OnlyOne:
   sole_instance = None
   def __init__(self):
  assert OnlyOne.sole_instance is None
  OnlyOne.sole_instance = self

Barry


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: type annotation vs working code

2023-10-01 Thread Chris Angelico via Python-list
On Mon, 2 Oct 2023 at 09:10, Barry via Python-list
 wrote:
>
>
>
> > On 1 Oct 2023, at 19:36, Richard Damon via Python-list 
> >  wrote:
> >
> > Perhaps a better method would be rather than just using the name and 
> > catching the exception, use a real already_initialized flag (set to True 
> > when you initialize), and look it up with getattr() with a default value of 
> > False.
> I would use a class variable not an instance variable.
>
> class OnlyOne:
>sole_instance = None
>def __init__(self):
>   assert OnlyOne.sole_instance is None
>   OnlyOne.sole_instance = self
>

Agreed, except that this should be an if-raise rather than an assert.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list