Hi!
Consider this simple script ...
___________________
from typing import List, Optional
class GLOBALS:
foos=None
class Foo:
def __init__(self):
pass
class Foos:
Foos: List[Foo]=[]
# SOME GLOBALS ARE USED HERE in a real script
def __init__(self):
pass
GLOBALS.foos: Optional[Foos]=Foos()
___________________
Running mypy on it:
pt9.py:18: error: Type cannot be declared in assignment to non-self
attribute
pt9.py:18: error: Incompatible types in assignment (expression has type "Foos", variable has type "None")
Line 18 is last line and pt9.py is the scrip.
Replacing last line by
GLOBALS.foos=Foos()
and running mypy still gives the second error.
pt9.py:18: error: Incompatible types in assignment (expression has type "Foos", variable has type "None")
What is the common practice in these cases?
Thank you.
--
https://mail.python.org/mailman/listinfo/python-list
Do you want the following?
```
from typing import List, Optional
class GLOBALS:
foos: Optional[Foos] = None
class Foo:
def __init__(self):
pass
class Foos:
Foos: List[Foo] = []
def __init__(self):
pass
GLOBALS.foos = Foos()
```
Kind regards,
Sam Ezeh
On Sat, 29 Oct 2022 at 22:13, Paulo da Silva < p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> wrote:
Hi!
Consider this simple script ...
___________________
from typing import List, Optional
class GLOBALS:
foos=None
class Foo:
def __init__(self):
pass
class Foos:
Foos: List[Foo]=[]
# SOME GLOBALS ARE USED HERE in a real script
def __init__(self):
pass
GLOBALS.foos: Optional[Foos]=Foos()
___________________
Running mypy on it:
pt9.py:18: error: Type cannot be declared in assignment to non-self
attribute
pt9.py:18: error: Incompatible types in assignment (expression has type
"Foos", variable has type "None")
Line 18 is last line and pt9.py is the scrip.
Replacing last line by
GLOBALS.foos=Foos()
and running mypy still gives the second error.
pt9.py:18: error: Incompatible types in assignment (expression has type
"Foos", variable has type "None")
What is the common practice in these cases?
Thank you.
--
https://mail.python.org/mailman/listinfo/python-list
Out of interest, tested snippet in PyCharm, cf native-mypy. It flags the original:
   GLOBALS.foos: Optional[Foos]=Foos()
but not the fall-back:
   GLOBALS.foos=Foos()
Must admit, the first query coming to mind was: why is the typing taking place at initialisation-time, rather than within the (class) definition?
At definition time "foos" has already been typed as None by implication!
Solution (below) will not work if the mention of Foos in GLOBALS is a forward-reference. Either move GLOBALS to suit, or surround "Foos" with quotes.This is the problem for me. So far, without typing, I used to have some
Also, these days (Python version allowing) importing "List" is
unnecessary. Instead could use "list".
On 30/10/2022 10.23, Sam Ezeh wrote:
Do you want the following?
```
from typing import List, Optional
class GLOBALS:
    foos: Optional[Foos] = None
class Foo:
    def __init__(self):
        pass
class Foos:
    Foos: List[Foo] = []
    def __init__(self):
        pass
GLOBALS.foos = Foos()
```
Kind regards,
Sam Ezeh
On Sat, 29 Oct 2022 at 22:13, Paulo da Silva <
p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> wrote:
Hi!
Consider this simple script ...
___________________
from typing import List, Optional
class GLOBALS:
     foos=None
class Foo:
     def __init__(self):
         pass
class Foos:
     Foos: List[Foo]=[]
     # SOME GLOBALS ARE USED HERE in a real script
     def __init__(self):
         pass
GLOBALS.foos: Optional[Foos]=Foos()
___________________
Running mypy on it:
pt9.py:18: error: Type cannot be declared in assignment to non-self
attribute
pt9.py:18: error: Incompatible types in assignment (expression has type
"Foos", variable has type "None")
Line 18 is last line and pt9.py is the scrip.
Replacing last line by
GLOBALS.foos=Foos()
and running mypy still gives the second error.
pt9.py:18: error: Incompatible types in assignment (expression has type
"Foos", variable has type "None")
What is the common practice in these cases?
Thank you.
--
https://mail.python.org/mailman/listinfo/python-list
Solution (below) will not work if the mention of Foos in GLOBALS is aThis is the problem for me. So far, without typing, I used to have some config and globals classes, mostly to just group definitions an make the program more readable. A matter of taste and style.
forward-reference. Either move GLOBALS to suit, or surround "Foos"
with quotes.
Now, "typing" is breaking this, mostly because of this forward reference issue.
class GLOBALS:
Foos: Optional[Foos]=None
The funny thing is that if I replace foos by Foos it works because it
gets known by the initial initialization :-) !
On 30/10/2022 11.59, Paulo da Silva wrote:Thank you.
Solution (below) will not work if the mention of Foos in GLOBALS is aThis is the problem for me. So far, without typing, I used to have
forward-reference. Either move GLOBALS to suit, or surround "Foos"
with quotes.
some config and globals classes, mostly to just group definitions an
make the program more readable. A matter of taste and style.
Agreed, a good practice.
Now, "typing" is breaking this, mostly because of this forward
reference issue.
As a first step, use the quotation-marks to indicate that such will be defined later in the code:-
class GLOBALS:
   Foos: Optional[Foos]=None
class GLOBALS:
   Foos: Optional["Foos"]=None
Later, as gather (typing) expertise, can become more sophisticated, as-and-when...
The funny thing is that if I replace foos by Foos it works because it
gets known by the initial initialization :-) !
Is the objective to write (good) code, or merely to satisfy the
type-checker?
Something that is misleading is not going to be appreciated by others (including the +6-months you), eg
a = a + 1Â Â # decrement total
Typing is not compulsory, and has been designed so that we can implement
it a bit at a time, eg only one function amongst many contained by a
module - if that's the only code that requires maintenance/update.
Best not to create "technical debt" though!
Às 22:34 de 29/10/22, dn escreveu:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Solution (below) will not work if the mention of Foos in GLOBALS is a forward-reference.
Either move GLOBALS to suit, or surround "Foos" with quotes.
This is the problem for me.
The funny thing is that if I replace foos by Foos it works because it gets known by the initial initialization :-) ![...]
________________________
from typing import List, Optional
class GLOBALS:
Foos: Optional[Foos]=None
class Foos:
On 2022-10-29 23:59:44 +0100, Paulo da Silva wrote:
Às 22:34 de 29/10/22, dn escreveu:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Solution (below) will not work if the mention of Foos in GLOBALS is a
forward-reference.
Either move GLOBALS to suit, or surround "Foos" with quotes.
This is the problem for me.
Quotes are a bit ugly, but why are they a problem?
[...]
The funny thing is that if I replace foos by Foos it works because it gets >> known by the initial initialization :-) ![...]
________________________
from typing import List, Optional
class GLOBALS:
Foos: Optional[Foos]=None
class Foos:
That seems like a bug to me. What is the «Foos» in «Optional[Foos]» referring to?
If it's the class attribute «Foos» then that's not a type and even if
its type is inferred that's not the same as «Optional[it's type]», or is it?
If it's referring to the global symbol «Foos» (i.e. the class defined later) that hasn't been defined yet, so it shouldn't work (or
alternatively, if forward references are allowed it should always work).
On 10/30/2022 6:26 AM, Peter J. Holzer wrote:
On 2022-10-29 23:59:44 +0100, Paulo da Silva wrote:
The funny thing is that if I replace foos by Foos it works because it gets
known by the initial initialization :-) !
________________________
from typing import List, Optional
class GLOBALS:[...]
Foos: Optional[Foos]=None
class Foos:
That seems like a bug to me. What is the «Foos» in «Optional[Foos]» referring to?
If it's the class attribute «Foos» then that's not a type and even if
its type is inferred that's not the same as «Optional[it's type]», or is it?
If it's referring to the global symbol «Foos» (i.e. the class defined later) that hasn't been defined yet, so it shouldn't work (or alternatively, if forward references are allowed it should always work).
Quoting a forward-referenced type is the way to use one. Unquoted types
need to have been declared already.
Is there anything to do without loosing my script structure and usual >practice?
On 2022-10-29 23:59:44 +0100, Paulo da Silva wrote:
Às 22:34 de 29/10/22, dn escreveu:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Solution (below) will not work if the mention of Foos in GLOBALS is a
forward-reference.
Either move GLOBALS to suit, or surround "Foos" with quotes.
This is the problem for me.
Quotes are a bit ugly, but why are they a problem?
[...]
The funny thing is that if I replace foos by Foos it works because it gets >> known by the initial initialization :-) ![...]
________________________
from typing import List, Optional
class GLOBALS:
Foos: Optional[Foos]=None
class Foos:
That seems like a bug to me. What is the «Foos» in «Optional[Foos]» referring to?
If it's the class attribute «Foos» then that's not a type and even if
its type is inferred that's not the same as «Optional[it's type]», or is it?
If it's referring to the global symbol «Foos» (i.e. the class defined later) that hasn't been defined yet, so it shouldn't work (or
alternatively, if forward references are allowed it should always work).
Out of interest, tested snippet in PyCharm, cf native-mypy. It flags the original:
   GLOBALS.foos: Optional[Foos]=Foos()
but not the fall-back:
   GLOBALS.foos=Foos()
Must admit, the first query coming to mind was: why is the typing taking place at initialisation-time, rather than within the (class) definition?
At definition time "foos" has already been typed as None by implication!
Solution (below) will not work if the mention of Foos in GLOBALS is a forward-reference. Either move GLOBALS to suit, or surround "Foos" with quotes.Somehow I missed this sentence the 1st. time I read this post :-(
Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
Is there anything to do without loosing my script structure and usual
practice?
to lose (losing): to stop having something
to loose (loosing): to let or make loose (see next line)
loose (adj.): not firmly attached/tied/fastened/controlled
to loosen: similar to "to loose"
On 2022-10-30 09:23:27 -0400, Thomas Passin wrote:
On 10/30/2022 6:26 AM, Peter J. Holzer wrote:
On 2022-10-29 23:59:44 +0100, Paulo da Silva wrote:
The funny thing is that if I replace foos by Foos it works because it gets >>>> known by the initial initialization :-) ![...]
________________________
from typing import List, Optional
class GLOBALS:
Foos: Optional[Foos]=None
class Foos:
That seems like a bug to me. What is the «Foos» in «Optional[Foos]»
referring to?
If it's the class attribute «Foos» then that's not a type and even if
its type is inferred that's not the same as «Optional[it's type]», or is >>> it?
If it's referring to the global symbol «Foos» (i.e. the class defined
later) that hasn't been defined yet, so it shouldn't work (or
alternatively, if forward references are allowed it should always work).
Quoting a forward-referenced type is the way to use one. Unquoted types
need to have been declared already.
Yes. I was referring to the code as written. Why does that work? I don't think it should.
Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
Is there anything to do without loosing my script structure and usual
practice?
to lose (losing): to stop having something
to loose (loosing): to let or make loose (see next line)
loose (adj.): not firmly attached/tied/fastened/controlled
to loosen: similar to "to loose"
On 31/10/2022 06.06, Stefan Ram wrote:
Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
Is there anything to do without loosing my script structure and usual
practice?
to lose (losing): to stop having something
to loose (loosing): to let or make loose (see next line)
loose (adj.): not firmly attached/tied/fastened/controlled
to loosen: similar to "to loose"
Hay, your write*!
Well done. There's many a native-speaker who doesn't know the
distinction, or doesn't care about accuracy.
Às 02:32 de 30/10/22, dn escreveu:
On 30/10/2022 11.59, Paulo da Silva wrote:Thank you.
Solution (below) will not work if the mention of Foos in GLOBALS isThis is the problem for me. So far, without typing, I used to have
a forward-reference. Either move GLOBALS to suit, or surround "Foos"
with quotes.
some config and globals classes, mostly to just group definitions an
make the program more readable. A matter of taste and style.
Agreed, a good practice.
The main idea is to eventually catch some, otherwise "hidden", errors
Now, "typing" is breaking this, mostly because of this forward
reference issue.
As a first step, use the quotation-marks to indicate that such will be
defined later in the code:-
class GLOBALS:
   Foos: Optional[Foos]=None
class GLOBALS:
    Foos: Optional["Foos"]=None
Later, as gather (typing) expertise, can become more sophisticated,
as-and-when...
The funny thing is that if I replace foos by Foos it works because it
gets known by the initial initialization :-) !
Is the objective to write (good) code, or merely to satisfy the
type-checker?
Something that is misleading is not going to be appreciated by others
(including the +6-months you), eg
a = a + 1Â Â # decrement total
Typing is not compulsory, and has been designed so that we can
implement it a bit at a time, eg only one function amongst many
contained by a module - if that's the only code that requires
maintenance/update.
Best not to create "technical debt" though!
and produce better and cleaner code. Documentation is also a must.
On Mon, 31 Oct 2022 at 09:39, dn <PythonList@danceswithmice.info> wrote:
On 31/10/2022 06.06, Stefan Ram wrote:
Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
Is there anything to do without loosing my script structure and usual
practice?
to lose (losing): to stop having something
to loose (loosing): to let or make loose (see next line)
loose (adj.): not firmly attached/tied/fastened/controlled
to loosen: similar to "to loose"
Hay, your write*!
Well done. There's many a native-speaker who doesn't know the
distinction, or doesn't care about accuracy.
I'm curious to what extent sloppy English correlates with sloppy code.
Do people care about learning proper Python but not about proper
English, or do they think there's no such thing as proper English just because there's no English Steering Council?
A lot of people seem to treat English the way web browsers treat HTML
- as long as you can make some sense out of it, it's good enough. Some
nerds treat English the way the W3C treats HTML - there actually is a standard and everything has defined rules. I know which camp I prefer
to communicate with.
* which may say something unfortunate about my coding/design, or may
simply show that SODD (Stack Overflow Driven Development - or the GitHub >equivalent) leaves much to be desired. Hence the gold-plated advice:
never copy-paste code without understanding it first!
On 31/10/2022 11.44, Chris Angelico wrote:...
...I'm curious to what extent sloppy English correlates with sloppy code.
When it comes to CVs/resumés (see what I did there?), I must admit that
the most egregious of errors in spelling or grammar do ensure that an >applicant's 'work' is quickly routed to "file 13" (an American-English
term, many other English-speakers will not have heard previously).
dn <PythonList@DancesWithMice.info> writes:
On 31/10/2022 11.44, Chris Angelico wrote:...
...I'm curious to what extent sloppy English correlates with sloppy code.
When it comes to CVs/resumés (see what I did there?), I must admit that
the most egregious of errors in spelling or grammar do ensure that an
applicant's 'work' is quickly routed to "file 13" (an American-English
term, many other English-speakers will not have heard previously).
This discussion reminds me of something Eric Raymond said:
|While sloppy writing does not invariably mean sloppy thinking,
|we've generally found the correlation to be strong -- and we
|have no use for sloppy thinkers. If you can't yet write
|competently, learn to.
Eric Raymond
. Other relevant quotations are:
|Besides a mathematical inclination, an exceptionally good
|mastery of one's native tongue is the most vital asset of a
|competent programmer.
Edsgar Dijkstra
|I've found that some of the best [Software ]developers
|of all are English majors. They'll often graduate with
|no programming experience at all, and certainly without
|a clue about the difference between DRAM and EPROM.
|
|But they can write. That's the art of conveying
|information concisely and clearly. Software development
|and writing are both the art of knowing what you're going
|to do, and then lucidly expressing your ideas.
|
Jack Ganssle
|The narrative measures of conjunction use, event
|content, perspective shift, and mental state reference
|were significantly predictive of later Math scores.
"Evidence of a Relation between Early Narrative and ..." (2004)
- DK O’Neill
|I have never, ever, ever seen a great software developer
|who does not have amazing attention to detail.
(2006-08-20) - Rob Walling
On 2022-10-29 23:59:44 +0100, Paulo da Silva wrote:
The funny thing is that if I replace foos by Foos it works because it gets known by the initial initialization :-) !
________________________
from typing import List, Optional
class GLOBALS:[...]
Foos: Optional[Foos]=None
class Foos:
That seems like a bug to me.
On 30/10/2022 14:37, Peter J. Holzer wrote:[...]
On 2022-10-30 09:23:27 -0400, Thomas Passin wrote:
On 10/30/2022 6:26 AM, Peter J. Holzer wrote:
On 2022-10-29 23:59:44 +0100, Paulo da Silva wrote:
The funny thing is that if I replace foos by Foos it works because it gets
known by the initial initialization :-) !
Yes. I was referring to the code as written. Why does that work? I don't think it should.
For me it makes sense. I think mypy should refrain from trying to figure
out order of execution.
On 2022-10-30 11:26:56 +0100, Peter J. Holzer wrote:
On 2022-10-29 23:59:44 +0100, Paulo da Silva wrote:
The funny thing is that if I replace foos by Foos it works because it gets >>> known by the initial initialization :-) ![...]
________________________
from typing import List, Optional
class GLOBALS:
Foos: Optional[Foos]=None
class Foos:
That seems like a bug to me.
But is it even true?
I just tried to reproduce it (should have done that before answering)
with mypy 0.942 (included in Ubuntu 22.04 LTS):
----[p1]---------------------------------------------------------------
from typing import List, Optional
class GLOBALS:
foos: Optional[Foos]=None
class Foo:
def __init__(self):
pass
class Foos:
Foos: List[Foo]=[]
# SOME GLOBALS ARE USED HERE
def __init__(self):
pass
GLOBALS.foos=Foos() -----------------------------------------------------------------------
----[p2]---------------------------------------------------------------
from typing import List, Optional
class GLOBALS:
Foos: Optional[Foos]=None
class Foo:
def __init__(self):
pass
class Foos:
Foos: List[Foo]=[]
# SOME GLOBALS ARE USED HERE
def __init__(self):
pass
GLOBALS.Foos=Foos() -----------------------------------------------------------------------
--- p1 2022-10-31 21:59:49.639869922 +0100
+++ p2 2022-10-31 21:58:19.815830677 +0100
@@ -1,7 +1,7 @@
from typing import List, Optional
class GLOBALS:
- foos: Optional[Foos]=None
+ Foos: Optional[Foos]=None
class Foo:
@@ -15,4 +15,4 @@
def __init__(self):
pass
-GLOBALS.foos=Foos()
+GLOBALS.Foos=Foos()
So the only difference is the capitalization of foos. And mypy accepts
both (as it probably should):
% mypy p1
Success: no issues found in 1 source file
% mypy p2
Success: no issues found in 1 source file
If you did something different, please explain what you did.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 79:04:14 |
Calls: | 6,716 |
Files: | 12,247 |
Messages: | 5,357,909 |