[Python-Dev] Re: Comparing dict.values()

2019-07-23 Thread Terry Reedy

On 7/23/2019 8:27 PM, Steven D'Aprano wrote:

On Tue, Jul 23, 2019 at 08:59:09PM -, Kristian Klette wrote:

Hi!

During the sprints after EuroPython, I made an attempt at adding support for
comparing the results from `.values()` of two dicts.

Currently the following works as expected:

```
d = {'a': 1234}

d.keys() == d.keys()
d.items() == d.items()
```

but `d.values() == d.values()` does not return the expected
results. It always returns `False`. The symmetry is a bit off.


It seems to be doing an identity test on the "dict_values" view object
itself:

py> d = {'a': 1}
py> a = b = d.values()
py> a == b
True

which I expect is probably the default __eq__ inherited from object.
Each time you call d.values() you get a distinct object, hence the
False.

I agree that this is a little surprising.


If one has not learned the default meaning of '==' in Python.  Perhaps 
this should be given more emphasis in beginner courses.  "What does it 
mean for two object to be 'equal'?"  It is not a trivial question.



Given that they are *views* of
an underlying dict, I would expect that two views of the same dict ought
to compare equal:

assert d.values() == d.values()

So at the least, we ought to have dict.values() comparison return True
if the underlying dicts are identical. In pseudocode:

def __eq__(self, other):
 if self is other:
 # Same object implies equality.
 return True
 if isinstance(other, Dict_Values_View_Type):
  if self.owner_dict is other.owner_dict:
  # Two views into the same dict are always equal.
  return True
 return NotImplemented


I think that's the minimal behaviour that makes sense for a view.

Beyond that, we start getting complicated, and potentially expensive.
But I can suggest at least one useful invariant. If a, b are two dicts:

 a.items() == b.items()

ought to be equivalent to:

 (a.keys() == b.keys()) and (a.values() == b.values)


That implies something like this pseudo-code:


def __eq__(self, other):
 if self is other:
 # Same object implies equality.
 return True
 if isinstance(other, Dict_Values_View_Type):
  a = self.owner_dict  # dict we are taking a view of
  b = other.owner_dict
  if a is b:
  # Two views into the same dict are always equal.
  return True
  if len(a) != len(b):
  # Unequal lengths implies the values cannot be equal.
  return False
  if a.items() == b.items():
  # (key,value) pairs are equal implies values are equal.
  return True
  elif a.keys() == b.keys():
  # keys are equal but items are not equal implies
  # that the values must be different.
  return False


Makes sense, up to here.


  # Fall back on value by value comparison?
  return list(self) == list(other)


This seems wrong.  Creating two lists raises the cost and the comparison 
will depend on insertion order.



 return NotImplemented


In the bug trackers[0] and the Github PR[1], I was asked
to raise the issue on the python-dev mailing list to find
a consensus on what comparing `.values()` should do.

I'd argue that Python should compare the values as expected here,
or if we don't want to encourage that behaviour, maybe we should
consider raising an exception.


Equality tests should (almost?) never raise an exception. It should be
safe to test "are these two objects equal?" without guarding it in a
try...except block. The definition of "equal" may not always be obvious,
but it shouldn't raise unless the __eq__ method is buggy.


I strongly agree, with almost? likely omitted.  Testing before acting 
and recovering from failure after acting should be alternatives.


--
Terry Jan Reedy
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/PJVCRTTZI26VVXZLZ4NAMY35HMRJAI64/


[Python-Dev] Re: Comparing dict.values()

2019-07-23 Thread Steven D'Aprano
On Tue, Jul 23, 2019 at 08:59:09PM -, Kristian Klette wrote:
> Hi!
> 
> During the sprints after EuroPython, I made an attempt at adding support for
> comparing the results from `.values()` of two dicts.
> 
> Currently the following works as expected:
> 
> ```
> d = {'a': 1234}
> 
> d.keys() == d.keys()
> d.items() == d.items()
> ```
> 
> but `d.values() == d.values()` does not return the expected
> results. It always returns `False`. The symmetry is a bit off.

It seems to be doing an identity test on the "dict_values" view object 
itself:

py> d = {'a': 1}
py> a = b = d.values()
py> a == b
True

which I expect is probably the default __eq__ inherited from object. 
Each time you call d.values() you get a distinct object, hence the 
False.

I agree that this is a little surprising. Given that they are *views* of 
an underlying dict, I would expect that two views of the same dict ought 
to compare equal:

assert d.values() == d.values()

So at the least, we ought to have dict.values() comparison return True 
if the underlying dicts are identical. In pseudocode:

def __eq__(self, other):
if self is other:
# Same object implies equality.
return True
if isinstance(other, Dict_Values_View_Type):
 if self.owner_dict is other.owner_dict:
 # Two views into the same dict are always equal.
 return True
return NotImplemented


I think that's the minimal behaviour that makes sense for a view.

Beyond that, we start getting complicated, and potentially expensive. 
But I can suggest at least one useful invariant. If a, b are two dicts:

a.items() == b.items()

ought to be equivalent to:

(a.keys() == b.keys()) and (a.values() == b.values)


That implies something like this pseudo-code:


def __eq__(self, other):
if self is other:
# Same object implies equality.
return True
if isinstance(other, Dict_Values_View_Type):
 a = self.owner_dict  # dict we are taking a view of
 b = other.owner_dict
 if a is b:
 # Two views into the same dict are always equal.
 return True
 if len(a) != len(b):
 # Unequal lengths implies the values cannot be equal.
 return False
 if a.items() == b.items():
 # (key,value) pairs are equal implies values are equal.
 return True
 elif a.keys() == b.keys():
 # keys are equal but items are not equal implies 
 # that the values must be different.
 return False
 # Fall back on value by value comparison?
 return list(self) == list(other)
return NotImplemented



> In the bug trackers[0] and the Github PR[1], I was asked
> to raise the issue on the python-dev mailing list to find
> a consensus on what comparing `.values()` should do.
> 
> I'd argue that Python should compare the values as expected here,
> or if we don't want to encourage that behaviour, maybe we should
> consider raising an exception. 

Equality tests should (almost?) never raise an exception. It should be 
safe to test "are these two objects equal?" without guarding it in a 
try...except block. The definition of "equal" may not always be obvious, 
but it shouldn't raise unless the __eq__ method is buggy.

In Python, its quite common for __eq__ to fall back on ``is``, e.g.:

py> a = lambda x: x+1
py> a == a
True
py> a == (lambda x: x+1)
False

but I think in the case of views, we should at least fall back on 
identity of the underlying dicts, even if we decide the more complex 
tests are not worth the trouble.





-- 
Steven
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/TT3NF3TFFRERELNJ6QCHRV2NBGW6EUN5/


[Python-Dev] Re: Comparing dict.values()

2019-07-23 Thread Kyle Stanley
I find myself in agreement with Inada (https://bugs.python.org/issue12445), in 
that comparing the values view between two dictionaries by itself would not be 
particularly useful for enough people to warrant implementing the comparison. 
In most situations when using the data structure, it is only useful to either 
compare the keys and values with ``d0.items() == d1.items()`` or just the keys 
with ``d0.keys() == d1.keys()``. 

The values are generally not particularly useful without the corresponding 
keys, so I'm actually somewhat curious as to the motivation of creating the 
function ``dict.values()``. But, if for any reason someone actually had to 
compare only the values (I can't imagine the reason), they could compare them 
by converting them to a list: ``list(d0.values()) == list(d1.values())``. It 
adds an extra step, but I don't think enough people would make use of something 
like this to justify adding the direct comparison with ``d0.values() == 
d1.values())``. 

However, I agree that the current behavior of just returning ``False`` is quite 
misleading, regardless of whether or not implementing an accurate comparison 
between the values views would be worthwhile. I'm not sure as to what the most 
appropriate behavior would be, but since it's using ``__eq__``, 
[NotImplemented](https://docs.python.org/3/library/constants.html#NotImplemented)
 seems appropriate. 

Another alternative would be to return ``None``. A note in the docs for 
[NotImplementedError](https://docs.python.org/3/library/exceptions.html#NotImplementedError)
 states "It [NotImplementedError] should not be used to indicate that an 
operator or method is not meant to be supported at all – in that case either 
leave the operator / method undefined or, if a subclass, set it to None".
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/KX2TG7ZPVOWKUNDILV74YNFTBZTJHUP5/


[Python-Dev] Re: Comparing dict.values()

2019-07-23 Thread MRAB

On 2019-07-23 21:59, Kristian Klette wrote:

Hi!

During the sprints after EuroPython, I made an attempt at adding support for
comparing the results from `.values()` of two dicts.

Currently the following works as expected:

```
d = {'a': 1234}

d.keys() == d.keys()
d.items() == d.items()
```

but `d.values() == d.values()` does not return the expected
results. It always returns `False`. The symmetry is a bit off.

In the bug trackers[0] and the Github PR[1], I was asked
to raise the issue on the python-dev mailing list to find
a consensus on what comparing `.values()` should do.

I'd argue that Python should compare the values as expected here,
or if we don't want to encourage that behaviour, maybe we should
consider raising an exception.
Returning just `False` seems a bit misleading.

What are your thoughts on the issue?

Best regards,
Kristian Klette


[0]: https://bugs.python.org/issue37585
[1]: https://github.com/python/cpython/pull/14737


Well, the keys can function as a set, and, in fact, can equal a set:

>>> {'a': 1234}.keys() == {'a'}
True

so the keys of 2 dicts can be compared efficiently.

The items of 2 dicts can also be compared efficiently because you still 
have the keys, so you can check the key efficiently and then check the 
value.


However, when comparing the values you have a problem: you have 2 
collections of objects that might contain duplicates, might not be 
hashable, and might not be sortable, so comparing them could be 
inefficient, and you can't refer back to their keys like in the case of 
comparing the items as above because the 2 dicts might have different 
keys. Unless someone can come up with an efficient solution, I'd 
probably go with raising an exception.

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/SBIYA5JAB3AUVBLQDXMT4CFSYSU76CNF/


[Python-Dev] Comparing dict.values()

2019-07-23 Thread Kristian Klette
Hi!

During the sprints after EuroPython, I made an attempt at adding support for
comparing the results from `.values()` of two dicts.

Currently the following works as expected:

```
d = {'a': 1234}

d.keys() == d.keys()
d.items() == d.items()
```

but `d.values() == d.values()` does not return the expected
results. It always returns `False`. The symmetry is a bit off.

In the bug trackers[0] and the Github PR[1], I was asked
to raise the issue on the python-dev mailing list to find
a consensus on what comparing `.values()` should do.

I'd argue that Python should compare the values as expected here,
or if we don't want to encourage that behaviour, maybe we should
consider raising an exception. 
Returning just `False` seems a bit misleading.

What are your thoughts on the issue?

Best regards,
Kristian Klette


[0]: https://bugs.python.org/issue37585
[1]: https://github.com/python/cpython/pull/14737
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/R2MPDTTMJXAF54SICFSAWPPCCEWAJ7WF/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Barry Warsaw
On Jul 23, 2019, at 12:02, Steve Dower  wrote:
> 
> Even if the performance impact is zero, commits that span the entire codebase 
> for not-very-impactful changes have a negative impact on readability (for 
> example, someone will suddenly become responsible for every single module as 
> far as some blame tools are concerned - including github's suggested 
> reviewers). I'm inclined to think this one would be primarily negative.

If we were to adopt @public, its inclusion in the stdlib would follow the 
precedence we already have for non-functional changes (e.g. whitespace, code 
cleanup, etc.).  It definitely shouldn’t be done willy nilly but if the 
opportunity arises, e.g. because someone is already fixing bugs or modernizing 
a module, then it would be fair game to add @public decorators.  Of course, you 
can’t do that if it’s not available. :)

> We already maintain separate documentation from the source code, and this is 
> the canonical reference for what is public or not. Until we make a new policy 
> for __all__ to be the canonical reference, touching every file to use it is 
> premature (let alone adding a builtin).

Agreed, sort of.  We’ve had lots of cases of grey areas though, where the 
documentation doesn’t match the source. The question always becomes whether the 
source or the documentation is the source of truth.  For any individual case, 
we don’t always come down on the same side of that question.

> So I apologise for mentioning that people care about import performance. 
> Let's ignore them/that issue for now and worry instead about making sure 
> people (including us!) know what the canonical reference for public/internal 
> is.

+1

-Barry



signature.asc
Description: Message signed with OpenPGP
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/42FXHI7YH3AJFGEJOW6IQVOMO4I4OFKA/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Kyle Stanley
Steve Dower wrote:
> So I apologise for mentioning that people care about import performance. 
> Let's ignore them/that issue for now and worry instead about making sure 
> people (including us!) know what the canonical reference for 
> public/internal is.

Good point, the discussion about __all__, adding the @public decorator, and 
worrying about performance impacts might be jumping too far ahead. 

For now, if most of the core devs are in agreement with the current unwritten 
rule of  "unless explicitly documented public, all imports are private even if 
not prefixed with an underscore", I think the first priority should be to 
document it officially somewhere. That way, other developers and any potential 
confused users can be referred to it.

It might not be the best long term solution, but it would require no code 
changes to be made and provide a written canonical reference for 
differentiating public vs private. I'm not certain as to where the most 
appropriate location for the rule would be, let me know if anyone has any 
suggestions.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/5XFBD2DECM234BYIEVCFQXCZP57S4FSY/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Steve Dower

On 23Jul2019 1128, Kyle Stanley wrote:

Barry Warsaw wrote:

My package has a C version.  If public() were a builtin (which I’ve implemented)
it wouldn’t have that much import time overhead.


Is there a way we could estimate the approximate difference in overhead this 
would add using benchmarks? If it's incredibly trivial, I'd say it's worthwhile 
in order to make the public API members more explicitly declared, and provide a 
significant QoL improvement for maintaining __all__. While we should strive to 
optimize the language as much as possible, as far as I'm aware, Python's main 
priority has been readability and convenience rather than pure performance.


Even if the performance impact is zero, commits that span the entire 
codebase for not-very-impactful changes have a negative impact on 
readability (for example, someone will suddenly become responsible for 
every single module as far as some blame tools are concerned - including 
github's suggested reviewers). I'm inclined to think this one would be 
primarily negative.


We already maintain separate documentation from the source code, and 
this is the canonical reference for what is public or not. Until we make 
a new policy for __all__ to be the canonical reference, touching every 
file to use it is premature (let alone adding a builtin).


So I apologise for mentioning that people care about import performance. 
Let's ignore them/that issue for now and worry instead about making sure 
people (including us!) know what the canonical reference for 
public/internal is.


Cheers,
Steve
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/CYVVNNMRBDA53DZVLQDVBP5HCWO5FQSH/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Kyle Stanley
Barry Warsaw wrote:
> This leads to the second problem, which is that it’s too easy for the __all__ 
> to get
> out of sync with the module’s contents. Often a function or class is renamed, 
> removed, or
> added without the __all__ being updated. 

IMO, this seems to be the best part of the @public decorator, at least from a 
general user's perspective. Manually having to update __all__ anytime something 
is added, removed, or has its name modified adds an extra step to easily 
forget. Also, those coming from other languages would be far more likely to 
recognize the significance of @public, the primary purpose of the decorator is 
quite clear based on it's name alone.

Barry Warsaw wrote:
> My package has a C version.  If public() were a builtin (which I’ve 
> implemented)
> it wouldn’t have that much import time overhead.

Is there a way we could estimate the approximate difference in overhead this 
would add using benchmarks? If it's incredibly trivial, I'd say it's worthwhile 
in order to make the public API members more explicitly declared, and provide a 
significant QoL improvement for maintaining __all__. While we should strive to 
optimize the language as much as possible, as far as I'm aware, Python's main 
priority has been readability and convenience rather than pure performance.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/J4JPURDHBKXH5B6Z52G3GYRHYPZ4HUCD/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Paul Ganssle
FWIW, I actually like the idea - though not strongly enough to really
campaign for it.

My reasoning is that I think that both the current "consenting adults"
policy and possibly more importantly the fact that we are implicitly
supporting private interfaces by our reluctance to changing them has
harmed the ecosystem of Python interpreters. Because the lines between
implementation details and deliberate functionality are very fuzzy,
alternate implementations need to go out of their way to be something
like "bug compatible" with CPython.

Of course, there are all kinds of other psychological and practical
reasons that are preventing a flourishing ecosystem of alternative
Python implementations, but I do think that we could stand to be more
strict about reliance on implementation details as a way of standing up
for people who don't have the resources or market position to push
people to write their code in a way that's compatible with multiple
implementations.

I'll note that I am basically neutral on the idea of consistency across
the codebase as a goal - it would be nice but there are too many
inconsistencies even in the public portion of the API for us to ever
actually achieve it, so I don't think it's critical. The main reason I
like the idea is that I /do/ think that there are a lot of people who
use "does it start with an underscore" as their only heuristic for
whether or not something is private (particularly since that is obvious
to assess no matter how you access the function/method/attribute/class,
whereas `__all__` is extra work and many people don't know its
significance). Yes, they are just as wrong as people who we would be
breaking by sweeping changes to the private interface, but the rename
would prevent more /accidental/ reliance on implementation details.

On 7/23/19 3:27 AM, Paul Moore wrote:
> On Tue, 23 Jul 2019 at 04:58, Kyle Stanley  wrote:
>> My primary motivation was to provide more explicit declaration of public vs 
>> private, not only for the purpose of shifting the responsibility to the 
>> authors, but also to shift the liability of using private members to the 
>> user.
> My view is that the current somewhat adhoc, "consenting adults"
> approach has served us well for many years now. There have been a few
> cases where we've needed to address specific points of confusion, but
> mostly things have worked fine.
>
> With Python's increased popularity, there has been an influx of new
> users with less familiarity with Python's easy-going attitude, and
> consequently an increase in pressure for more "definite", or
> "explicit" rules. While it's great to see newcomers arrive with new
> ideas, and it's important to make their learning experience as
> pleasant as possible, we should also make sure that we don't lose the
> aspects of Python that *made* it popular in the process. And to my
> mind, that easy-going, "assume the users know what they are doing"
> attitude is a key part of Python's appeal.
>
> So I'm -1 on any global change of this nature, particularly if it is
> motivated by broad, general ideas of tightening up rules or making
> contracts more explicit rather than a specific issue.
>
> The key point about making changes on a "case by case" basis is *not*
> about doing bits of the fix when needed, but about having clear,
> practical issues that need addressing, to guide the decision on what
> particular fix is appropriate in any given situation.
>
> Paul
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-dev@python.org/message/QB436KAE4WGF66LNFJICR3P3BFZNP5BR/


signature.asc
Description: OpenPGP digital signature
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/THWGSQZUK6JZEEMRYYR7CKREHF2I5KYX/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Ethan Furman

On 07/23/2019 10:21 AM, Barry Warsaw wrote:

On Jul 23, 2019, at 09:20, Ethan Furman wrote:

On 07/23/2019 08:44 AM, Steve Dower wrote:



It's trivial, but it adds a runtime overhead that is also trivially avoided by 
putting the name in __all__ manually. And once it's public API, we shouldn't be 
making it too easy to rename the function anyway ;)


The run-time overhead added by executing @public is trivially trivial.  ;)  But 
your argument about the too-easy change of a public API strikes home.


That actually defeats the purpose of @public IMHO.  There should be exactly one 
source of truth, and that ought to be the @public decorator.


In other words, we should be smart enough to not change the name of the 
function preceded by an `@public` ?  Yeah, I can see that argument, too.  ;-)

--
~Ethan~
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/VTNXULMBOG3OIRISEKTCKYJWFF7OCP4Q/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Barry Warsaw
On Jul 23, 2019, at 09:20, Ethan Furman  wrote:
> 
> On 07/23/2019 08:44 AM, Steve Dower wrote:
> 
>> The @public decorator is basically:
>> def public(fn):
>> __all__.append(fn.__name__)
>> return fn
>> It's trivial, but it adds a runtime overhead that is also trivially avoided 
>> by putting the name in __all__ manually. And once it's public API, we 
>> shouldn't be making it too easy to rename the function anyway ;)
> 
> The run-time overhead added by executing @public is trivially trivial.  ;)  
> But your argument about the too-easy change of a public API strikes home.
> 
> I think a safer @public would be one that verifies the function is in 
> `__all__` and raises if it is not.

That actually defeats the purpose of @public IMHO.  There should be exactly one 
source of truth, and that ought to be the @public decorator.  From 
https://public.readthedocs.io/en/latest/

“”"
__all__ has two problems.

First, it separates the declaration of a name’s public export semantics from 
the implementation of that name. Usually the __all__ is put at the top of the 
module, although this isn’t required, and in some cases it’s actively 
prohibited. So when you’re looking at the definition of a function or class in 
a module, you have to search for the __all__ definition to know whether the 
function or class is intended for public consumption.

This leads to the second problem, which is that it’s too easy for the __all__ 
to get out of sync with the module’s contents. Often a function or class is 
renamed, removed, or added without the __all__ being updated. Then it’s 
difficult to know what the module author’s intent was, and it can lead to an 
exception when a string appearing in __all__ doesn’t match an existing name in 
the module. Some tools like Sphinx will complain when names appear in __all__ 
don’t appear in the module. All of this points to the root problem; it should 
be easy to keep __all__ in sync!
“””

Think of it this way: __all__ is an implementation detail, and @public is the 
API for extending it.

Cheers,
-Barry



signature.asc
Description: Message signed with OpenPGP
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/Z3KOW266JN6VOOGR5VIB5Z7KDEFAQ7MQ/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Ethan Furman

On 07/23/2019 08:44 AM, Steve Dower wrote:


The @public decorator is basically:

def public(fn):
     __all__.append(fn.__name__)
     return fn

It's trivial, but it adds a runtime overhead that is also trivially avoided by 
putting the name in __all__ manually. And once it's public API, we shouldn't be 
making it too easy to rename the function anyway ;)


The run-time overhead added by executing @public is trivially trivial.  ;)  But 
your argument about the too-easy change of a public API strikes home.

I think a safer @public would be one that verifies the function is in `__all__` 
and raises if it is not.

--
~Ethan~
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/ZFZLRGKXMBTW6ZH27XTMNE335KCZWMDY/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Barry Warsaw
On Jul 23, 2019, at 08:44, Steve Dower  wrote:

> The @public decorator is basically:
> 
> def public(fn):
>__all__.append(fn.__name__)
>return fn
> 
> It's trivial, but it adds a runtime overhead that is also trivially avoided 
> by putting the name in __all__ manually. And once it's public API, we 
> shouldn't be making it too easy to rename the function anyway ;)

My package has a C version.  If public() were a builtin (which I’ve 
implemented) it wouldn’t have that much import time overhead.

-Barry



signature.asc
Description: Message signed with OpenPGP
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/CVL6TBW7J7U4YU756DI4JUFGFDXLQS6B/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Steve Dower

On 22Jul2019 2051, Kyle Stanley wrote:

Also, is the rule  "unless explicitly documented public, all
imports are private even if not prefixed with an underscore" officially stated 
anywhere, or is it mostly implied? Personally, I think that it should be explicitly 
stated in a public manner if it's the methodology being followed.


I'm not sure if it is, which probably means it isn't. But I agree this 
should be the rule as it implicitly gives us the minimal public API upon 
definition and it is very easy to add in anything else that ought to 
have been there.



A solid alternative proposal would also be Barry's public decorator proposal: 
https://public.readthedocs.io/en/latest/. I remember him saying that it was 
largely rejected by the community when it was proposed, but I'm not certain as 
to why. It would be far easier to implement something like this than it would 
be to rename all of the non-public functions.


The @public decorator is basically:

def public(fn):
__all__.append(fn.__name__)
return fn

It's trivial, but it adds a runtime overhead that is also trivially 
avoided by putting the name in __all__ manually. And once it's public 
API, we shouldn't be making it too easy to rename the function anyway ;)


Cheers,
Steve
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/Z32PBAL2ORI7GDVC4HECURKUI4REA6B7/


[Python-Dev] Re: Python 3.7.4, Visual Studio versions for building modules from source

2019-07-23 Thread Steve Dower

On 23Jul2019 0812, Kacvinsky, Tom wrote:

Tests passed once I used the right Visual Studio Command prompt.  I was using 
the
x64 Native toolchain command shell.  Once I switched to the generic command 
shell,
all is well.  Thanks for the lick in the right direction, it got me to thinking 
that even
though the tools are installed, I should try different Visual Studio shells.


In general, it's better to not use the VS command shell at all. 
distutils figures out what it needs (setuptools does a better job, for 
what its worth).


If you are going to use the shell, also set DISTUTILS_USE_SDK=1 to 
disable the automatic detection. In the wrong shell you'll get a broken 
build, but it might have unblocked you in this case.


Cheers,
Steve
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/MZXX5YFIHUQ6VHAM26WZHWHRTXNVXNME/


[Python-Dev] Re: Python 3.7.4, Visual Studio versions for building modules from source

2019-07-23 Thread Kacvinsky, Tom



> -Original Message-
> From: Steve Dower 
> Sent: Monday, July 22, 2019 11:36 PM
> To: Kacvinsky, Tom ; python-dev@python.org
> Subject: [Python-Dev] Re: Python 3.7.4, Visual Studio versions for building
> modules from source



> This is probably not the best place to ask, though I can understand why you
> ended up here. Please try this command:
> 
>  -m test -v test_distutils -m *get_vc*
> 
> If the tests pass, post to distutils-...@python.org or the Packaging category
> on https://discuss.python.org/
> 
> If the tests fail, post the output into a new bug at https://bugs.python.org/
> along with
> 
> If the tests are skipped, you probably did not install the C++ or "Python
> Native Development" options for Visual Studio. You can run "Visual Studio
> Installer" from Start to change your installed options.

Tests passed once I used the right Visual Studio Command prompt.  I was using 
the
x64 Native toolchain command shell.  Once I switched to the generic command 
shell,
all is well.  Thanks for the lick in the right direction, it got me to thinking 
that even
though the tools are installed, I should try different Visual Studio shells.

Tom
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/55WQKH6XGVJS7EOQT3LGXBJE2LA7LSEW/


[Python-Dev] Re: Replacing 4 underscores with a $ sign, idea for a PEP

2019-07-23 Thread Aldwin Pollefeyt
Hi Karl,

  Maybe have a look at https://discuss.python.org/c/ideas where you could
open up a discussion about your ideas. It's maybe a easier tool than the
mailing list.

On Tue, Jul 23, 2019 at 2:05 PM Karl Dolenc  wrote:

> I have changed my mind. I will not be taking part in these mailing lists
> any further for the time being. My thinking about the issue I have raised
> has evolved and I have more developed ideas to offer, but for the case to
> be made properly with any chance of success, the first thing that should
> happen is for this present mode of communication to be upgraded with
> something more modern and useable. An interface where posting does not have
> a latency of several hours, where theads may be managed and moved between
> lists if needed, or deleted if needed, where code snippets may be
> represented properly. If the Steering Council is genuine in their call for
> greater inclusiveness, and in particular in better serving the needs of the
> "novice, non-technical" users, they need to ensure the communication is
> unhindered. Compared to other possible solutions that exist nowadays, these
> mailing lists are stone-age. I'll keep an eye on developments and will
> return with a proposal for an easy-to-use Tool su
>  perset of the present object/class/instance paradigm, targeting the
> aforementioned segment of users. For now, I wish you all the very best in
> your work taking Python forward.
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/JWV7DBAXBLVNNSWXY5ITWG73WXWGKZN4/
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/F6QF375OYWKREZCMCIBNKFYQ5GZFLLRX/


[Python-Dev] Re: Replacing 4 underscores with a $ sign, idea for a PEP

2019-07-23 Thread Steven D'Aprano
Hi Karl,

Email should not have a latency of "several hours" unless there is 
something seriously wrong, perhaps your mail server (your ISP?) is 
broken. Or possibly you're still being moderated: we recently changed to 
moderating newcomers, in response to a flurry of spam.

As a newcomer to this community, it isn't very nice of you to start the 
conversation by telling us that we're doing it wrong, or trying to guilt 
us into changing the ways we manage technical discussions to suit your 
taste over those of existing developers ("If the Steering Council is 
genuine in their call for greater inclusiveness...").

Many of us *like* email, and consider it modern enough, more usable than 
web interfaces, with most of the features we want and none of the ones 
we don't. Without getting into a flame-war, people have very strong 
opinions about technology, and many people consider web forums to be 
terrible for technical discussions. I'm not asking you to agree, but I 
am asking you to respect the fact that the question of what technology 
is used for technical discussions is nuanced and complicated.

In 2019, email shouldn't have a latency of more than a few minutes 
unless there's a problem, and since code is text, it is perfectly 
possible to represent code snippets in email. And while we can't move 
posts from one mailing list to another, you can certainly press the 
Forward button in your mail client to re-send it. Or copy and paste the 
text into a new email.

But for those who prefer a web-based interface, with lots of 
~~unnecessary cruft~~ features like user-icons and badges and smileys, 
you can try the Discuss interface here:

https://discuss.python.org/c/ideas

or the Python-Ideas web interface here:

https://mail.python.org/archives/list/python-id...@python.org


-- 
Steven
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/3ASOT65IYMF7SBAM4PFIFHGPQI3IRQVS/


[Python-Dev] Re: What is a public API?

2019-07-23 Thread Paul Moore
On Tue, 23 Jul 2019 at 04:58, Kyle Stanley  wrote:
>
> My primary motivation was to provide more explicit declaration of public vs 
> private, not only for the purpose of shifting the responsibility to the 
> authors, but also to shift the liability of using private members to the user.

My view is that the current somewhat adhoc, "consenting adults"
approach has served us well for many years now. There have been a few
cases where we've needed to address specific points of confusion, but
mostly things have worked fine.

With Python's increased popularity, there has been an influx of new
users with less familiarity with Python's easy-going attitude, and
consequently an increase in pressure for more "definite", or
"explicit" rules. While it's great to see newcomers arrive with new
ideas, and it's important to make their learning experience as
pleasant as possible, we should also make sure that we don't lose the
aspects of Python that *made* it popular in the process. And to my
mind, that easy-going, "assume the users know what they are doing"
attitude is a key part of Python's appeal.

So I'm -1 on any global change of this nature, particularly if it is
motivated by broad, general ideas of tightening up rules or making
contracts more explicit rather than a specific issue.

The key point about making changes on a "case by case" basis is *not*
about doing bits of the fix when needed, but about having clear,
practical issues that need addressing, to guide the decision on what
particular fix is appropriate in any given situation.

Paul
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/QB436KAE4WGF66LNFJICR3P3BFZNP5BR/


[Python-Dev] Re: Replacing 4 underscores with a $ sign, idea for a PEP

2019-07-23 Thread Karl Dolenc
I have changed my mind. I will not be taking part in these mailing lists any 
further for the time being. My thinking about the issue I have raised has 
evolved and I have more developed ideas to offer, but for the case to be made 
properly with any chance of success, the first thing that should happen is for 
this present mode of communication to be upgraded with something more modern 
and useable. An interface where posting does not have a latency of several 
hours, where theads may be managed and moved between lists if needed, or 
deleted if needed, where code snippets may be represented properly. If the 
Steering Council is genuine in their call for greater inclusiveness, and in 
particular in better serving the needs of the "novice, non-technical" users, 
they need to ensure the communication is unhindered. Compared to other possible 
solutions that exist nowadays, these mailing lists are stone-age. I'll keep an 
eye on developments and will return with a proposal for an easy-to-use Tool su
 perset of the present object/class/instance paradigm, targeting the 
aforementioned segment of users. For now, I wish you all the very best in your 
work taking Python forward.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/JWV7DBAXBLVNNSWXY5ITWG73WXWGKZN4/