Re: [Python-ideas] Heap data type, the revival

2016-10-16 Thread Devin Jeanpierre
> As I said, it has been discussed and the consensus so far was: "not 
> everything needs to be a class if it does not provide substantial benefit" + 
> "functions are more flexible" + "if it's slower that the original it won't 
> happen".

(These) functions are less flexible here. heapq forbids the use of
anything except lists, for some reason. They would be *better* as list
methods, because then array.array could implement them, and code could
accept some arbitrary mutable sequence and transform it into a heap --
but instead, lists are required.

xheap has a similar problem -- for some reason it subclasses list,
which is bad practice in OOP, for good reason. Aside from making it
impossible to use with array.array, it also e.g. makes it too easy to
violate the heap invariant -- one of the big benefits of using a heap
interface could have been making that impossible whenever your
mutations originate from the heap object).


The main thing I've always wanted from heapq is the ability to specify
a key. This is a lot easier with a class:

  x = heapq.Heap(..., key=len)
  x.pop()

vs (hypothetical, because heapq doesn't have this feature):

  x =...
  heapq.heapify(x, key=len)
  heapq.heappop(x, key=len)
  # Don't ever forget key=len unless you want to waste a few hours debugging.

Classes would be more convenient and less dangerous as soon as you
start adding features like this. +1 to classes.


Replying to OP:

> * Should __init__ shallow-copy the list or leave that up to the
> caller? Less memory if the heap object just co-opts it, but user might
> accidentally reuse the reference and ruin the heap. If we make our own
> list then it's easier to just suck in any arbitrary iterable.

Leave it up to the caller. The caller can just as easily call
list(...) as you can, and might have good reasons to want to mutate
the existing thing.  That said, as a safety thing, it might be
reasonable to create a new list by default but provide a special
factory function/class to build an instance that wraps the sequence
without copying. e.g.: heapq.Heap(x) vs heapq.HeapWrapper(x)).

> * How much should the underlying list be exposed? Is there a use case
> for __setitem__, __delitem__?

If you allow the caller to keep hold of the original list, then they
can always mutate it through that reference if they need to. If you
don't allow the caller to keep the original list, but you support the
list interface, then you've lost much of the safety you were trying to
keep by not reusing references.

-- Devin
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] pdb to support running modules

2018-01-04 Thread Devin Jeanpierre
On Thu, Jan 4, 2018 at 1:56 PM, Mario Corchero  wrote:
> Since PEP 338 we can run python modules as a script via `python -m
> module_name` but there is no way to run pdb on those (AFAIK).
>
> The proposal is to add a new argument "-m" to the pdb module to allow users
> to run `python -m pdb -m my_module_name`

Mega +1, I always, always want this, for every command that itself can
invoke other python scripts. There is prior art in that this feature
was already added to cProfile as well:
https://bugs.python.org/issue21862

-- Devin
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Add the imath module

2018-07-12 Thread Devin Jeanpierre
On Thu, Jul 12, 2018 at 5:20 AM Daniel Moisset  wrote:
> (I don't have a good name): something telling that an integer can be 
> represented exactly as a float

One might also ask that question of e.g. decimal.Decimal,
fractions.Fraction, so maybe it's better as a method or somewhere
else.

(Is this any different than float(x).as_integer_ratio() ==
(x.numerator, x.denominator) for ints/fractions?)

-- Devin
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Using sha512 instead of md5 on python.org/downloads

2018-12-07 Thread Devin Jeanpierre
On Fri, Dec 7, 2018 at 1:40 AM Antoine Pitrou  wrote:

> md5 is only used for a quick integrity check here (think of it as a
> sophisticated checksum).  For security you need to verify the
> corresponding GPG signature.
>

More to the point: you're getting the hash from the same place as the
binary. If one is vulnerable to modifications by attackers, both are. So it
doesn't matter. The real defense most people are relying on is TLS.

-- Devin
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Using sha512 instead of md5 on python.org/downloads

2018-12-07 Thread Devin Jeanpierre
On Fri, Dec 7, 2018 at 10:48 AM Antoine Pitrou  wrote:

> If the site is vulnerable to modifications, then TLS doesn't help.
> Again: you must verify the GPG signatures (since they are produced by
> the release manager's private key, which is *not* stored on the
> python.org Web site).
>

This is missing the point. They were asking why not to use SHA512. The
answer is that the hash does not provide any extra security. GPG is
separate: even if there was no GPG signature, SHA512 would still not
provide any extra security. That's why I said "more to the point". :P

Nobody "must" verify the GPG signatures. TLS doesn't protect against
everything, but neither does GPG. A naive user might just download a public
GPG key from a compromised python.org and use it to verify the compromised
release, see everything is "OK", and still be hosed.

-- Devin
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add Subscriptable ABC

2019-09-27 Thread Devin Jeanpierre
On Fri, Sep 27, 2019 at 9:14 AM Steven D'Aprano  wrote:

> But doing it correctly is too painful:
>
> if any(getattr(T, '__getitem__', None) is not None for T in
> type(obj).mro())
>

For what it's worth, walking the MRO isn't necessary, and the None trick is
only necessary if you want to support people that reuse the __getitem__
name for something else. (And it's often reasonable to say "nope, I don't
support that.")

>>> class A(object):
...   def __getitem__(self, i): return i
>>> class B(A): pass
...
>>> hasattr(B, '__getitem__')
True

So for a given object, one could check hasattr(type(obj), '__getitem__').
Or do the None trick with it, but without checking the MRO. (Or replace
None with a sentinel object()...)

-- Devin
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/AFJISUYDKGGOLL7ZCOWNNBVTAGXJPFXX/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Make list.reverse() more flexible

2021-03-07 Thread Devin Jeanpierre
On Fri, Mar 5, 2021 at 3:23 PM Steven D'Aprano  wrote:

> On Fri, Mar 05, 2021 at 04:27:27PM -, Vincent Cheong wrote:
>
> > Currently, list.reverse() only works for an entire list. If one wants
> > to reverse a section of it 'in-place', one needs to slicing which
> > makes the space complexity no longer O(1).
>
> The space complexity of a list is not constant, O(1).
>
> The lists [] and [1]*10 do not take the same amount of space.
>
> I think that, perhaps, you are trying to say that reversing a list
> requires no additional storage and can be done in place.
>

For what it's worth, that is exactly what it means for the space complexity
to be constant. Space complexity of an algorithm refers to the additional
storage needed to execute that algorithm, on top of the space used by the
input. And so list.reverse() is O(1) in space and O(n) in time, if you hold
pointer/index sizes to be O(1). (This is a big "if", and reverse is more
accurately O(log n) in space, because pointers/indexes into a sequence of
size n are O(log n) if you let n grow arbitrarily large.)

I don't know good reading for this, maybe
https://en.wikipedia.org/wiki/DSPACE#Machine_models or
https://en.wikipedia.org/wiki/In-place_algorithm

- What about sorting?
>

This is a good question!

In fact most operations you might want to do with a list, you might want to
do with a sub-list. There's even a bunch of methods that take start/stop
already, even while there's others that don't, and no good rule of thumb
for which methods have them and which don't. For example, list.index()
takes optional start/stop, but list.remove() and list.count() don't. It
even changes between types: bytes.count *does* support start/stop (as does
str.count), even though this is not required of Sequence or even of
ByteString. Speaking of which, ByteString.index() didn't have start/stop
until 3.5, and...

Ad-hoc start/stop parameters are annoying, but honestly it seems like the
inconsistency shouldn't and doesn't block adding new start/stop parameters,
since the inconsistency is already there,

(Other languages that focus on avoiding copying find it more useful to use
a vocabulary type that represents a sub-list -- for example, std::span
in C++, &[T] in Rust, or []T in Go. (The closest thing in Python that I'm
aware of is memoryview.) Once you have that kind of lazy slice, you don't
need index start/stop parameters for any particular method, and the whole
problem mostly vanishes in a poof of smoke.)

-- Devin
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/JJJH6XAAEML7WE7MAYL64KODYN2OAWG3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Auto assignment of attributes

2022-05-01 Thread Devin Jeanpierre
On Sun, May 1, 2022 at 9:35 AM Ethan Furman  wrote:

> My own thoughts about the proposal:  It seems interesting, and assigning
> as-is arguments is a chore -- but I'm not sure
> using up a token to help only one method per class is a good trade.
>

Is it unreasonable to instead suggest generalizing the assignment target
for parameters? For example, if parameter assignment happened left to
right, and allowed more than just variables, then one could do:

def __init__(self, self.x, self.y): pass

Python 2 had non-variable parameters (but not attributes, just unpacking:
def foo((x, y)): pass), but it was removed in Python 3, because of issues
with introspection (among other, perhaps less significant, issues):
https://peps.python.org/pep-3113/

Perhaps now that positional-only parameters exist, and the introspection
APIs have evolved over time, there is a way to work this into the
introspection APIs sensibly.

(a "@foo" parameter does not have this problem, because it's just a
parameter named `foo` with some extra stuff.)

-- Devin
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/UY2TQTPRFAPN3OG3TBPCOYMAYZWFZ3E4/
Code of Conduct: http://python.org/psf/codeofconduct/