Re: lxml namespace as an attribute

2018-08-15 Thread dieter
Skip Montanaro  writes:
> Much of XML makes no sense to me. Namespaces are one thing. If I'm
> parsing a document where namespaces are defined at the top level, then
> adding namespaces=root.nsmap works when calling the xpath method. I
> more-or-less get that.
>
> What I don't understand is how I'm supposed to search for a tag when
> the namespace appears to be defined as an attribute of the tag itself.

You seem to think that you need to take the namespace definitions
from the XML document itself. This is not the case: you can
provide them from whatever soure you want.

The important part of the namespace is the namespace uri; the namespace
prefix is just an abbreviation - its exact value is of no importance;
you can use whatever you want (and there is no need that your choice
is the same as that of the XML document).

"lxml" handles "xmlns" "attributes" differently from "normal" attributes.
"Normal" attributes are accessed via a mapping interface; "xmlns" attributes
via the "nsmap" attribute. I think (but I am not sure) that the "nsmap" 
of an element contains all namespace definitions "active" at the element,
not just those defined on the element itself. Thus, if you are able
to locate an element, you can get its relevant namespace definitions
via its "nsmap" (as you did with "root").


In my typical applications, I know the relevant namespace uris.
I define a namespace dict:

 ns = dict(
   p1=uri1,
   p2=uri2,
   ...
   )

with prefixes "p1", ... of my own choice and pass "ns"
as "namespaces" (e.g. for "xpath").


Note that the XPATH specification does not provide to search
with a local part alone for a namespace qualified element
(even if that qualification comes from the default XML namespace).
Such searches must always use a qualified (i.e. with namespace prefix)
path.

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


Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?

2018-08-15 Thread Ben Finney
David Raymond  writes:

> So what are you saying is an option vs an argument? Because I see no
> distinction whatsoever.

The command-line conventions do recognise the distinction.

* A command-line argument specifies input to the program.

  For example, the destination file for a ‘cp’ command is specified as
  the final argument to that command.

* A command-line option specifies a modifier to the program's behaviour.

  For example, the ‘--force’ option for a ‘cp’ command modifies the
  behaviour to remove the destination file if it already exists.

> When you run something you give it a bunch of strings.

Sure, command-line arguments and options are specified as strings. That
doesn't erase the distinction; it just means there is a category they
both belong to.

> That's it.

You can claim to not see the distinction, but that's athwart existing
convention, and you'll need to accept that there *is* such a distinction
in the specification of a great many programs.

> There is nothing magical about putting a dash in front of a letter,

Convention is not magical, true. Specifying options with a leading
hyphen is arbitrary.

That doesn't make it meaningless; the convention exists and is very
normal.

https://en.wikipedia.org/wiki/Command-line_interface#Arguments>

-- 
 \  “In the long run, the utility of all non-Free software |
  `\  approaches zero. All non-Free software is a dead end.” —Mark |
_o__)Pilgrim, 2006 |
Ben Finney

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


Re: lxml namespace as an attribute

2018-08-15 Thread Skip Montanaro
> See https://lxml.de/tutorial.html#namespaces and
> https://lxml.de/2.1/FAQ.html#how-can-i-specify-a-default-namespace-for-xpath-expressions
> for direction.

I had read at least the namespaces section of the tutorial. I could
see the namespace definition right there in the XML and figured
somehow, some way, it must be fully self-describing. I guess not.

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


RE: lxml namespace as an attribute

2018-08-15 Thread Joseph L. Casale
-Original Message-
From: Python-list  On Behalf Of Skip
Montanaro
Sent: Wednesday, August 15, 2018 3:26 PM
To: Python 
Subject: lxml namespace as an attribute
 
> Much of XML makes no sense to me. Namespaces are one thing. If I'm
> parsing a document where namespaces are defined at the top level, then
> adding namespaces=root.nsmap works when calling the xpath method. I
> more-or-less get that.
> 
> What I don't understand is how I'm supposed to search for a tag when
> the namespace appears to be defined as an attribute of the tag itself.
> I have some SOAP XML I'm trying to parse. It looks roughly like this:
> 
> 
>   
>  ...
>   
>   
> http://some/new/path";>
> ...
> 
>   
> 
> If the document is "doc", I can find the body like so:
> 
> body = doc.xpath(".//Body" namespaces=doc.nsmap)
> 
> I don't understand how to find Tag, however. When I iterate over the
> body's children, printing them out, I see that Tag's name is actually:
> 
> {http://some/new/path}Tag
> 
> yet that namespace is unknown to me until I find Tag. It seems I'm
> stuck in a chicken-and-egg situation. Without knowing that
> http://some/new/path namespace, is there a way to cleanly find all
> instances of Tag?

See https://lxml.de/tutorial.html#namespaces and
https://lxml.de/2.1/FAQ.html#how-can-i-specify-a-default-namespace-for-xpath-expressions
for direction. I don't have Python at my current location but I trust that will 
point you straight.

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


Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?

2018-08-15 Thread Malcolm Greene
Thanks to everyone who contributed to this thread. Great feedback and 
suggestions! - Malcolm
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?

2018-08-15 Thread Chris Angelico
On Thu, Aug 16, 2018 at 8:51 AM, Cameron Simpson  wrote:
> And as an additional alternative, when I want something weird (extra python
> args or the like) I usually make my script.py into a module and invoke it
> via a shell script, eg:
>
>  #!/bin/sh
>  exec /particular/python python-opts... -m script_module ${1+"$@"}
>
> Obviously that'd need a little adaption under Windows.

Since an executable file without a shebang should normally be invoked
through /bin/sh, you can actually combine this technique into the
script itself with a cool hack:


exec /usr/local/bin/python3 -x -W error $0 "$@"
"""
This is an example script.

It is executable and will invoke itself through Python.
"""
import warnings
warnings.warn("This should be an error.")
print("This shouldn't happen.")


The "-x" parameter means "skip the first line", and in a sense, the
exec line is a non-standard shebang. :)

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


Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?

2018-08-15 Thread Cameron Simpson

On 15Aug2018 20:54, eryk sun  wrote:

On Wed, Aug 15, 2018 at 9:22 AM, Thomas Jollans  wrote:

If you really want to, you can pass a *single* argument in your #! line,
e.g.:

#!/usr/bin/python3 -Wd


This works for options that can be grouped into a single argument.
Multiple -X options aren't supported, nor is combining a -X option
with other options.

Using a shebang also works in Windows if .py files are associated with
the py.exe launcher, which can handle multiple arguments in the
shebang instead of just one.


And as an additional alternative, when I want something weird (extra python 
args or the like) I usually make my script.py into a module and invoke it via a 
shell script, eg:


 #!/bin/sh
 exec /particular/python python-opts... -m script_module ${1+"$@"}

Obviously that'd need a little adaption under Windows.

This has a few advantages:

 - you can use several python-opts

 - your script, unless very trivial, will usually have some reusable pieces; 
   by making it a module with a main() function you can make those pieces 
   available for _other_ modules to import and use!


Making your script a module may seem like some extra effort to little benefit, 
but after you've done it a few times it is easy and I at least now have a suite 
of little modules whose components get reused all the time.


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


Re: how to make super() work with externally defined methods in inheritance???

2018-08-15 Thread Paint-It-Black via Python-list
> ChrisA

Yes, that works.  Thank you all for your help.  -->


class A:
  def __init__(self):
self.number = 1

def A_biginc(self):
  self.number += 107

A.biginc = A_biginc

class B(A):
  def __init__(self):
super().__init__()
print("making a B")

def B_biginc(self):
  super(B,self).biginc() # super() trips up
  super(B,self).biginc()
  return self.number

B.biginc = B_biginc

def f_ut_oh():
   a = A()
   flag1 = a.number == 1
   a.biginc()
   flag2 = a.number == 108

   b = B()
   flag3 = b.number == 1
   b.biginc() 
   flag4 = b.number == 215

   if flag1 and flag2 and flag3 and flag4 :
 print("all good!") 
   else:
 print("hmm something went wrong..")

print("loaded try_adding_method.py")

>

Python 3.6.6 (default, Jun 27 2018, 14:44:17) 
[GCC 8.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> python.el: native completion setup loaded
>>> loaded try_adding_method.py
>>> f_ut_oh()
making a B
all good!
>>> 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: lxml namespace as an attribute

2018-08-15 Thread Skip Montanaro
Ack. Of course I meant the subject to be "XML namespace as an
attribute". I happen to be using lxml.etree. (Long day, I guess...)

S
On Wed, Aug 15, 2018 at 4:25 PM Skip Montanaro  wrote:
>
> Much of XML makes no sense to me. Namespaces are one thing. If I'm
> parsing a document where namespaces are defined at the top level, then
> adding namespaces=root.nsmap works when calling the xpath method. I
> more-or-less get that.
>
> What I don't understand is how I'm supposed to search for a tag when
> the namespace appears to be defined as an attribute of the tag itself.
> I have some SOAP XML I'm trying to parse. It looks roughly like this:
>
> 
>   
>  ...
>   
>   
> http://some/new/path";>
> ...
> 
>   
>
> If the document is "doc", I can find the body like so:
>
> body = doc.xpath(".//Body" namespaces=doc.nsmap)
>
> I don't understand how to find Tag, however. When I iterate over the
> body's children, printing them out, I see that Tag's name is actually:
>
> {http://some/new/path}Tag
>
> yet that namespace is unknown to me until I find Tag. It seems I'm
> stuck in a chicken-and-egg situation. Without knowing that
> http://some/new/path namespace, is there a way to cleanly find all
> instances of Tag?
>
> Thx,
>
> Skip
-- 
https://mail.python.org/mailman/listinfo/python-list


lxml namespace as an attribute

2018-08-15 Thread Skip Montanaro
Much of XML makes no sense to me. Namespaces are one thing. If I'm
parsing a document where namespaces are defined at the top level, then
adding namespaces=root.nsmap works when calling the xpath method. I
more-or-less get that.

What I don't understand is how I'm supposed to search for a tag when
the namespace appears to be defined as an attribute of the tag itself.
I have some SOAP XML I'm trying to parse. It looks roughly like this:


  
 ...
  
  
http://some/new/path";>
...

  

If the document is "doc", I can find the body like so:

body = doc.xpath(".//Body" namespaces=doc.nsmap)

I don't understand how to find Tag, however. When I iterate over the
body's children, printing them out, I see that Tag's name is actually:

{http://some/new/path}Tag

yet that namespace is unknown to me until I find Tag. It seems I'm
stuck in a chicken-and-egg situation. Without knowing that
http://some/new/path namespace, is there a way to cleanly find all
instances of Tag?

Thx,

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


Re: how to make super() work with externally defined methods in inheritance???

2018-08-15 Thread Chris Angelico
On Thu, Aug 16, 2018 at 6:00 AM, thomas.lynch--- via Python-list
 wrote:
> Appreciate some help in how in Python a person can add some external methods 
> to existing classes in the presence of simple one level inheritance.  Here is 
> an example stripped down to the shiny brass tacks:
>
> class A:
>   def __init__(self):
> self.number = 1
>
> def A_biginc(self):
>   self.number += 100
>
> A.biginc = A_biginc
> #setattr(A, 'biginc', A_biginc)
>
> class B(A):
>   def __init__(self):
> super().__init__()
> print("making a B")
>
> def B_biginc(self):
>   super().biginc() # super() trips up
>   super().biginc()
>   return self.number
>
> B.biginc = B_biginc
> #setattr(B, 'biginc', B_biginc)
>

The no-arg form of super() is a bit magical, and depends on being
compiled inside a class definition. You can use the regular form of
the function instead:

super(B, self)

On Thu, Aug 16, 2018 at 6:17 AM, Calvin Spealman  wrote:
> You really can't, and shouldn't. The super() helper relies on information
> that exists inside the class definition and which is not available simply
> at runtime by virtue of being attached to the class.
>
> Besides, modifying classes externally is generally considered a bad idea.
> Maybe you could accomplish this with a subclass adding this method, instead.

When used correctly, it's perfectly acceptable. It's a feature for a reason.

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


Re: how to make super() work with externally defined methods in inheritance???

2018-08-15 Thread Calvin Spealman
You really can't, and shouldn't. The super() helper relies on information
that exists inside the class definition and which is not available simply
at runtime by virtue of being attached to the class.

Besides, modifying classes externally is generally considered a bad idea.
Maybe you could accomplish this with a subclass adding this method, instead.

On Wed, Aug 15, 2018 at 4:04 PM, Paint-It-Black via Python-list <
python-list@python.org> wrote:

> > # this prints for me when I run this in 3.6
>
> excuse me, that is an extraneous comment from a cut and paste, in fact the
> example never makes it to the prints, as shown in the transcript just below
> the source code
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: how to make super() work with externally defined methods in inheritance???

2018-08-15 Thread Paint-It-Black via Python-list
> # this prints for me when I run this in 3.6 

excuse me, that is an extraneous comment from a cut and paste, in fact the 
example never makes it to the prints, as shown in the transcript just below the 
source code
-- 
https://mail.python.org/mailman/listinfo/python-list


how to make super() work with externally defined methods in inheritance???

2018-08-15 Thread thomas.lynch--- via Python-list
Appreciate some help in how in Python a person can add some external methods to 
existing classes in the presence of simple one level inheritance.  Here is an 
example stripped down to the shiny brass tacks:

class A:
  def __init__(self):
self.number = 1

def A_biginc(self):
  self.number += 100

A.biginc = A_biginc
#setattr(A, 'biginc', A_biginc)

class B(A):
  def __init__(self):
super().__init__()
print("making a B")

def B_biginc(self):
  super().biginc() # super() trips up
  super().biginc()
  return self.number

B.biginc = B_biginc
#setattr(B, 'biginc', B_biginc)

def f_ut_oh():
   a = A()
   flag1 = a.number == 1
   a.biginc()
   flag2 = a.number == 108

   b = B()
   flag3 = b.number == 1
   b.biginc() 
   flag4 = b.number == 215

   if flag1 and flag2 and flag3 and flag4 :
 print("all good!") # this prints for me when I run this in 3.6
   else:
 print("hmm something went wrong..")

print("loaded try_adding_method_decorator.py")

Python 3.6.6 (default, Jun 27 2018, 14:44:17) 
[GCC 8.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> python.el: native completion setup loaded
>>> loaded try_adding_method_decorator.py
>>> f_ut_oh()
making a B
Traceback (most recent call last):
  File "", line 1, in 
  File "/home/rt-fra/src/server-side/try_adding_method_decorator.py", line 34, 
in f_ut_oh
b.biginc() 
  File "/home/rt-fra/src/server-side/try_adding_method_decorator.py", line 19, 
in B_biginc
super().biginc() # super() trips up
RuntimeError: super(): __class__ cell not found
>>> 

<

It appears that supper() doesn't work with externally defined methods, but 
surely that can't be.  What is the incantation that makes this work?? Thanks!

(using setattr had the same results,  AA.biginc() said AA wasn't defined .. 
being a class instead of an object I guess.  Putting in another self.super() 
didn't work ..)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?

2018-08-15 Thread eryk sun
On Wed, Aug 15, 2018 at 9:22 AM, Thomas Jollans  wrote:
>
> If you really want to, you can pass a *single* argument in your #! line,
> e.g.:
>
> #!/usr/bin/python3 -Wd

This works for options that can be grouped into a single argument.
Multiple -X options aren't supported, nor is combining a -X option
with other options.

Using a shebang also works in Windows if .py files are associated with
the py.exe launcher, which can handle multiple arguments in the
shebang instead of just one.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Program to output a subset of the composite numbers

2018-08-15 Thread Peter Otten
tomusa...@gmail.com wrote:

> Thank you very much! Do you also know how I might slightly alter to
> composite numbers that are one less than twice a composite number?
> 
> 15 would be the first number
> Since 8 is composite then
> 
> 2*8=16
> 16 - 1=15 Is composite

Like

>>> def is_composite(n):
... return not is_prime(n)
... 
>>> print(list(islice((i for i in count(3, step=2) if is_composite(i) and 
is_composite((i+1)//2)), 20)))
[15, 27, 35, 39, 49, 51, 55, 63, 65, 69, 75, 77, 87, 91, 95, 99, 111, 115, 
119, 123]

?

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


Re: Program to output a subset of the composite numbers

2018-08-15 Thread tomusatov
Thank you very much! Do you also know how I might slightly alter to composite 
numbers that are one less than twice a composite number?

15 would be the first number
Since 8 is composite then

2*8=16
16 - 1=15 Is composite 
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?

2018-08-15 Thread David Raymond
So what are you saying is an option vs an argument? Because I see no 
distinction whatsoever. When you run something you give it a bunch of strings.

That's it.

There is nothing magical about putting a dash in front of a letter, nothing 
magical about putting in a string that might possibly also be a file name. The 
only things that might matter are white space and quote characters, because 
really all you're doing is giving the shell or OS a  string, and it 
decides what to run and what is the resulting (ordered) list of strings which 
it will then pass to that program.

Being able to just run "script.py" is just a convenience provided by the OS. It 
goes "ohh, after I've parsed it, that first token matches up with an existing 
file, and my records say that that extension can be opened with this python.exe 
program, so I'm just gonna run that python.exe thing and pass it the ordered 
list of everything I just got."

In this specific case, the people who wrote python.exe decided that when it 
goes through the list of strings which it was given, that that first thing that 
doesn't start with a dash is the "file name", that anything before that "file 
name" are things it will look at right now, and anything after the "file name" 
are things it will throw into sys.argv and let later execution decide what to 
do with.

Since the convenience method uses the first bit as the "file name" to determine 
which convenience program to run, and the python.exe program just tosses 
anything after the "file name" into sys.argv, then to get anything as an 
"argument" to python.exe and not the script, then you either need to run it as 
"python.exe bunch of strings to pass to python.exe", or the more difficult 
method of "muck about with the OS's convenience method to get it to do 
something magical."


-Original Message-
From: Python-list 
[mailto:python-list-bounces+david.raymond=tomtom@python.org] On Behalf Of 
Malcolm Greene
Sent: Tuesday, August 14, 2018 7:47 PM
To: python-list@python.org
Subject: Re: How to pass Python command line options (vs arguments) when 
running script directly vs via Python interpreter?

> You might try:
> from getopt import getopt
> or the (apparently newer):
> from optparse import OptionParser

Thanks Mike. My question was trying to make a distinction between Python 
options (flags that precede the script or module name) and arguments (the 
script specific values passed on the command line following the script's name).

Here's a description of the options I'm referring to:
https://docs.python.org/3/using/cmdline.html#generic-options
-- 
https://mail.python.org/mailman/listinfo/python-list
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Program to output a subset of the composite numbers

2018-08-15 Thread Peter Otten
Steven D'Aprano wrote:

> On Wed, 15 Aug 2018 05:34:06 -0700, tomusatov wrote:
> 
>> I am not terribly familiar with Python, but am currently authoring an
>> integer sequence for www.oeis.org and was wondering if anyone in the
>> community could help me with authoring a Python program that outputs,
>> "Composite numbers that are one less than a composite number."
> 
> 
> Do you have a function to test for primality? For now, I'll assume you do.
> 
> 
> def is_prime(n):
> # Returns True if n is prime, False otherwise.
> # implementation left as an exercise
> 
> 
> # 0 (and 1) are neither prime nor composite; skip them.
> # 2 and 3 are prime; start at the first composite, 4
> i = 4
> for j in range(5, 1001):
> if not is_prime(j):
> print(i)
> i = j

I think that are "any numbers that are one less than a composite number" 
while the OP wants only composite numbers that are one less than a composite 
number". In code

from itertools import count, islice

def cntaoltacn():
prev = None
for i in count(2):
if is_prime(i):
prev = None
else:
if prev is not None:
yield prev
prev = i

print(list(islice(cntaoltacn(), 20)))
# [8, 9, 14, 15, 20, 21, 24, 25, 26, 27, 32, 33, 34, 35, 38, 39, 44, 45, 48, 
49]


> 
> 
> The above will stop at 999. To go forever, use this instead:
> 
> 
> 
> from itertools import count
> i = 4
> for j in count(5):
> if not is_prime(j):
> print(i)
> i = j
> 
> 
> 
> Alternatively, if you have a function which efficiently returns primes
> one at a time, you can do this:
> 
> 
> n = 4  # start at the first composite
> for p in primes(5):  # primes starting at 5
> print(list(range(n, p-1))
> n = p + 1
> 
> 
> 
> This ought to print out lists of composites, starting with:
> 
> []
> []
> [8, 9]
> []
> [14, 15]
> 
> 
> etc. Take care though: I have not tested this code.
> 
> 
> 


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


Re: Program to output a subset of the composite numbers

2018-08-15 Thread Steven D'Aprano
On Wed, 15 Aug 2018 05:34:06 -0700, tomusatov wrote:

> I am not terribly familiar with Python, but am currently authoring an
> integer sequence for www.oeis.org and was wondering if anyone in the
> community could help me with authoring a Python program that outputs,
> "Composite numbers that are one less than a composite number."


Do you have a function to test for primality? For now, I'll assume you do.


def is_prime(n):
# Returns True if n is prime, False otherwise.
# implementation left as an exercise


# 0 (and 1) are neither prime nor composite; skip them.
# 2 and 3 are prime; start at the first composite, 4
i = 4
for j in range(5, 1001):
if not is_prime(j):
print(i)
i = j


The above will stop at 999. To go forever, use this instead:



from itertools import count
i = 4
for j in count(5):
if not is_prime(j):
print(i)
i = j



Alternatively, if you have a function which efficiently returns primes 
one at a time, you can do this:


n = 4  # start at the first composite
for p in primes(5):  # primes starting at 5
print(list(range(n, p-1))
n = p + 1



This ought to print out lists of composites, starting with:

[]
[]
[8, 9]
[]
[14, 15]


etc. Take care though: I have not tested this code.



-- 
Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson

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


Re: Program to output a subset of the composite numbers

2018-08-15 Thread Joel Goldstick
On Wed, Aug 15, 2018 at 8:36 AM  wrote:
>
> I am not terribly familiar with Python, but am currently authoring an integer 
> sequence for www.oeis.org and was wondering if anyone in the community could 
> help me with authoring a Python program that outputs, "Composite numbers that 
> are one less than a composite number."
>
> Thanks!
> Musatov
> --
> https://mail.python.org/mailman/listinfo/python-list

Since composite numbers are all the positive integers that are not
prime and not one, I believe you can find code to produce a sequence
of prime numbers, and you can subtract that sequence from the sequence
of positive integers

-- 
Joel Goldstick
http://joelgoldstick.com/blog
http://cc-baseballstats.info/stats/birthdays
-- 
https://mail.python.org/mailman/listinfo/python-list


Program to output a subset of the composite numbers

2018-08-15 Thread tomusatov
I am not terribly familiar with Python, but am currently authoring an integer 
sequence for www.oeis.org and was wondering if anyone in the community could 
help me with authoring a Python program that outputs, "Composite numbers that 
are one less than a composite number."

Thanks!
Musatov
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pylint false positives

2018-08-15 Thread Jon Ribbens
On 2018-08-15, Steven D'Aprano  wrote:
> On Tue, 14 Aug 2018 15:18:13 +, Jon Ribbens wrote:
>> On 2018-08-14, Steven D'Aprano 
>> wrote:
>>> # === process abstract methods en masse === 
>>> for name in "method_a method_b method_c method_d".split():
>>> @abstractmethod
>>> def inner(self):
>>> raise NotImplementedError
>>> inner.__name__ = name
>>> # This is okay, writing to locals works inside the class body.
>>> locals()[name] = inner
>>>
>>> del inner, name  # Clean up the class namespace.
>> 
>> You have a peculiar idea of "good style"...
>
> Yes, very peculiar. It's called "factor out common operations" and "Don't 
> Repeat Yourself" :-)
>
> In a world full of people who write:
>
> d[1] = None
> d[2] = None
> d[3] = None
> d[4] = None
>
> I prefer to write:
>
> for i in range(1, 5):
>d[i] = None
>
> Shocking, I know.

Obviously what I'm objecting to is not the presence of a loop,
it's the presence of many obscure, bodgey and/or broken features
all lumped together:

  * code running directly under the class definition
  * creating a method then changing its name with foo.__name__
  * poking things into to the class namespace with locals()
  * using @abstractmethod without metaclass=ABCMeta
  * dynamically adding @abstractmethod methods to a class

(Not to mention your code means the methods cannot have meaningful
docstrings.)

I would refuse a pull request containing code such as the above,
unless the number of methods being dynamically created was much
larger than 4, in which case I would refuse it because the design
of a class requiring huge numbers of dynamically created methods is
almost certainly fundamentally broken.

>> No - if you think about it, there's no way Pylint could possibly know
>> that the above class has methods method_a, method_b, etc. 
>
> Well, if a human reader can do it, a sufficiently advanced source-code 
> analyser could do it too... *wink*

If we get there, we won't need to do computer programming since we'll
have strong AI and we'll just say "computer, obey my wishes" :-)

> Yes, of course you are right, in practical terms I think it is extremely 
> unlikely that PyLint or any other linter is smart enough to recognise 
> that locals()[name] = inner is equivalent to setting attributes method_a 
> etc. I actually knew that... "although to be honest I'm not sure" is an 
> understated way of saying "It isn't" :-)

It's not so much the locals()[name] thing as much as that Pylint would
have to know what the computed values of `name` would be.

>> It also doesn't like the `del inner, name` because theoretically
>> neither of those names might be defined, if the loop executed zero
>> times.
>
> That's a limitation of the linter. Don't blame me if it is too stupid to 
> recognise that looping over a non-empty string literal cannot possibly 
> loop zero times :-)

Well, it's not looping over a string literal, it's looping over the
output of a method call on a string literal. You could *maybe* argue
that "literal words here".split() is sufficiently idiomatic that
Pylint should understand it, and the Pylint issues page would be an
excellent place to do so ;-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to pass Python command line options (vs arguments) when running script directly vs via Python interpreter?

2018-08-15 Thread Thomas Jollans
On 14/08/18 23:45, Malcolm Greene wrote:
> When you run a script via "python3 script.py" you can include command
> line options like -b, -B, -O, -OO, etc between the "python3" interpreter
> reference and the script.py file, eg. "python3 -b -B -O -OO script.py".
> When you create a script that is executable directly, eg. script.py with
> execution bit set on Linux or on Windows where the .py file extension is
> associated with a specific Python executable, there doesn't appear to be
> a way to pass command line options to the script. In this later case,
> how can I pass my script command line options without having these
> options confused with command line arguments?
> Thank you,
> Malcolm
> 

If you really want to, you can pass a *single* argument in your #! line,
e.g.:

#!/usr/bin/python3 -Wd
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pylint false positives

2018-08-15 Thread Steven D'Aprano
On Tue, 14 Aug 2018 15:18:13 +, Jon Ribbens wrote:

> On 2018-08-14, Steven D'Aprano 
> wrote:
>> If there really are a lot of such missing methods, I'd consider writing
>> something like this:
>>
>> class A:
>> def __init__(self, ...):
>> ...
>>
>> # === process abstract methods en masse === 
>> for name in "method_a method_b method_c method_d".split():
>> @abstractmethod
>> def inner(self):
>> raise NotImplementedError
>> inner.__name__ = name
>> # This is okay, writing to locals works inside the class body.
>> locals()[name] = inner
>>
>> del inner, name  # Clean up the class namespace.
> 
> You have a peculiar idea of "good style"...

Yes, very peculiar. It's called "factor out common operations" and "Don't 
Repeat Yourself" :-)

In a world full of people who write:

d[1] = None
d[2] = None
d[3] = None
d[4] = None

I prefer to write:

for i in range(1, 5):
   d[i] = None

Shocking, I know.

Literally my first professional programming job was working on a 
Hypercard project written by a professional programmer. (He was paid for 
it, so he was professional.) The first time I looked at his code, as a 
fresh-out-of-uni naive coder, I was surprised to read his GUI set-up 
code. By memory, it was something like this:

set the name of button 1 to "Wibble 1"
set the name of button 2 to "Wibble 2"
set the name of button 3 to "Wibble 3"
set the name of button 4 to "Wibble 4"
# and so on...
set the name of button 100 to "Wibble 100"

(using "Wibble" as a placeholder for the actual name, which I don't 
recall). The first thing I did was replace that with a loop:

for i = 1 to 100 do
set the name of button 100 to ("Wibble " & i)
end for


Hypertalk uses & for string concatenation. That one change cut startup 
time from something like 90 seconds to about 30, and a few more equally 
trivial changes got it down to about 15 seconds.

Hypertalk in 1988 was not the fastest language in the world, but it was 
fun to work with.



>> although to be honest I'm not sure if that would be enough to stop
>> PyLint from complaining.
> 
> No - if you think about it, there's no way Pylint could possibly know
> that the above class has methods method_a, method_b, etc. 

Well, if a human reader can do it, a sufficiently advanced source-code 
analyser could do it too... *wink*

Yes, of course you are right, in practical terms I think it is extremely 
unlikely that PyLint or any other linter is smart enough to recognise 
that locals()[name] = inner is equivalent to setting attributes method_a 
etc. I actually knew that... "although to be honest I'm not sure" is an 
understated way of saying "It isn't" :-)

https://en.wikipedia.org/wiki/Litotes


> It also
> doesn't like the `del inner, name` because theoretically neither of
> those names might be defined, if the loop executed zero times.

That's a limitation of the linter. Don't blame me if it is too stupid to 
recognise that looping over a non-empty string literal cannot possibly 
loop zero times :-)



-- 
Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson

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


Re: right way to use zipimport, zipimport.ZipImportError: not a Zip file

2018-08-15 Thread iMath
Not works on Windows 

>>> import sys
>>> sys.path.insert(0, 
>>> 'C:/Users/i/Downloads/you-get-0.4.1128.zip/you-get-0.4.1128/src')
  
>>> from you_get import common
  
Traceback (most recent call last):
  File "", line 1, in 
from you_get import common
ModuleNotFoundError: No module named 'you_get'
>>> 
-- 
https://mail.python.org/mailman/listinfo/python-list