Re: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers?

2017-08-07 Thread Thomas Güttler



Am 05.08.2017 um 06:14 schrieb Ben Finney:

Thomas Güttler  writes:


The underlaying question is: Imangine you are a newcomer.


A newcomer is in a tough position when it comes to packaging and
distributing Python code, especially the command-line programs.

There has been significant progress on this in recent years. The
Setuptools third-party library is a lot saner, the inclusion of ‘pip’ in
standard installs makes it much broader in scope.

But *not* in the standard library today, it's true.


You need a guide like 'if unsure do x'. With other words: What is the
sane default choice?


There isn't a good answer to that question, today.

The best answer today is: Read the guides from the Python Packaging
Authority, and stay abreast of developments because this continues to
change.

Maybe eventually the ongoing work of the PyPA will be settled enough
that it can update the standard library Distutils. But not today.



You say that there isn't a good answer to that question, today.

For me the question was: setup.py "script" vs "console_scripts" ?

I found this: 
https://packaging.python.org/tutorials/distributing-packages/#console-scripts

You say that there isn't a good answer to that question, today.

I can't follow.

Why is "the sane default is 'use console_scripts entry-point in setup.py'" not 
a good answer?

Regards,
  Thomas Güttler



--
Thomas Guettler http://www.thomas-guettler.de/
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod?

2017-08-07 Thread Steven D'Aprano
On Sun, Aug 06, 2017 at 06:35:10PM -0500, boB Stepp wrote:

> py3: class MyClass:
> ... def my_method():
> ... print('This is my_method in MyClass!')
> ...
> py3: class MyOtherClass:
> ... @staticmethod
> ... def my_other_method():
> ... print('This is my_other_method in MyOtherClass!')
> ...
> py3: MyClass.my_method()
> This is my_method in MyClass!
> py3: MyOtherClass.my_other_method()
> This is my_other_method in MyOtherClass!

A small comment: since the methods have different names, there's no 
reason why they couldn't both be in the same class. 

It is hard to see the distinction between an ordinary method and a 
static method from this example. What you are seeing is, by accident, 
the equivalent of just writing:

def my_method():
print('This is my_method in MyClass!')

outside of the class and calling the bare function. Notice that despite 
the name, my_method is not *actually* usable as a method. It has no 
"self" parameter.


> I see no difference in result, whether I use the @staticmethod decorator or 
> not.

Indeed you would not, because you are calling MyClass.my_method, 
directly from the class object. If you created an instance first, and 
then called the methods, you would see a big difference!

obj = MyClass()
obj.my_method()  # fails with TypeError, as there is no "self" parameter

while the staticmethod would succeed.

So what's going on here?

When you call MyClass.my_method, Python looks up my_method on the class 
object, equivalent to:

thing = getattr(MyClass, 'my_method')

before calling thing(), which then prints the message.

This is where is gets complex... Python performs some special magic when 
you look up attributes, according to "the descriptor protocol". Don't 
worry about how it works -- think of it as black magic for now. But the 
bottom line is, if the look up returns something like a string or an int 
or a list, no descriptor magic happens, but if it returns a function 
(something you created with "def"), something not far removed from this 
happens:

# (instance) method descriptor
if thing is a function:
if the source was a class # like "MyClass.method":
# This was different in Python 2.
return thing, unchanged
else:  # source was an instance, "MyClass().method"
wrap thing in a method object that receives "self"
return the method object

Why does it bother? Because that way Python can automatically fill in 
the instance as "self".

Example: today we write:

s = "Hello world!"
t = s.upper()

But without this method magic, or something similar, we would have to 
write:

s = "Hello world!"
t = str.upper(s)  # need to manually provide "self"

or even:

s = "Hello world!"
t = s.upper(s)

in order for the upper() method to receive the instance s as the "self" 
parameter.

Despite the name, your example "my_method" isn't a method and doesn't 
require "self". If you try to pass one in, you get a TypeError because 
the function doesn't take any arguments at all. But normally methods 
need to know what instance they are working on, in other words, they 
need to know "self".

So when you call MyClass.my_method, calling from the class, Python just 
gives you the raw function object, unchanged. Normally that means you 
would need to provide "self" yourself. This is called an "unbound 
method", it's unbound because it doesn't know what instance to work on.

Example:

str.upper

is the equivalent of an unbound method. It is incomplete, because it 
doesn't know what string to uppercase. You have to provide one for it to 
work on:

str.upper("spam")

But if you call directly from an instance, Python knows what string to 
use as "self", and you don't need to do any more:

"spam".upper()


Unbound methods have their uses. In Python 2, they were actual custom 
method objects, but in Python 3 it was decided that this was pointless 
and instead the bare function is returned instead. But conceptually, the 
base function is an unbound method.

So normal methods convert a function to a method which automatically 
provides "self", but only if called from the instance (self). Otherwise 
they return the function, which needs you to manually provide self.

In your example, by accident (I assume?) you forgot to include "self", 
so the fact that no self was provided didn't stop the function from 
working.

Now, how about class methods? Class methods are just like ordinary 
(instance) methods, except instead of "self", they receive the class 
object as first parameter. There aren't many good examples of class 
methods, and so they aren't common. But here's one:

dict.fromkeys

Most dict methods (update, pop, popitem, clear, etc.) need to know which 
specific dict to work on. But fromkeys is different: it does not care 
what instance you use. Both of these will work exactly the same:

{}.fromkeys(['one', 'two', 'three'])
{100: 'A', 200: 'B'

Re: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod?

2017-08-07 Thread boB Stepp
I feel like I have gazed into a crystal clear pool, apparently
shallow, with many interesting objects (Pun intended!) on the pool
floor.  Interested in these beautiful things, I jump in to grab one
for close-up study only to find that the pool is much, ... , much
deeper (> 1 boB-height) than it appeared.  And alas!  I don't know how
to swim!

On Mon, Aug 7, 2017 at 8:36 AM, Steven D'Aprano  wrote:
> On Sun, Aug 06, 2017 at 06:35:10PM -0500, boB Stepp wrote:
>
>> py3: class MyClass:
>> ... def my_method():
>> ... print('This is my_method in MyClass!')
>> ...
>> py3: class MyOtherClass:
>> ... @staticmethod
>> ... def my_other_method():
>> ... print('This is my_other_method in MyOtherClass!')
>> ...
>> py3: MyClass.my_method()
>> This is my_method in MyClass!
>> py3: MyOtherClass.my_other_method()
>> This is my_other_method in MyOtherClass!
>
> A small comment: since the methods have different names, there's no
> reason why they couldn't both be in the same class.

As I did not know exactly where I was going with these exploratory
examples, I thought I would keep things separated in case something
surprising developed.  Then I could easily compare the two.

> It is hard to see the distinction between an ordinary method and a
> static method from this example. What you are seeing is, by accident,
> the equivalent of just writing:
>
> def my_method():
> print('This is my_method in MyClass!')
>
> outside of the class and calling the bare function. Notice that despite
> the name, my_method is not *actually* usable as a method. It has no
> "self" parameter.

I thought that was the whole essence of static methods -- no self parameter.

>
>> I see no difference in result, whether I use the @staticmethod decorator or 
>> not.
>
> Indeed you would not, because you are calling MyClass.my_method,
> directly from the class object. If you created an instance first, and
> then called the methods, you would see a big difference!

Alan pointed out I might want to investigate this.  I did and got what
you show below.

> obj = MyClass()
> obj.my_method()  # fails with TypeError, as there is no "self" parameter
>
> while the staticmethod would succeed.
>
> So what's going on here?
>
> When you call MyClass.my_method, Python looks up my_method on the class
> object, equivalent to:
>
> thing = getattr(MyClass, 'my_method')
>
> before calling thing(), which then prints the message.
>
> This is where is gets complex... Python performs some special magic when
> you look up attributes, according to "the descriptor protocol". Don't
> worry about how it works -- think of it as black magic for now. But the
> bottom line is, if the look up returns something like a string or an int
> or a list, no descriptor magic happens, but if it returns a function
> (something you created with "def"), something not far removed from this
> happens:
>
> # (instance) method descriptor
> if thing is a function:
> if the source was a class # like "MyClass.method":
> # This was different in Python 2.
> return thing, unchanged
> else:  # source was an instance, "MyClass().method"
> wrap thing in a method object that receives "self"
> return the method object
>
> Why does it bother? Because that way Python can automatically fill in
> the instance as "self".

[snip]

>
> Despite the name, your example "my_method" isn't a method and doesn't
> require "self". If you try to pass one in, you get a TypeError because
> the function doesn't take any arguments at all. But normally methods
> need to know what instance they are working on, in other words, they
> need to know "self".

Question(s):  While something like "my_method" can't be called from an
object instance, it can be called on the class.  Are there use cases
where this behavior is actually desired?  If wrapped with
"@staticmethod" then there are two ways of calling the method, using
objects or using the class.  Is there some reason not to use the
"ClassName.a_static_method()" syntax?  Are there intended uses for
doing this?

> So when you call MyClass.my_method, calling from the class, Python just
> gives you the raw function object, unchanged. Normally that means you
> would need to provide "self" yourself. This is called an "unbound
> method", it's unbound because it doesn't know what instance to work on.

[snip]

> Unbound methods have their uses. In Python 2, they were actual custom
> method objects, but in Python 3 it was decided that this was pointless
> and instead the bare function is returned instead. But conceptually, the
> base function is an unbound method.
>
> So normal methods convert a function to a method which automatically
> provides "self", but only if called from the instance (self). Otherwise
> they return the function, which needs you to manually provide self.
>
> In your example, by accident (I assume?) ...

No, on purpose.  I was just playing around to see what would o

Re: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers?

2017-08-07 Thread Ben Finney
Thomas Güttler  writes:

> Why is "the sane default is 'use console_scripts entry-point in
> setup.py'" not a good answer?

Because third-party Setuptools is required for entry points, which means
entry points cannot be a default choice.

It may well be a good choice for many cases. But that's a different
matter from it being a good *default* choice; it can only be a default
choice if it's in the standard library.

-- 
 \   “The best in us does not require the worst in us: Our love of |
  `\ other human beings does not need to be nurtured by delusion.” |
_o__) —Sam Harris, at _Beyond Belief 2006_ |
Ben Finney

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] How does len() compute length of a string in UTF-8, 16, and 32?

2017-08-07 Thread boB Stepp
py3: s = 'Hello!'
py3: len(s.encode("UTF-8"))
6
py3: len(s.encode("UTF-16"))
14
py3: len(s.encode("UTF-32"))
28

How is len() getting these values?  And I am sure it will turn out not
to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28.  Hmm
...

-- 
boB
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32?

2017-08-07 Thread Ben Finney
boB Stepp  writes:

> How is len() getting these values?

By asking the objects themselves to report their length. You are
creating different objects with different content::

>>> s = 'Hello!'
>>> s_utf8 = s.encode("UTF-8")
>>> s == s_utf8
False
>>> s_utf16 = s.encode("UTF-16")
>>> s == s_utf16
False
>>> s_utf32 = s.encode("UTF-32")
>>> s == s_utf32
False

So it shouldn't be surprising that, with different content, they will
have different length::

>>> type(s), len(s)
(, 6)
>>> type(s_utf8), len(s_utf8)
(, 6)
>>> type(s_utf16), len(s_utf16)
(, 14)
>>> type(s_utf32), len(s_utf32)
(, 28)

What is it you think ‘str.encode’ does?

-- 
 \  “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

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32?

2017-08-07 Thread Zachary Ware
On Mon, Aug 7, 2017 at 9:44 PM, boB Stepp  wrote:
> py3: s = 'Hello!'
> py3: len(s.encode("UTF-8"))
> 6
> py3: len(s.encode("UTF-16"))
> 14
> py3: len(s.encode("UTF-32"))
> 28
>
> How is len() getting these values?  And I am sure it will turn out not
> to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28.  Hmm

First, make sure you know exactly what is having its length checked.
In each of those cases, you're not checking the length of the string,
`s`, you're checking the length of the string `s` encoded in various
encodings (try each of those lines without the 'len' part).

Next, take a dive into the wonderful* world of Unicode:

https://nedbatchelder.com/text/unipain.html
https://www.youtube.com/watch?v=7m5JA3XaZ4k

Hope this helps,
-- 
Zach
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32?

2017-08-07 Thread Cameron Simpson

On 07Aug2017 21:44, boB Stepp  wrote:

py3: s = 'Hello!'
py3: len(s.encode("UTF-8"))
6
py3: len(s.encode("UTF-16"))
14
py3: len(s.encode("UTF-32"))
28

How is len() getting these values?  And I am sure it will turn out not
to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28.  Hmm


The result of str.encode is a bytes object with the specified encoding of the 
original text.


Your sample string contains only ASCII characters, which encode 1-to-1 in 
UTF-8. So as you might expect, your UTF-8 encoding is 6 bytes. The others have 
a slight twist. Let's see:


   Python 3.6.1 (default, Apr 24 2017, 06:17:09)
   [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
   Type "help", "copyright", "credits" or "license" for more information.
   >>> s = 'Hello!'
   >>> s.encode()
   b'Hello!'
   >>> s.encode('utf-16')
   b'\xff\xfeH\x00e\x00l\x00l\x00o\x00!\x00'
   >>> s.encode('utf-32')
   
b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00!\x00\x00\x00'

The utf-8 encoding (the default) is as you would expect.

The UTF-16 and UTF-32 encodings encode code points into 2 and 4 byte sequences 
as you might expect. Unlike the UTF-8 encoding, however, it is necessary to to 
know whether these byte sequences are big-endian (most significant byte first) 
or little-endian (least significant byte first).


The machine I'm on here is writing big endian UTF-16 and UTF-32.

As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This is 
because each encoding has a leading byte order marker to indicate the big 
endianness or little endianness. For big endian data that is \xff\xfe; for 
little endian data it would be \xfe\xff.


Cheers,
Cameron Simpson  (formerly c...@zip.com.au)
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32?

2017-08-07 Thread eryk sun
On Tue, Aug 8, 2017 at 3:20 AM, Cameron Simpson  wrote:
>
> As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This
> is because each encoding has a leading byte order marker to indicate the big
> endianness or little endianness. For big endian data that is \xff\xfe; for
> little endian data it would be \xfe\xff.

To avoid encoding a byte order mark (BOM), use an "le" or "be" suffix, e.g.

>>> 'Hello!'.encode('utf-16le')
b'H\x00e\x00l\x00l\x00o\x00!\x00'

Sometimes a data format includes the byte order, which makes using a
BOM redundant. For example, strings in the Windows registry use
UTF-16LE, without a BOM.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor