Re: Lies in education [was Re: The "loop and a half"]

2017-10-12 Thread Jon Ribbens
On 2017-10-12, Ben Bacarisse  wrote:
> Chris Angelico  writes:
>> Normally, with a Python-based framework, you don't need _any_ web
>> server configuration. You simply define your URL routing within the
>> Python code. The only thing the web server needs to know is where to
>> find the web app, and that's sufficiently standard that it can be done
>> off-the-shelf; for instance, you push your code to Heroku, and they
>> set everything up to pass requests to your app. Not possible with PHP,
>> since you need *custom* web server config to manage your rewrite
>> rules.
>
> That's at odds with what I've read online which admittedly may be all
> junk.  I wanted to try Flask so I installed the Ubuntu packages but then
> got stuck on a huge document that suggested I needed to install things
> called Nginx and Gunicorn.  You've now mentioned another: Heroku.  I'm
> sure the complex instructions I found are not really required -- it was
> probably just the usual "this is what I did so this is how it's done"
> document, but I'm having trouble finding the simpler way to do it.
>
> Since no web server configuration is needed (I have a working Apache
> installation that mirrors, as closely as possible, what my hosting
> provider uses) it should be relatively easy.  Can you tell me, or can
> you point me to a resource that tells me, where to put the app?  I don't
> yet know what "push your code to Heroku" means.

"don't need _any_ web server configuration" is rather, er, optimistic.
For Apache you'd need the mod_proxy_uwsgi module installed, and the
config would be something like this:

DocumentRoot /srv/www/appname/appname

ProxyPass uwsgi://127.0.0.1:3031/


ProxyPass !


and you need an app container listening on the port defined above,
e.g. uwsgi with config like:

/etc/uwsgi/apps-available/appname.ini:

[uwsgi]
plugin = python3
socket = 127.0.0.1:3031
threads = 4
master = 1
chdir = /srv/www/appname
module = appname:app
# https://github.com/unbit/uwsgi/issues/1126
wsgi-disable-file-wrapper = true

and you'll need something to run uwsgi on system startup.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Lies in education [was Re: The "loop and a half"]

2017-10-12 Thread Jon Ribbens
On 2017-10-12, Ben Bacarisse  wrote:
> I see.  If I'm reading this right, the app requests are passed through
> to another server -- uWSGI.

Yes. It doesn't have to be uWSGI; it could be gunicorn, or you could
probably use Apache's mod_fcgid. As a last resort you could use CGI,
which wouldn't involve any long-running processes, which has the
benefit of not requiring any special support from your host but the
disadvantage of most likely being very slow indeed.

> How does this typically work on low-cost hosting?  I may be able to set
> up the ProxyPass locally (i.e. in .htaccess) but I won't be able to
> write /etc/uwsgi/apps-available/appname.ini.  Maybe there are a locally
> defined .ini files that uwsgi reads?

You need to choose a host that supports one of the relevant systems
mentioned above. If you already have a host then it's possible they
already do, otherwise you may need to choose another.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Report on non-breaking spaces in posts (was: How to join elements at the beginning and end of the list)

2017-10-31 Thread Jon Ribbens
On 2017-10-31, Stefan Ram  wrote:
> Ned Batchelder  writes:
>>     def wrapped_join(values, sep):
>
>   Ok, here's a report on me seing non-breaking spaces in 
>   posts in this NG. I have written this report so that you
>   can see that it's not my newsreader that is converting
>   something, because there is no newsreader involved.

Yes Ned's post definitely had non-breaking spaces in; it looks like
Thunderbird is turning strings of spaces into ' \xa0+ ', presumably
because things that expect HTML will squash runs of spaces (even
though the post is not HTML...)

By the way I would commend 'od -tx1z' to you as it is *far* easier to
read:

0012460 20 0a 65 6e 63 61 70 73 75 6c 61 74 65 20 69 74  > .encapsulate it<
0012500 3a 0a 0a 20 c2 a0 c2 a0 c2 a0 20 64 65 66 20 77  >:.. .. def w<
0012520 72 61 70 70 65 64 5f 6a 6f 69 6e 28 76 61 6c 75  >rapped_join(valu<
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-02 Thread Jon Ribbens
On 2017-11-01, Alexey Muranov  wrote:
> what do you think about the idea of replacing "`else`" with "`then`" in 
> the contexts of `for` and `try`?
>
> It seems clear that it should be rather "then" than "else."  Compare 
> also "try ... then ... finally" with "try ... else ... finally".
>
> Currently, with "else", it is almost impossible to guess the meaning 
> without looking into the documentation.

Why would we want to make the language worse? It is fairly obvious
what 'else' means, whereas 'then' has an obvious meaning that is in
fact the opposite of what it would actually do. It seems clear that
'else' is the correct word (or at least, far better than 'then').

Maybe the change should be that it is a syntax error to use a
'for/while...else' with no 'break'.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-02 Thread Jon Ribbens
On 2017-11-02, Steve D'Aprano  wrote:
> On Fri, 3 Nov 2017 12:39 am, Jon Ribbens wrote:
>> Why would we want to make the language worse? It is fairly obvious
>> what 'else' means, 
>
> Yes, obvious and WRONG.

Nope, obvious and right.

> for x in seq:
> do_something()
> else:
> print("seq was empty")
>
> is an obvious, common and wrong interpretation.

No, it's an obvious bug. You have a 'for...else' with no 'break'.
Like I said, that should probably be a syntax error.

>> whereas 'then' has an obvious meaning that is in 
>> fact the opposite of what it would actually do.
>
> Er... is today opposite day? Because 'then' describes precisely what it
> actually does.

No, 'then' describes the opposite of what it does. The word 'then'
implies something that always happens next, whereas 'else' conveys
the correct meaning, which is something that happens if the course
of the preceding piece of code did not go as expected.

> Perhaps before we continue, we should ask what you think for...else
> and while...else statements do. Just to be sure we are all on the
> same page here.

I think they do what the Python Language Reference sections 8.2
and 8.3 say they do.

>> It seems clear that 'else' is the correct word (or at least, far
>> better than 'then').
>
> Not clear at all. The 'for...else' block is a common source of
> confusion, if it was clear what it did, people wouldn't so often get
> it wrong.

That might be an argument that it is imperfect. It doesn't even begin
to constitute an argument that 'then' would be an improvement.

>> Maybe the change should be that it is a syntax error to use a
>> 'for/while...else' with no 'break'.
>
> Only if you want to make the experience of using Python in the interactive
> interpreter worse. See my recent post:
>
> "A use-case for for...else with no break"

Yes, I saw that. It's possible you are the only person in the world
ever to have done that. It would not make the interactive interpreter
'worse' in the slightest for that silly trick to be lost.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-03 Thread Jon Ribbens
On 2017-11-03, Alexey Muranov  wrote:
> 'Then' describes what happens next indeed, unless some extraordinary 
> situation prevents it from happening, for example:
>
> try:
> go_to_the_bakery()
> then:
> buy_croissants(2)
> except BakeryClosed:
> go_to_the_grociery()
> buy_baguette(1)
> finally:
> come_back()
>
> I know this is a poor program example (why not to use a boolean return 
> value instead of an exception, etc.), and i know that currently in 
> Python `except` must precede `else`, it is just to illustrate the 
> choice of terms.

It looks like you're suggesting not just changing the 'else' keyword
to 'then', but changing the syntax completely. The above is certainly
not an improvement on the status quo, as it is completely
counter-intuitive that exceptions in the 'then' clause will not be
caught by the 'except' clauses.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-03 Thread Jon Ribbens
On 2017-11-03, Steve D'Aprano  wrote:
> On Fri, 3 Nov 2017 03:31 am, Jon Ribbens wrote:
>> No, it's an obvious bug. You have a 'for...else' with no 'break'.
>> Like I said, that should probably be a syntax error.
>
> It should absolutely not be a syntax error. There's no reason for it
> to be a syntax error, except to satisfy some arrogant and foolish
> idea of purity.

It'd be nice if you could be a little less rude. It's not an "arrogant
and foolish idea of purity", it's to help people catch bugs in their
code, and to aid their understanding of the language.

> There are uncountable ways of writing code which is seemingly
> "pointless", and we don't make it a syntax error.

And there's uncountable ways of writing code which we *do* make a
syntax error. I'm not sure what your point is there.

>> No, 'then' describes the opposite of what it does. The word 'then'
>> implies something that always happens next, 
>
> Right, which is what happens with the for...else block.

No. Ok, so look. It's obvious that you and I have different mental
models of the situation here. You're thinking of 'for...else' as two
arbitrary clauses that run consecutively unless the whole thing is
aborted by a 'break', whereas I'm thinking of the 'for' clause as
being a search for a situation that matches a condition and the
'else' clause being what happens if the condition is not matched
(i.e. exactly the same as 'if...else').

Now there's nothing inherently *wrong* with your choice of mental
model, except it's leading you into confusion because my model means
the meaning of the 'else' keyword is intuitive and obvious, and yours
means it's counter-intuitive and confusing. Your suggestion is that
the fix is to change the language, my suggestion is to fix your model.
I'd suggest that changing your mind is easier than changing the
language ;-)

Also, my model has the advantage that if what the 'for' clause is
doing doesn't match the concept of 'searching for a match' then it's
obvious that you shouldn't be using 'for...else' in the first place.
Again, sure, the language doesn't currently strictly enforce the
requirement for a 'break', but nevertheless if you don't have one
you almost certainly have a bug.

>> Yes, I saw that. It's possible you are the only person in the world
>> ever to have done that. It would not make the interactive interpreter
>> 'worse' in the slightest for that silly trick to be lost.
>
> Just because you personally haven't used this technique doesn't make it
> a "silly trick".

It's an incredibly obscure work-around for a different problem,
i.e. an infelicity in the way the interactive prompt parses input
blocks. If the parsing is a genuine issue then the answer is to
fix that, not to look for hacks that almost never help anyway.

> And while I thank you for the complement that I am the cleverest and most
> insightful Python coder in the world,

I didn't say anything even remotely resembling that.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-03 Thread Jon Ribbens
On 2017-11-03, Chris Angelico  wrote:
> On Fri, Nov 3, 2017 at 10:49 PM, Jon Ribbens  
> wrote:
>>> It should absolutely not be a syntax error. There's no reason for it
>>> to be a syntax error, except to satisfy some arrogant and foolish
>>> idea of purity.
>>
>> It'd be nice if you could be a little less rude. It's not an "arrogant
>> and foolish idea of purity", it's to help people catch bugs in their
>> code, and to aid their understanding of the language.
>
> That wasn't rudeness.

Yes, it was.

>> No. Ok, so look. It's obvious that you and I have different mental
>> models of the situation here. You're thinking of 'for...else' as two
>> arbitrary clauses that run consecutively unless the whole thing is
>> aborted by a 'break', whereas I'm thinking of the 'for' clause as
>> being a search for a situation that matches a condition and the
>> 'else' clause being what happens if the condition is not matched
>> (i.e. exactly the same as 'if...else').
>>
>> Now there's nothing inherently *wrong* with your choice of mental
>> model, except it's leading you into confusion because my model means
>> the meaning of the 'else' keyword is intuitive and obvious, and yours
>> means it's counter-intuitive and confusing. Your suggestion is that
>> the fix is to change the language, my suggestion is to fix your model.
>> I'd suggest that changing your mind is easier than changing the
>> language ;-)
>
> If anything, I would say that Steven's model is at a lower abstraction
> layer than yours

Yes, absolutely.

> - though IMO your model is more of an example use-case than a
> description of what is actually happening.

It's a high-level way of thinking about it that avoids confusion and
leads to correct code. Unless you can come up with a *sensible*
use-case that it doesn't cover, it's also a comprehensive way of
thinking about it.

> TBH I prefer the "if 1:" trick to gather code into a block. But that
> requires pre-planning,

Or pressing up-arrow ;-)

> whereas slapping an "else:" after the loop can be done after the event.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-03 Thread Jon Ribbens
On 2017-11-03, Steve D'Aprano  wrote:
> The for loop does not necessarily perform a search:
>
> count = 1
> for obj in sequence:
> if count > MAX_OBJECTS:
> print("too many objects, halting")
> break
> process(obj)
> else:
> print("finished")
>
> According to your mental model, this code is... what? Illegal? Silly?
> Impossible? A syntax error?

That conforms to my model. It's searching for the condition
'count > MAX_OBJECTS'.

> Even when there is a search, the sense of the search may be reversed
> from your mental model:
>
> for request in sequence:
> if 'please' not in request:
> break
> process(request)
> else:
> print('done')
> return
> raise SysExit('failure to say please')

That's searching for the condition "'please' not in request".

> It doesn't matter if you can think of alternative ways of writing these code
> snippets. They're legal, and they work, and your mental model doesn't cover
> them, at all or easily. That means your mental model is at best incomplete.

You've yet to come up with one that it doesn't cover.

> In other words, it was only when I realised that `else` would be better
> written as `then` that I understood the behaviour of the statement. If I read
> it as "else", then the natural interpretation is that the block runs only if
> the loop doesn't run:

You're repeating yourself.

> You'll probably dismiss them as "silly" because they don't meet your mental
> model, and insist that I would be wrong to use them.

As above, you're mistaken.

> Your response to code that doesn't match your mental model is to say
> that it is obviously wrong and probably buggy and should be made
> into a syntax error if possible.

No, it isn't. Try reading again what I actually wrote.

> And my mental model is to treat "else" in this concept as some foreign word,
> perhaps Dutch, a false-friend that actually means "next" but due to some
> awful coincidence happens to look exactly like the English word for "else".

And that's leading you into confusion, as you've demonstrated.

> Ah yes, because it is inconceivable that anyone might have thought of a use
> for for...else without a break.

It's not inconceivable, but nobody has thought of a sensible use so far
(by which I mean one that shows it's a useful feature).

> What matters is that only code that matches your model is allowed.

You do seem to enjoy telling other people what their opinions are.
Frankly, I don't know why I even bother having opinions when you're
here to tell me what they are. In future, I'll just come to you to
find out what I think.

>> It's an incredibly obscure work-around for a different problem,
>
> You mean a different problem to "searching"? Yes indeed it is.

No, I mean a problem that has nothing to do with 'for...else' clauses.
If your door is stuck then you might climb in through a window, but
that doesn't mean that the purpose of windows is to be entrances,
or that windows should be designed to make them better entrances,
or that the problem isn't the stuck door.

>>> And while I thank you for the complement that I am the cleverest and most
>>> insightful Python coder in the world,
>> 
>> I didn't say anything even remotely resembling that.
>
> That was sarcasm.

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


Re: replacing `else` with `then` in `for` and `try`

2017-11-04 Thread Jon Ribbens
On 2017-11-04, Michael Torrie  wrote:
> On 11/03/2017 09:06 PM, Chris Angelico wrote:
>> On Sat, Nov 4, 2017 at 1:57 PM, Michael Torrie  wrote:
>>> On 11/03/2017 07:09 PM, Steve D'Aprano wrote:
 That's incorrect. There are multiple ways to exit a loop that
 will prevent the `else` block from executing, `break` is only one.
>>>
>>> Such as?
>> 
>> There are many. But other than break, I don't know of any that WOULD
>> execute the next line of code immediately _after_ the loop.
>
> Can you be more specific? What are some of these "many" ways of aborting
> a loop?  Help a guy out here.
>
> I know, for example, that we have exceptions. But those hardly matter in
> this discussion because they wouldn't execute the else clause either.
> They'd either be caught elsewhere, or end the program.  sys.exit() can
> also terminate a for loop, but it terminates the whole program without
> running the else statement.

Yes, those are the sort of thing that Steve was referring to.
He was being unhelpfully pedantic. A giant meteor destroying
the computer the program was running on would prevent the 'else'
block from executing too.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Ideas about how software should behave (was: replacing `else` with `then` in `for` and `try`)

2017-11-04 Thread Jon Ribbens
On 2017-11-04, Ben Finney  wrote:
> To respond to the criticism of an idea – criticism containing no mention
> of the person – as though it “clearly refers to the [person]”, is of
> significant concern on a software dicussion forum such as this.

No, the thing that is "of significant conern on a software discussion
forum such as this" is people such as yourself defending the abuse of
other contributors.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-05 Thread Jon Ribbens
On 2017-11-05, Steve D'Aprano  wrote:
> On Sat, 4 Nov 2017 04:44 am, Jon Ribbens wrote:
>> That conforms to my model. It's searching for the condition
>> 'count > MAX_OBJECTS'.
>
> That's sounds to me that you are willing to call just about any test of a
> condition inside a loop a "search". I don't think that's helpful. I think it
> is mangling the word to the point it is meaningless.

You're entitled to your opinion, of course. I've provided you with a
way of thinking about 'for...else' that makes its purpose and meaning
intuitively obvious. You'd apparently prefer to think about it a
different way that makes it counter-intuitive, and would like to
change the language to match your thinking instead. I'd regretfully
suggest that that is not going to happen.

> How about a loop that exits at some random time? Is that a search?
>
> for i in range(100, 0, -1):
> if flip_coin() == 'Heads':

Of course, that's searching for the condition "flip_coin() == 'Heads'".

> What you actually wrote, in various posts:
>
> You have a 'for...else' with no 'break'. Like I said, that should
> probably be a syntax error.
>
> if what the 'for' clause is doing doesn't match the concept 
> of 'searching for a match' then it's obvious that you shouldn't
> be using 'for...else' in the first place.
>
> the language doesn't currently strictly enforce the requirement
> for a 'break', but nevertheless if you don't have one you almost
> certainly have a bug.
>
> I stand by my comment as an accurate description of your response.

You're conflating two completely different points:

  * whether to allow 'for...else' with no 'break'
  * how to think about 'for...else' with a 'break'

My comment about syntax errors only has any relevance at all to the
former point.

> I find the code useful. I shouldn't have to justify why it is useful to me,
> but for the record it especially comes in handy when I've already typed out a
> multi-line loop in the REPL, and only then realised that I'll need some way
> to add an extra line at the end.

Just press up arrow to go back and edit the first line of your
current input and insert an 'if 1:' as someone else suggested.

> And yes, a better REPL would also solve that problem. But I have to use the
> REPL that exists, not the imaginary one that I'd like. If you want to call
> this a hackish work around for a limitation of the REPL, I'll say... okay.
> What's your point? It is still useful.

The question isn't whether it's useful, but whether it's *more* useful
than preventing bugs in peoples' code. You're entitled to your opinion
on that, and I'm entitled to mine, and neither opinion is 'arrogant'.

We're all just making guesses in the dark, unless anybody has any
statistics about how much time is wasted each year by bugs caused by
'for...else' with no 'break' and how much time would be wasted each
year by people being unable to use your REPL trick.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-05 Thread Jon Ribbens
On 2017-11-05, Ben Finney  wrote:
> Jon Ribbens  writes:
>> I've provided you with a way of thinking about 'for...else' that makes
>> its purpose and meaning intuitively obvious.
>
> I've read that sentence several times, and I still can't make it
> anything but a contradiction in terms.

Well, keep at it and I'm sure you'll work it out eventually.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-06 Thread Jon Ribbens
On 2017-11-06, Ben Finney  wrote:
> Jon Ribbens  writes:
>> On 2017-11-05, Ben Finney  wrote:
>> > Jon Ribbens  writes:
>> >> I've provided you with a way of thinking about 'for...else' that makes
>> >> its purpose and meaning intuitively obvious.
>> >
>> > I've read that sentence several times, and I still can't make it
>> > anything but a contradiction in terms.
>>
>> Well, keep at it and I'm sure you'll work it out eventually.
>
> You don't want to provide me with a way of thinking about it that makes
> it mean something non-contradictory? :-)

It already does mean something non-contradictory. This is
comp.lang.python (or python-list), not alt.english.remedial.
If you start from the wrong premise, as Steve is doing, then
even the most obvious of things can be rendered opaque and
confusing.

As I said, I've provided a solution to the problem, what more
do you want? This feels very much like you're arguing for
argument's sake, which is a game I'm not willing to play along
with for much longer.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-06 Thread Jon Ribbens
On 2017-11-06, Chris Angelico  wrote:
> If you start with the assumption that "intuitively obvious" doesn't
> actually mean "intuitively obvious" but actually means something
> completely different, then your statement definitely means something
> non-contradictory. But if you start with the assumption that
> "intuitively obvious" really does mean that the purpose and meaning of
> for-else can be understood easily without external information, then
> your statement contradicts itself.

I didn't say that 'for...else' was inherently "intutively obvious".
In fact I said the opposite of that. I said that *if* you start from
the right premise then it *becomes* intuitively obvious.

> This is comp.lang.python, not alt.english.remedial, so we expect you
> to use English competently, or at least accept correction when you
> misuse words.

I'm glad your expectations are being met then. You might want to work
on also reading English competently, and then everyone will be happy!

>> As I said, I've provided a solution to the problem, what more
>> do you want? This feels very much like you're arguing for
>> argument's sake, which is a game I'm not willing to play along
>> with for much longer.
>
> Except that you haven't. Your proposed solution is incorrect and false.

Yes, your logical argument there as to why is undeniable. I must admit
that your little gang's assertion that I'm foolish and mistaken because
I find Python's syntax simple to understand and you find it hard to
understand seems a little contradictory.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Ideas about how software should behave

2017-11-08 Thread Jon Ribbens
On 2017-11-08, Ben Finney  wrote:
> I also think Jon had cause to bristle somewhat at the characterisation.
> I don't think Jon was attacked by Steve's remark, but I do sympathise
> with the instinct to feel a criticism as an attack.

Steve called me arrogant, that's an attack - never mind that he hadn't
the slightest justification for it. If you're going to respond again
that he was calling the idea arrogant, then please just stop and
think for a moment: an idea, in the abstract, cannot be arrogant.
Arrogance is simply not a concept that applies to ideas, it is
a concept that applies to people. If you call an idea arrogant
you are necessarily stating that the person espousing the idea is
guilty of arrogance - that's what the word means.

Chris also called the idea "ridiculous", which is also fairly rude,
not least because, again, he hadn't the slightest justification for
it. The idea is clearly not ridiculous. One might reasonably think
that the idea was a bad idea, or unwise, etc, and someone else might
reasonably think it isn't - but to call it ridiculous is not
legitimate disagrement, it is insulting hyperbole.

You have also, in the past, pretty much straight-up called me a liar.
That is also, obviously, insulting - yet again, not that you had any
justification for it at all.

It is my experience of this group/list that if one disagrees with any
of you, Steve and Chris, you all rally round and gang up on that
person to insult and belittle them. This makes the atmosphere quite
hostile, and it would be quite remarkable if it isn't hurting the
community by driving people away. Please stop doing it.

(Finally, to forestall the inevitable accusation that I am being
unusually fragile, please let me point out that I have been around
on Usenet since the early 1990s. I am used to flamewars etc.
But this is not alt.usenet.kooks, this is comp.lang.python /
python-list, and it's supposed to be a civilised discussion forum.
If people can't have on-topic discussions without being called
ridiculous arrogant liars, then there's something wrong.)
-- 
https://mail.python.org/mailman/listinfo/python-list


Finding the module object in Python 3 C extensions

2017-11-22 Thread Jon Ribbens
In Python 2, a C extension module's global state was stored in
global variables. This obviously means the state is trivially
accessible to all code in the module.

In Python 3, you are supposed to store the global state in an
allocated memory area instead. For functions defined directly
under the module, it is still trivial to find the state, because
a pointer to the module object is passed as the first parameter
to the function, so you just call PyModule_GetState(self).

However, suppose your module defines a new type, and you define
methods on that type. How do those methods get access to the
module object so that they can access the module state?

Unfortunately neither PEP3121 nor the "Porting Extension Modules
to Python 3" documentation seem to have thought to mention this
presumably extremely common situation.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: reading text in pdf, some working sample code

2017-11-22 Thread Jon Ribbens
On 2017-11-21, Daniel Gross  wrote:
> I am new to python and jumped right into trying to read out (english) text
> from PDF files.

That's not a trivial task. However I just released pycpdf, which might
help you out. Check out https://github.com/jribbens/pycpdf which shows
an example of extracting text from PDFs. It may or may not cope with
the particular PDFs you have, as there's quite a lot of variety within
the format.

Example:

pdf = pycpdf.PDF(open("file.pdf", "rb").read())
if pdf.info and pdf.info.get('Title'):
print('Title:', pdf.info['Title'])
for pageno, page in enumerate(pdf.pages):
print('Page', pageno + 1)
print(page.text)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Finding the module object in Python 3 C extensions (Posting On Python-List Prohibited)

2017-11-23 Thread Jon Ribbens
On 2017-11-23, Lawrence D’Oliveiro  wrote:
> On Thursday, November 23, 2017 at 4:03:18 AM UTC+13, Jon Ribbens wrote:
>> In Python 3, you are supposed to store the global state in an
>> allocated memory area instead.
>
> Says who? Considering that this
> <https://docs.python.org/3/extending/extending.html#calling-python-functions-from-c>
> example uses a global variable.

Says Benjamin Peterson on docs.python.org:

https://docs.python.org/3/howto/cporting.html

"Python 3 has a revamped extension module initialization system.
(See PEP 3121.) Instead of storing module state in globals, they
should be stored in an interpreter specific structure. Creating
modules that act correctly in both Python 2 and Python 3 is
tricky."

He's not kidding, not least because it appears that creating modules
that act correctly in Python 3 at all is tricky!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: request fails on wikipedia (https) - certificate verify failed (_ssl.c:748)

2017-12-12 Thread Jon Ribbens
On 2017-12-11, F Massion  wrote:
> ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 
> (_ssl.c:748)

Try `pip install certifi`
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: request fails on wikipedia (https) - certificate verify failed (Posting On Python-List Prohibited)

2017-12-13 Thread Jon Ribbens
On 2017-12-13, Lawrence D’Oliveiro  wrote:
> On Wednesday, December 13, 2017 at 10:17:15 AM UTC+13, Jon Ribbens wrote:
>> Try `pip install certifi`
>
> It really is preferable to install standard distro packages where available, 
> rather than resort to pip:
>
> sudo apt-get install python3-certifi

No, it really really isn't.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: request fails on wikipedia (https) - certificate verify failed (_ss

2017-12-13 Thread Jon Ribbens
On 2017-12-11, F Massion  wrote:
> Am Dienstag, 12. Dezember 2017 14:33:42 UTC+1 schrieb Jon Ribbens:
>> On 2017-12-11, F Massion  wrote:
>> > ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
> (_ssl.c:748)
>>
>> Try `pip install certifi`
>
> certifi was installed.
> If I make the following changes I do not have the error message. I don't
> understand why, but this makes a difference:
>
> #import requests --> import urllib.request
>
> url = 'https://en.wikipedia.org/wiki/Stethoscope'
> #res = requests.get(url) --> res = urllib.request.urlopen(url).read()

That's because that won't even try to verify the SSL certificate.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: request fails on wikipedia (https) - certificate verify failed (Posting On Python-List Prohibited)

2017-12-13 Thread Jon Ribbens
On 2017-12-13, Chris Angelico  wrote:
> On Wed, Dec 13, 2017 at 10:38 PM, Jon Ribbens  
> wrote:
>> On 2017-12-13, Lawrence D’Oliveiro  wrote:
>>> On Wednesday, December 13, 2017 at 10:17:15 AM UTC+13, Jon Ribbens wrote:
>>>> Try `pip install certifi`
>>>
>>> It really is preferable to install standard distro packages where 
>>> available, rather than resort to pip:
>>>
>>> sudo apt-get install python3-certifi
>>
>> No, it really really isn't.
>
> This isn't a connected series of statements intended to establish a
> proposition. This is just contradiction. Not very useful here. Care to
> elaborate as to why apt-get is such a bad thing?
>
> Generally, if you're using a system-provided Python (either Py2 or
> Py3) and not using a virtual environment, it's easier and safer to use
> your system-provided package manager to install additional components.
> If you want to argue otherwise, argue it, don't just assert it.

I'll make assertions if I feel like it, especially in response to bare
assertions. System-provided Python has tended to be a disaster and
best kept at bargepole-distance. But regardless, in this specific case
you'll note that the OP is clearly using Windows and therefore any
advice to use 'sudo apt-get' will be less than entirely helpful.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Repeated Names (Repeated Names)

2017-12-17 Thread Jon Ribbens
On 2017-12-17, Tim Golden  wrote:
> On 17/12/17 00:10, Gregory Ewing wrote:
>> The duplicate posts all seem to have this header:
>> 
>> Injection-Info: news.bbs.geek.nz; 
>> posting-host="M6YmRdZYyc42DJk0lNlt/X4dpP4dzvceBNabSmESN3E";
>>  logging-data="4415"; mail-complaints-to="ab...@news.bbs.geek.nz"
>> 
>> I've emailed the administrator of bbs.geek.nz, maybe he
>> will be able to stop it.
>
> Thanks, Greg. We're actually blocking via that and related headers at 
> the gateway, which is why the mailing list is no longer seeing the 
> duplicates. I'm not sure any of us thought to email the news server 
> admin, though!

I did; the address is fake.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Repeated Names (Repeated Names)

2017-12-18 Thread Jon Ribbens
On 2017-12-17, Skip Montanaro  wrote:
>>> I've emailed the administrator of bbs.geek.nz, maybe he
>>> will be able to stop it.
>>
>> Thanks, Greg. We're actually blocking via that and related headers at
>> the gateway, which is why the mailing list is no longer seeing the
>> duplicates. I'm not sure any of us thought to email the news server
>> admin, though!
>
> I did; the address is fake.
>
> Worked for me. From the URL http://news.bbs.geek.nz/
...
> I just sent a note to that email address. No bounce yet.

"No bounce" is not the same as "worked". You'll get a bounce message
when the mail server at your end gives up some time several days in
the future. Depending on how your mail server is configured, you
may get a "delayed" warning some time before that.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: requests / SSL blocks forever?

2018-01-13 Thread Jon Ribbens
On 2018-01-13, Nagy László Zsolt  wrote:
> I have a multi threaded Windows service written in Python. It is running
> on 3.6.2.  Sometimes I cannot stop the service, because on of the
> threads won't exit. I have narrowed down the problem to request and
> _lib.SSL_read.

(a) are you setting daemon=True on the thread?
(b) are you setting a timeout on the requests call?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: requests / SSL blocks forever?

2018-01-15 Thread Jon Ribbens
On 2018-01-15, Nagy László Zsolt  wrote:
>> In other words: if the server starts to send the response, but then
>> stops sending it (without closing the connection), then this will block
>> forever anyway.
> Or maybe I misunderstood the docs and the timeout means the max. time
> elapsed between receiving two chunks of data from the server?

Yes. It's documented better here:
http://docs.python-requests.org/en/master/user/advanced/#timeouts

You can't specify a "total time" within which the operation must
succeed or be abandoned, but if you specify a timeout and the
server stops responding, either at the start of the process or
in the middle of the response, then it will time out after the
specified delay.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Right way to io.open(...) an existing file object in Python 2.7?

2018-01-16 Thread Jon Ribbens
On 2018-01-16, Skip Montanaro  wrote:
> I'd like to take advantage of the seekable() method of io.IOBase with
> existing open file objects, especially the standard in/out/err file
> objects.

If it's difficult to imagine a circumstance in which you would want to
seek on stdio/out/err where you were not making some considerable error.
But they are already io objects so you can just call sys.stdin.seekable
or whatever.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: documentation on read.encode

2018-01-16 Thread Jon Ribbens
On 2018-01-16, Larry Martell  wrote:
> Yeah I saw it mentioned in a SO post that was java related. Wondering
> if there is some way to do the same in python.

base64.b64encode(foo)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: JSON confusion

2016-08-17 Thread Jon Ribbens
On 2016-08-17, Steve Simmons  wrote:
> I'm trying to write a small utility to find the closest railway station 
> to a given (UK) postcode but the result is in JSON and I'm not familiar 
> with it. I've got as far as extracting the JSON object and I can print 
> the first level elements ("success" and "result") but I've totally 
> confused myself about how to delve into the rest of the data structure. 
> Can anyone point me to a 'how-to' for tackling a fairly complex SJON 
> object or give me some pointers. ... or maybe point out if I'm taking an 
> unnecessarily complex approach. Initially, I'm Looking to extract 
> 'stationname', 'distance' and one or two of the coordinate pairs. To be 
> honest, I'd rather have some hints rather than the whole solution 
> otherwise I'll not learn anything :-) SteveS

It's not clear what the problem is. Does this help:

  print(p_json["result"][0]["stationname"])
  print(p_json["result"][0]["latlong"]["coordinates"])

?

(To extract an item from a JSON object you index it with a string,
e.g. ["foo"]; to extract an item from an array you use an integer,
e.g. [0].)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: index for regex.search() beyond which the RE engine will not go.

2016-08-19 Thread Jon Ribbens
On 2016-08-19, iMath  wrote:
> for
> regex.search(string[, pos[, endpos]]) 
> The optional parameter endpos is the index into the string beyond
> which the RE engine will not go, while this lead me to believe the
> RE engine will still search on till the endpos position even after
> it returned the matched object, is this Right ?

I am not able rightly to apprehend the kind of confusion of ideas
that could provoke such a question.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: saving octet-stream png file

2016-08-21 Thread Jon Ribbens
On 2016-08-19, Larry Martell  wrote:
> fd.write(request.POST[key])

You could try:

  request.encoding = "iso-8859-1"
  fd.write(request.POST[key].encode("iso-8859-1"))

It's hacky and nasty and there might be a better "official" method
but I think it should work.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Does This Scare You?

2016-08-22 Thread Jon Ribbens
On 2016-08-22, Steve D'Aprano  wrote:
> On Mon, 22 Aug 2016 10:38 am, eryk sun wrote:
>> To me it's scary that this check misses cases because it's trying to
>> be cross-platform instead of simply relying on GetFullPathName to do
>> the work. For example, it misses at least the following cases:
>
> Instead of shaking in your boots over a simple bug in a non-critical
> library, how about reporting these cases on the bug tracker with an
> explanation of the problem?

That seems a rather unnecessarily harsh response.
Also, it's not "non-critical", this is a security bug.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Does This Scare You?

2016-08-22 Thread Jon Ribbens
On 2016-08-22, Chris Angelico  wrote:
> On Mon, Aug 22, 2016 at 8:33 PM, Jon Ribbens  
> wrote:
>> On 2016-08-22, Steve D'Aprano  wrote:
>>> On Mon, 22 Aug 2016 10:38 am, eryk sun wrote:
>>>> To me it's scary that this check misses cases because it's trying to
>>>> be cross-platform instead of simply relying on GetFullPathName to do
>>>> the work. For example, it misses at least the following cases:
>>>
>>> Instead of shaking in your boots over a simple bug in a non-critical
>>> library, how about reporting these cases on the bug tracker with an
>>> explanation of the problem?
>>
>> That seems a rather unnecessarily harsh response.
>> Also, it's not "non-critical", this is a security bug.
>
> Explain how?

I don't know what purpose you are envisaging this function being used
for, but the only one I can think of is input sanitisation. e.g. a web
form where you receive a file from the Internet and store it somewhere,
and you want to use the filename given to you rather than choose your
own randomly-generated one.

Under Unix all you need to do is check for the filename starting with
"." or containing "/." (or "/", depending on your requirements).
Under Windows you would use this function, which apparently doesn't
work, hence: security hole.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Does This Scare You?

2016-08-22 Thread Jon Ribbens
On 2016-08-22, Chris Angelico  wrote:
> I tried things like "con.txt" and it simply failed (no such file or
> directory), without printing anything to the console.

I'm not sure how you got that to fail, but writing to "con.txt"
certainly does write to the console in Windows 10 - I just tried it:

C:\>echo hello >con.txt
hello
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: saving octet-stream png file

2016-08-22 Thread Jon Ribbens
On 2016-08-22, Larry Martell  wrote:
> On Sun, Aug 21, 2016 at 5:24 PM, Jon Ribbens  
> wrote:
>> On 2016-08-19, Larry Martell  wrote:
>>> fd.write(request.POST[key])
>>
>> You could try:
>>
>>   request.encoding = "iso-8859-1"
>>   fd.write(request.POST[key].encode("iso-8859-1"))
>>
>> It's hacky and nasty and there might be a better "official" method
>> but I think it should work.
>
> For some reason that messes up the request structure:
>
> (Pdb) type(request.POST[key])
>
> (Pdb) request.encoding = "iso-8859-1"
> (Pdb) type(request.POST[key])
> *** MultiValueDictKeyError:
> "u'right-carotidartery:63B2E474-D690-445F-B92A-31EBADDC9D93.png'"

Sounds like you should be filing a bug report with Django.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Does This Scare You?

2016-08-22 Thread Jon Ribbens
On 2016-08-22, Steve D'Aprano  wrote:
> On Mon, 22 Aug 2016 09:50 pm, Jon Ribbens wrote:
>> I don't know what purpose you are envisaging this function being used
>> for, but the only one I can think of is input sanitisation. e.g. a web
>> form where you receive a file from the Internet and store it somewhere,
>> and you want to use the filename given to you rather than choose your
>> own randomly-generated one.
>> 
>> Under Unix all you need to do is check for the filename starting with
>> "." or containing "/." (or "/", depending on your requirements).
>> Under Windows you would use this function, which apparently doesn't
>> work, hence: security hole.
>
> That's backwards: it works under Windows, but is buggy under non-Windows.

I'm not sure what you're getting at there, but you appear to be wrong:

C:\>python
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:38:48) [MSC v.1900
32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pathlib
>>> pathlib.WindowsPath("con .txt").is_reserved()
False

> For starters, even on Unix I probably wouldn't want to
> use "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\.txt" as a
> file name, even if it is technically legal.

That might be your personal preference, but it's not a security hole
per se.

> No, not at all. I can't assume that just because a file name is legal that I
> can write to it. Even after sanitising the name (or deciding I don't need
> to bother) I still need to be prepared to catch I/O errors when writing the
> file -- including attempts to write to reserved file names.

As mentioned by others, this is nothing to do with lack of error-checking.

> Technically that could be called a DoS attack, but the same could be said
> for ANY bug that raises an exception. I think that it takes more than that
> to be a security bug.

It doesn't raise an exception. It interacts with the hardware of the
server.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Does This Scare You?

2016-08-22 Thread Jon Ribbens
On 2016-08-22, Steve D'Aprano  wrote:
> I'm not really sure what the question is -- we've established that there's a
> bug in the non-Windows implementation that tries to emulate Window's
> behaviour. What else is there to argue about?

It doesn't seem to be "the non-Windows implementation", it seems to be
"the implementation".

> - Does anyone wish to argue that Python shouldn't provide
>   PureWindowsPath.is_reserved on non-Windows systems? For what reason?

It shouldn't provide it at all unless it works. The reason I'm putting
it that way is that making it work may be a very great deal of effort
(What is the actual full list of special filenames? Does it vary
between supported Windows versions? How can anyone tell test that
the function is correct?)

> - Is anyone still arguing that there's a new security vulnerability
>   here because of the pathlib functions? If so, how do you see this
>   attack working? (Existing filename-based attacks are not new.)

Already answered.

> I don't see what the issue is. Eryksun found a bug in pathlib, well done. (I
> mean that, I'm not being sarcastic.) I still don't understand why Lawrence
> posed his question in the first place.

Presumably because of the security implications as described.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: saving octet-stream png file

2016-08-22 Thread Jon Ribbens
On 2016-08-22, Larry Martell  wrote:
> On Mon, Aug 22, 2016 at 1:25 PM, Jon Ribbens  
> wrote:
>> On 2016-08-22, Larry Martell  wrote:
>>> (Pdb) type(request.POST[key])
>>>
>>> (Pdb) request.encoding = "iso-8859-1"
>>> (Pdb) type(request.POST[key])
>>> *** MultiValueDictKeyError:
>>> "u'right-carotidartery:63B2E474-D690-445F-B92A-31EBADDC9D93.png'"
>>
>> Sounds like you should be filing a bug report with Django.
>
> Turns out that is expected behavior -- request.encoding clears
> existing GET/POST data. Not sure how it's useful to set that then.

Yeah it clears the cached parsed data, but when you fetch a value
afterwards it should automatically recalculate the data, not fail.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Does This Scare You?

2016-08-26 Thread Jon Ribbens
On 2016-08-24, Chris Angelico  wrote:
> On Thu, Aug 25, 2016 at 7:00 AM, eryk sun  wrote:
>> I discovered why "Logs/con.txt" isn't working right in Windows 7,
>> while "Logs/nul.txt" does get redirected correctly to r"\\.\nul".
>> Prior to Windows 8 the console doesn't use an NT device, so the base
>> API has a function named BaseIsThisAConsoleName that looks for names
>> such as r"\\.CON", r"\\.CONIN$", "CON", or r"C:\Temp\con.txt" and
>> returns either "CONIN$" or "CONOUT$" if there's a match. A match for
>> just "CON" maps to one or the other of the latter depending on whether
>> read or write access is desired.
>
> See? This is why *even after I tested it* I wasn't sure I was right!
> The rules are... complicated.

Hence my doubts about this function - it has almost no chance of not
being broken, potentially leading to whatever code was using it having
security holes. Perhaps it should be deprecated or at least attract a
large caveat in the documentation.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any ReST aware editors?

2016-09-22 Thread Jon Ribbens
On 2016-09-22, Steve D'Aprano  wrote:
> I have editors which will use syntax highlighting on .rst files, but I'm
> hoping for something a bit smarter.
>
> What I'd like is an editor with a split window, one side showing the rst
> that I can edit, the other side showing the formatted text updated as I
> type. (Or at least, updated every thirty seconds or so.)
>
> Anybody know anything like that?

There's dillinger.io if online is ok.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any ReST aware editors?

2016-09-22 Thread Jon Ribbens
On 2016-09-22, Yann Kaiser  wrote:
> On Thu, Sep 22, 2016, 12:59 Jon Ribbens  wrote:
>> On 2016-09-22, Steve D'Aprano  wrote:
>> > I have editors which will use syntax highlighting on .rst files, but I'm
>> > hoping for something a bit smarter.
>> >
>> > What I'd like is an editor with a split window, one side showing the rst
>> > that I can edit, the other side showing the formatted text updated as I
>> > type. (Or at least, updated every thirty seconds or so.)
>> >
>> > Anybody know anything like that?
>>
>> There's dillinger.io if online is ok.
>
> Does that work with with ReST?

Ah, apologies, ignore me, I was forgetting that ReST and MD
are not the same.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generator comprehension - list None

2016-10-18 Thread Jon Ribbens
On 2016-10-18, Steve D'Aprano  wrote:
> On Tue, 18 Oct 2016 10:43 pm, Sayth Renshaw wrote:
>> I was solving a problem to create a generator comprehension with 'Got '
>> and a number for each in range 10.
>> 
>> This I did however I also get a list of None. I don't understand where
>> none comes from. Can you please clarify?
>
> You get None because print() returns None.
>
> Try this:
>
> result = print("Hello")
> result is None
>
>
> Every time you call print(), it returns None. Normally that just gets thrown
> away, and no harm is done, but when you do it in a generator expression,
> the None values are collected and returned.
>
> Your code:
>
> a = (print("Got {0}".format(num[0])) for num in enumerate(range(10)))
> b = list(a)
> print(b)
>
>
> is equivalent to this:
>
> b = []
> for two_numbers in enumerate(range(10)):
> num = two_numbers[0]  # pick the first number
> message = "Got {0}".format(num)
> result = print(message)
> b.append(result)
>
> print(b)

I must admit I find the idea of enumerate(range(n)) quite pleasing.
gotta keep track of which numbers those numbers are!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Internet Data Handling » mailbox

2016-10-23 Thread Jon Ribbens
On 2016-10-23, Jon Ribbens  wrote:
> On 2016-10-23, Jason Friedman  wrote:
>>>
>>> for message in mailbox.mbox(sys.argv[1]):
>>> if message.has_key("From") and message.has_key("To"):
>>> addrs = message.get_all("From")
>>> addrs.extend(message.get_all("To"))
>>> for addr in addrs:
>>> addrl = addr.lower()
>>> if addrl.find(name) > 0:
>>> print message
>>> break
>>> -
>>
>> I usually see
>>
>> if addrl.find(name) > 0:
>>
>> written as
>>
>> if name in addrl:
>
> I suppose technically it would be:
>
>   iaddrf name in addrl[1:]:

s/iaddrf/if/ obviously!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Internet Data Handling » mailbox

2016-10-23 Thread Jon Ribbens
On 2016-10-23, Jason Friedman  wrote:
>>
>> for message in mailbox.mbox(sys.argv[1]):
>> if message.has_key("From") and message.has_key("To"):
>> addrs = message.get_all("From")
>> addrs.extend(message.get_all("To"))
>> for addr in addrs:
>> addrl = addr.lower()
>> if addrl.find(name) > 0:
>> print message
>> break
>> -
>
> I usually see
>
> if addrl.find(name) > 0:
>
> written as
>
> if name in addrl:

I suppose technically it would be:

  iaddrf name in addrl[1:]:

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


Re: Calling Bash Command From Python

2016-10-31 Thread Jon Ribbens
On 2016-10-31, Wildman  wrote:
> Here is a bash command that I want to run from a python
> program:  sudo grep "^user\:" /etc/shadow
>
> If I enter the command directly into a terminal it works
> perfectly.  If I run it from a python program it returns an
> empty string.  Below is the code I am using.  Suggestions
> appreciated.
>
> cmdlist = ["sudo", "grep", '"^$USER\:"', "/etc/shadow"]
> p = subprocess.Popen(cmdlist,
>  stdout=subprocess.PIPE,
>  stderr=subprocess.PIPE)
> shadow, err = p.communicate()
> print shadow

Slightly surprised that nobody's pointed out that in your bash
invocation, the first argument to grep is:

^user\:

and in the Python code it is:

"$USER\:"

Your cmdlist should read:

["sudo", "grep", r"^user\:", "/etc/shadow"]

or if you really want it to do the same as the bash:

["sudo", "grep", "^" + os.environ["USER"] + r"\:", "/etc/shadow"]

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


Re: pip3 : command not found

2016-10-31 Thread Jon Ribbens
On 2016-10-31, Ben Finney  wrote:
> Instead, you should invoke the exact Python interpreter you want – and,
> by extension, the Python environment into which you want packages
> installed.
>
> $ /foo/bar/virtualenv/bin/python3 -m pip install LoremIpsum

I'm slightly curious about that. /foo/bar/virtualenv/bin/python3
will just be a symbolic link to /usr/bin/python3, so how does
invoking the intepreter that way make any difference?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-05 Thread Jon Ribbens
On 2016-10-31, Steve D'Aprano  wrote:
> On Mon, 31 Oct 2016 07:21 pm, Jon Ribbens wrote:
>> On 2016-10-31, Ben Finney  wrote:
>>> Instead, you should invoke the exact Python interpreter you want – and,
>>> by extension, the Python environment into which you want packages
>>> installed.
>>>
>>> $ /foo/bar/virtualenv/bin/python3 -m pip install LoremIpsum
>> 
>> I'm slightly curious about that. /foo/bar/virtualenv/bin/python3
>> will just be a symbolic link to /usr/bin/python3, so how does
>> invoking the intepreter that way make any difference?
>
> It doesn't. If you read the rest of Ben's post, or for that matter the
> subject line of this thread, you will see he is comparing:
>
> path/to/python3 -m pip install LoremIpsum
>
> against:
>
> pip3 install LoremIpsum

No, if you read the rest of Ben's post you will see that that is not
what he wrote. Maybe he meant what you are saying, I don't know, but
it isn't what he wrote. He clearly implied that you can run Python
in the context of a virtualenv by just invoking that virtualenv's
local Python without running 'activate' first. I'm curious as to
whether this is true or not (how virtualenvs work seems to be very
opaque).
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-05 Thread Jon Ribbens
On 2016-11-05, Steve D'Aprano  wrote:
> Your implied question here:
>
>> Maybe he meant what you are saying, I don't know, but 
>> it isn't what he wrote. He clearly implied that you can run Python
>> in the context of a virtualenv by just invoking that virtualenv's
>> local Python without running 'activate' first. I'm curious as to
>> whether this is true or not (how virtualenvs work seems to be very
>> opaque).
>
> is a separate issue from the symbolic link question. Possibly you do have to
> run `activate` first, I don't know, but either way this was not part of
> your earlier question. You said nothing about `activate` in your earlier
> post, and this is the first time you have mentioned it.

I'm afraid I can only suggest that you try re-reading the subthread
again until you manage to understand it. It wasn't really that
complicated but you seem to have confused yourself greatly.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-05 Thread Jon Ribbens
On 2016-11-05, Steve D'Aprano  wrote:
> On Sun, 6 Nov 2016 02:55 am, Jon Ribbens wrote:
>> I'm afraid I can only suggest that you try re-reading the subthread
>> again until you manage to understand it. It wasn't really that
>> complicated but you seem to have confused yourself greatly.
>
> Are you serious?

Yes. You haven't understood the thread, and I don't know how to
explain it any simpler, so I'm afraid all I can suggest is that
you re-read what was already written.

> I can only repeat yet again: you have not understood Ben.

You're still wrong no matter how many times you repeat yourself.
I've understood him, you have understood neither him nor me.
You've got hung up on the pip3 issue which is blinding you to
the other implications of Ben's answer.

Threads can and usually do diverge to a greater or lesser degree. Just
because a post is a follow-up in a thread doesn't mean that post is
entirely and solely about the original topic of that thread. Try
dropping your preconceptions and reading the sub-thread again from the
post before my first post without making false assumptions and while
bearing in mind that I am asking a question that is tangential to the
original question rather than directly descended from it.

> The implication is that the answer to your question is Yes, you can run
> Python in the context of a virtualenv by just invoking that virtualenv's
> local Python without running 'activate' first.

So you were wrong earlier when you said you couldn't do that?

You're spending an awful lot of effort being pointlessly argumentative
about who has or hasn't understood what while avoiding addressing the
actual perfectly simple question - if running Python directly from a
venv path is equivalent to running 'activate' then Python, how does it
know that it's in a venv? (Yes, I know it can sort-of work out where
it's run from using argv[0] but how does it know it's *in a venv*?)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-05 Thread Jon Ribbens
On 2016-11-06, Steve D'Aprano  wrote:
> *plonk*

Thank feck for that, I was beginning to think he'd never shut up.

I don't suppose anyone else more constructive and informed actually
knows the answer to my rather simple question of how Python knows
it's in a venv? ;-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-05 Thread Jon Ribbens
On 2016-11-06, Chris Angelico  wrote:
> On Sun, Nov 6, 2016 at 3:03 PM, Jon Ribbens  wrote:
>> I don't suppose anyone else more constructive and informed actually
>> knows the answer to my rather simple question of how Python knows
>> it's in a venv? ;-)
>
> Two ways.
>
> 1) Normally, you 'activate' the venv by sourcing a script into your
> shell. This modifies $PATH, $PYTHONHOME, and I think a couple of other
> environment variables.

It sets VIRTUAL_ENV, adds the virtualenv's bin directory to PATH,
and *unsets* PYTHONHOME if set. That's it (modulo storing old values
of variables and updating PS1 which is presumably just cosmetic).

> 2) If Python notices that its executable comes from a venv, it uses it.

Yes. My question is *how does it notice*?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-05 Thread Jon Ribbens
On 2016-11-06, Ben Finney  wrote:
> Jon Ribbens  writes:
>> On 2016-11-06, Steve D'Aprano  wrote:
>> > *plonk*
>>
>> Thank feck for that, I was beginning to think he'd never shut up.
>
> Really? I didn't see a single message from Steven that wasn't solicited
> by an assertion from you that needed response.
>
> If your concept of “won't shut up” includes “responds to me when I
> demand he acknowledge my position is correct”, then it seems clear the
> problem has a different solution.

He consistently misunderstood almost everything I said (which is
a pattern of behaviour he seems to have, i.e. heroically
misunderstanding people so he can argue with them), lied about
what I had said, lied about what he had said, lied about me "not
arguing in good faith", was rude and insulting, and studiously avoided
the actual interesting and useful topic in favour of a stupid and
pointless flamewar about his misunderstanding of my original question.

He clearly didn't know the answer to the question nor did he have any
interest in dicussing it in a civilised manner with a view to
discovering the answer, he just wants an argument. So yes, I view him
bowing out of the conversation as an unmitigated blessing.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-05 Thread Jon Ribbens
On 2016-11-06, Ben Finney  wrote:
> Jon Ribbens  writes:
>
>> He […] lied about me "not arguing in good faith"
>
> I find you to be not arguing in good faith;

I find that to be particularly pompous of you. I am arguing in good
faith regardless of your misguided opinion.

I wasn't actually even trying to argue at all, I simply had
a question, which Steven successfully derailed into a stupid argument
as to whether he knew better than me what question I was asking.

>> So yes, I view him bowing out of the conversation as an unmitigated
>> blessing.
>
> You could have disengaged at any time, so I don't find your statement
> believable.

I plead guilty to an excess of optimism that I could persuade him to
start discussing the actual topic. I had actually reached the end of
my optimism in that regard and the last post I had made to him was
the last one in which I had intended to bother trying to get through
to him.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-06 Thread Jon Ribbens
On 2016-11-06, Chris Angelico  wrote:
> On Sun, Nov 6, 2016 at 4:27 PM, Jon Ribbens  wrote:
>>> 2) If Python notices that its executable comes from a venv, it uses it.
>>
>> Yes. My question is *how does it notice*?
>
> I could answer this question, but since you don't appear to be
> following the thread properly, I'll point out that it's already been
> said up above. Go read it.

That's not particularly helpful. I have read the entire thread and
the question does not appear to have been answered. Could you at
least provide the date/date/from (if not a Message-ID) of the post
you are talking about please?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: pip3 : command not found

2016-11-06 Thread Jon Ribbens
On 2016-11-06, Michael Torrie  wrote:
> I'm guessing that it notices by examining the path it was launched from
> and looks for virtual environment files relative to that path.

Indeed, the mysterious thing is what are "virtual environment files"?
The official docs say "A venv is a directory tree which contains
Python executable files and other files which indicate that it is a
venv." but don't explain what they mean by "other files".

> Here's what a random site said about this (I didn't search long enough
> to find the official documentation on python.org):
>
> "When Python is starting up, it looks at the path of its binary (which,
> in a virtual environment, is actually just a copy of, or symlink to,
> your system’s Python binary). It then sets the location of sys.prefix
> and sys.exec_prefix based on this location, omitting the “bin” portion
> of the path."

Aha! This is progress. OK, I've done some more investigation and it
looks like the above description is not exactly accurate.

The magic is actually all in site.py by the looks of it. This looks
at argv[0] (effectively - it's actually using sys.executable) and
then looks for ./pyvenv.cfg and ../pyvenv.cfg relative to that file.
Only if one of those files exists does it then set sys.prefix to ..
relative to sys.executable and then sys.path is set using various
hard-coded paths relative to sys.prefix.

So the answer to my original question is that Python knows it's in a
venv "if there exists a file called pyvenv.cfg in the same directory
as or the parent directory of the python exeuctable".

It also appears that this feature was added in Python 3.3, so being
able to run the venv python directly presumably only works on that
version and later.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python String Handling

2016-11-12 Thread Jon Ribbens
On 2016-11-12, subhabangal...@gmail.com  wrote:
> I am restating the problem. 
>
> "Hello my name is Richard"
>
> is a string. 
>
> I have tagged the words Hello and Richard
> as "Hello/Hi" and "Richard/P". 
> After this I could get the string as a list of words
> as in,
> ['Hello/Hi','my','name','is','Richard/P'] 
>
> Now I want to replace the string with 
> Hello/Hi my name is Richard/P
>
> It may seem a joining of list but is not because
> if I try to make, 
> ['Hello/Hi','my/M','name','is/I','Richard/P'] 
>
> I may do, but doing the following string 
>
> Hello/Hi my/M name is/I Richard/P
>
> is tough as entities with tag may vary. I have to make
> a rule. 
>
> I am trying to recognize the index of the word in
> the list, pop it and replace with new value and joining
> the list as string.

I'm afraid your description of the problem is still rather... opaque.
>From your original post it looked like the answer would be:

def replacer(target, replacements):
for replacement in replacements:
if "/" in replacement:
target = target.replace(*replacement.split("/", 1))
return target

print(replacer("Hello my name is Richard",
   ['Hello/Hi','my','name','is','Richard/P']))

but in your new description where you start talking about word indices
I have no idea if that's what you actually wanted.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Guido? Where are you?

2016-11-22 Thread Jon Ribbens
On 2016-11-22, Gilmeh Serda  wrote:
> On Mon, 21 Nov 2016 00:53:33 -0800, Ethan Furman wrote:
>> Unfortunately, we do not have any control over the comp.lang.python
>> newsgroup
>
> Gee, "unfortunately"? Really!? Gosh! I'm glad I don't have to live 
> anywhere close to you. 8·[
>
> NOBODY "owns" the groups, and rightfully so. If you want the groups to be 
> private, run your own server!

... or make them moderated, which I think they should do to this group,
so that the list mirroring works properly.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: python 2.7.12 on Linux behaving differently than on Windows

2016-12-06 Thread Jon Ribbens
On 2016-12-06, Chris Angelico  wrote:
> On Tue, Dec 6, 2016 at 10:56 PM, BartC  wrote:
>> In that directory (which was on Windows but accessible via a virtual Linux),
>> typing any Linux command followed by * would have required all 3.4 million
>> directory entries to be accessed in order to build a 3.4 million-element
>> argv list. I've no idea how long that would have taken.
>
> I just asked Python to build me a 4-million-element list, and it took
> no visible time - a small fraction of a second. Don't be afraid of
> large argument lists. We're not writing 8088 Assembly Language
> programs in 64KB of working memory here.

To be fair, literally just now I couldn't run the command I wanted to:

  sed -i -e 's/foo/bar/g' /dir/ectory/*.txt

because there were 300,000 files matching the glob, and 'sed' can't
cope with that many command-line arguments. I had to do this instead:

  find /dir/ectory -name '*.txt' -exec sed -i -e 's/foo/bar/g' {} \;

(Yes, I could also have done something with 'xargs' instead, which
would've been slower to write and quicker to run.)

However please don't take that to mean I agree with BartC - he's
clearly just reacting with instinctive hostility to the unknown.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: CLP stats: last 500 posts

2016-12-09 Thread Jon Ribbens
On 2016-12-09, DFS  wrote:
> import sys as y,nntplib as t,datetime as d
> s=''
> g=y.argv[1]
> n=t.NNTP(s,119,'','')
> r,a,b,e,gn=n.group(g)
> def printStat(st,hd,rg):
>   r,d=n.xhdr(st,'%s-%s'%rg)
>   p=[]
>   for i in range(len(d)):
>   v=d[i][1]
>   if st=='Subject':v=v[4:] if v[:3]=='Re:' else v
>   p.append(v)
>   x=[(i,p.count(i)) for i in set(p)]
>   x.sort(key=lambda s:(-s[1],s[0].lower()))
>   print('Posts  %s %s'%(len(set(p)),hd))
>   for v in x: print(' %s %s'%(v[1],v[0]))
>   print
> print 'As of '+d.datetime.now().strftime("%I:%M%p %B %d, %Y") + '\n'
> m=(int(e)-int(y.argv[3])+1,int(e))
> printStat("From","Posters",m)
> printStat("Subject","Subjects",m)
> printStat("User-Agent","User-Agents",m)
> n.quit()

Was there ever an "International Obfuscated Python Code Contest"? ;-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: CLP stats: last 500 posts

2016-12-11 Thread Jon Ribbens
On 2016-12-11, Wildman  wrote:
> I don't think it is a problem with the code but any thoughts
> why giganews is not playing nice?

Most likely because you're calling XHDR on a header which is not in
the server's overview file.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: OT - "Soft" ESC key on the new MacBook Pro

2016-12-14 Thread Jon Ribbens
On 2016-12-14, mm0fmf  wrote:
> On 14/12/2016 02:40, Paul Rubin wrote:
>> Skip Montanaro  writes:
>>> Does the lack of a physical ESC key create problems for people, especially
>>> Emacs users?
>>
>> Not a Mac user and I rarely use ESC instead of ALT while editing with
>> Emacs on a local computer, but when editing remotely I do have to use
>> ESC because the Gnome terminal emulator steals a few ALTed keys.  Maybe
>> there is a way to stop that behaviour but it didn't occur to me til just
>> now.  Hmm.
>>
>> Meanwhile the concept of a computer with "no escape" just shows Apple
>> getting deeper into existentialism.  First it was the hipster Mac users
>> with the Beatnik black berets and turtlenecks, and now this. 
>
> If you need a full time ESC key then you are just "typing it wrong" as 
> Steve Jobs would say if he wasn't dead.

With respect to pressing ESC in Emacs or Vim, you literally don't need
a "full time" ESC key, you only need one when the keyboard input focus
is on a terminal, Emacs or Vim window - and I should imagine that the
ESC key is indeed present whenever that's the case.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Extended ASCII

2017-01-13 Thread Jon Ribbens
On 2017-01-13, D'Arcy Cain  wrote:
> I thought I was done with this crap once I moved to 3.x but some 
> Winblows machines are still sending what some circles call "Extended 
> ASCII".  I have a file that I am trying to read and it is barfing on 
> some characters.  For example:
>
>due to the Qu\xe9bec government
>
> Obviously should be "due to the Québec government".  I can't figure out 
> what that encoding is or if it is anything that can even be understood 
> outside of M$.

$ cat decode.py
#!/usr/bin/env python3

CODECS = (
"ascii", "big5", "big5hkscs", "cp037", "cp273", "cp424", "cp437", "cp500",
"cp720", "cp737", "cp775", "cp850", "cp852", "cp855", "cp856", "cp857",
"cp858", "cp860", "cp861", "cp862", "cp863", "cp864", "cp865", "cp866",
"cp869", "cp874", "cp875", "cp932", "cp949", "cp950", "cp1006", "cp1026",
"cp1125", "cp1140", "cp1250", "cp1251", "cp1252", "cp1253", "cp1254",
"cp1255", "cp1256", "cp1257", "cp1258", "cp65001", "euc_jp",
"euc_jis_2004", "euc_jisx0213", "euc_kr", "gb2312", "gbk", "gb18030", "hz",
"iso2022_jp", "iso2022_jp_1", "iso2022_jp_2", "iso2022_jp_2004",
"iso2022_jp_3", "iso2022_jp_ext", "iso2022_kr", "latin_1", "iso8859_2",
"iso8859_3", "iso8859_4", "iso8859_5", "iso8859_6", "iso8859_7",
"iso8859_8", "iso8859_9", "iso8859_10", "iso8859_11", "iso8859_13",
"iso8859_14", "iso8859_15", "iso8859_16", "johab", "koi8_r", "koi8_t",
"koi8_u", "kz1048", "mac_cyrillic", "mac_greek", "mac_iceland",
"mac_latin2", "mac_roman", "mac_turkish", "ptcp154", "shift_jis",
"shift_jis_2004", "shift_jisx0213", "utf_32", "utf_32_be", "utf_32_le",
"utf_16", "utf_16_be", "utf_16_le", "utf_7", "utf_8", "utf_8_sig",
)

for encoding in CODECS:
try:
if b"Qu\xe9bec".decode(encoding) == "Québec":
print(encoding)
except (UnicodeError, LookupError):
pass

$ ./decode.py 
cp1250
cp1252
cp1254
cp1256
cp1257
cp1258
latin_1
iso8859_2
iso8859_3
iso8859_4
iso8859_9
iso8859_10
iso8859_13
iso8859_14
iso8859_15
iso8859_16
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is Python SSL API thread-safe?

2017-01-22 Thread Jon Ribbens
On 2017-01-22, Grant Edwards  wrote:
> Is the Python SSL API thread-safe with respect to recv() and send()?
>
> IOW, can I have one thread doing blocking recv() calls on an SSL
> connection object while "simultaneously" a second thread is calling
> send() on that same connection object?

I think this question is equivalent to asking "is OpenSSL thread-safe",
the answer to which would appear to be "yes":
https://www.openssl.org/docs/man1.0.2/crypto/threads.html
(the necessary functions mentioned on that page, threadid_func and
locking_function are indeed set by Python).
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How coding in Python is bad for you

2017-01-23 Thread Jon Ribbens
On 2017-01-23, alister  wrote:
> On Tue, 24 Jan 2017 07:19:42 +1100, Chris Angelico wrote:
>> I believe that's "bad for you" in the sense that chocolate is bad for
>> you.
>> 
>> It isn't.
>
> chocolate is a poison (lethal dose for a human approx 22lb)

That's a meaningless statement. *Everything* is a poison
in sufficient quantities.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How coding in Python is bad for you

2017-01-24 Thread Jon Ribbens
On 2017-01-24, alister  wrote:
> On Mon, 23 Jan 2017 20:39:26 +0000, Jon Ribbens wrote:
>> That's a meaningless statement. *Everything* is a poison in sufficient
>> quantities.
>
> indees when I here someone saying "I won't have any xyz because they have 
> heard that too much is bad for them" I invariably inform them that too 
> much oxygen is poisonous & challenge then to cut that out completely :-)

Just wait until they find out that raw fruit and vegetables contain
hundreds of chemicals!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Need reviews for my book on introductory python

2017-01-27 Thread Jon Ribbens
On 2017-01-27, D'Arcy Cain  wrote:
> On 2017-01-27 03:17 PM, bob gailer wrote:
>> sudo apt-get won't work on Windows. Tell the reader that this is how to
>> do it in Unix, and show the Windows equivalent.
>
> Actually it doesn't work on Unix either.  It only works on Linux.

Actually it doesn't work on Linux either.  It only works on
Debian-derived systems.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Rename file without overwriting existing files

2017-01-30 Thread Jon Ribbens
On 2017-01-30, Jussi Piitulainen  wrote:
> It doesn't seem to be documented. I looked at help(os.link) on Python
> 3.4 and the corresponding current library documentation on the web. I
> saw no mention of what happens when dst exists already.
>
> Also, creating a hard link doesn't seem to work between different file
> systems, which may well be relevant to Steve's case. I get:
>
> OSError: [Errno 18] Invalid cross-device link: [snip]
>
> And that also is not mentioned in the docs.

Nor *should* either of those things be mentioned in the Python docs.

A lot of the functions of the 'os' module do nothing but call the
underlying OS system call with the same name. It would not only be
redundant to copy the OS documentation into the Python documentation,
it would be misleading and wrong, because of course the behaviour may
vary slightly from OS to OS.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Rename file without overwriting existing files

2017-01-30 Thread Jon Ribbens
On 2017-01-30, Peter Otten <__pete...@web.de> wrote:
> Jon Ribbens wrote:
>> A lot of the functions of the 'os' module do nothing but call the
>> underlying OS system call with the same name. It would not only be
>> redundant to copy the OS documentation into the Python documentation,
>> it would be misleading and wrong, because of course the behaviour may
>> vary slightly from OS to OS.
>
> However, the current Python version of link() is sufficiently different from 
><https://linux.die.net/man/2/link>, say, to warrant its own documentation.

What are you referring to here? As far as I can see, the current
Python implementation of link() just calls the underlying OS call
directly.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Rename file without overwriting existing files

2017-01-30 Thread Jon Ribbens
On 2017-01-30, Peter Otten <__pete...@web.de> wrote:
> Jon Ribbens wrote:
>> On 2017-01-30, Peter Otten <__pete...@web.de> wrote:
>>> However, the current Python version of link() is sufficiently different
>>> from
>>><https://linux.die.net/man/2/link>, say, to warrant its own documentation.
>> 
>> What are you referring to here? As far as I can see, the current
>> Python implementation of link() just calls the underlying OS call
>> directly.
>
> The current signature differs from that of link()
>
> os.link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)
>
> but it looks like you are right in so far as link() is still called by 
> default:

Yeah, it's been extended to call linkat() if the extra parameters are
provided, but it still calls link() if you call it like link().

So basically it's been extended analogously to how Linux has been,
and the OS manpage is still the right place to look to understand
what it does. (linkat() is documented as part of the same manpage as
link() anyway.)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: New PyPI launched, legacy PyPI shutting down April 30

2018-04-18 Thread Jon Ribbens
Going live with the new site while its search function is mostly
inoperative seems a bit brave.

https://github.com/pypa/warehouse/issues/3746

On 2018-04-18, Noah  wrote:
> Awesome
>
> On Mon, Apr 16, 2018 at 8:21 PM, Laura Hampton 
> wrote:
>
>> New PyPI launched, legacy PyPI shutting down April 30[1]
>>
>> Starting today, the canonical Python Package Index is at https://pypi.org
>> and uses the new Warehouse codebase.  We announced the https://pypi.org
>> beta on March 26 and your feedback and test usage have helped us get it
>> production-ready.
>>
>> Monday April 16 (2018-04-16): We launched the new PyPI, redirecting
>> browser traffic and API calls (including "pip install") from
>> pypi.python.org to the new site. The old codebase is still available at
>> https://legacy.pypi.org for now.
>>
>> Monday April 30 (2018-04-30): We plan to shut down legacy PyPI
>> https://legacy.pypi.org . The address pypi.python.org will continue to
>> redirect to Warehouse.
>>
>> For more details, see our roadmap: https://wiki.python.org/psf/
>> WarehouseRoadmap
>>
>> If your site/service links to or uses pypi.python.org, you should start
>> using pypi.org instead: https://warehouse.readthedocs.
>> io/api-reference/integration-guide/#migrating-to-the-new-pypi
>>
>> Thank you.
>>
>> [1] https://blog.python.org/2018/04/new-pypi-launched-legacy-
>> pypi-shutting.html
>>
>>   Laura Hampton
>>   laura at laura-hampton dot com
>> --
>> https://mail.python.org/mailman/listinfo/python-announce-list
>>
>> Support the Python Software Foundation:
>> http://www.python.org/psf/donations/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: please test the new PyPI (now in beta)

2018-04-18 Thread Jon Ribbens
On 2018-03-27, Chris Angelico  wrote:
> Any time you see something that requires JavaScript for this, you know
> you've found a web site that dates back to... uhh, actually I don't
> know. I only have versioning info on MDN back as far as HTML 4.01 ergo
> 1999, and the placeholder attribute is there. Of course, that doesn't
> mean everyone *used* it, but it was certainly available.

'placeholder' was most certainly not in HTML 4 - it was an HTML 5
addition (i.e. it was standardised in 2014). Browser support arrived
mainly in 2011/2012, so if a web site is 5 years old it probably could
not have relied on this feature.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: New PyPI launched, legacy PyPI shutting down April 30

2018-04-19 Thread Jon Ribbens
On 2018-04-18, Tony van der Hoff  wrote:
> On 18/04/18 13:15, Zbigniew Jędrzejewski-Szmek wrote:
>> On Mon, Apr 16, 2018 at 01:21:50PM -0400, Laura Hampton wrote:
>>> New PyPI launched, legacy PyPI shutting down April 30[1]  
>>>
>>> Starting today, the canonical Python Package Index is at
>>> https://pypi.org and uses the new Warehouse codebase.  We
>>> announced the https://pypi.org beta on March 26 and your feedback
>>> and test usage have helped us get it production-ready.  

>> Search seems to be broken:
>>> https://pypi.org/search/?q=numpy
>> There were no results for 'numpy' 
>>
>> Zbyszek
> *Using your link:
> 2,797* projects for "/numpy/"

The search system is indeed intermittently broken:
https://github.com/pypa/warehouse/issues/3746
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Leading 0's syntax error in datetime.date module (Python 3.6)

2018-05-10 Thread Jon Ribbens
On 2018-05-10, Skip Montanaro  wrote:
>> I wonder why someone would take a feature generally agreed to be a
>> poorly designed feature of C, and incorporate it into a new language.
>
> I think you might be looking at a decision made in the late 1980s through a
> pair of glasses made in 2018.
>
> As a C programmer back then I never had a problem with C's octal number
> notation. People coming from C, C++ or Java to Python at that time would
> certainly have understood that syntax. It's only in the past 15 years or so
> that we've seen tons of people coming to Python as a first language for
> whom leading zero notation would be unfamiliar.

This whole thread is reminding me PHP 2, which would magically treat
the second parameter of ChMod() as octal, because clearly if weak
typing is good then *no* typing must be best of all!

  ChMod($filename, 644); // second parameter is actually 420 base 10

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


Re: Leading 0's syntax error in datetime.date module (Python 3.6)

2018-05-11 Thread Jon Ribbens
On 2018-05-10, Chris Angelico  wrote:
> On Fri, May 11, 2018 at 5:04 AM, Jon Ribbens  
> wrote:
>> This whole thread is reminding me PHP 2, which would magically treat
>> the second parameter of ChMod() as octal, because clearly if weak
>> typing is good then *no* typing must be best of all!
>>
>>   ChMod($filename, 644); // second parameter is actually 420 base 10
>
> Bear in mind that Unix file modes are traditionally written in octal,
> because they have no meaning as numbers. They're more like
> enumerations, or bitfields. The second parameter happens to be equal
> to the base 10 number 420, but that's completely useless. A file mode
> of 100644 means something; a file mode of 0x81a4 or 33188 decimal
> means nothing. PHP went for crazy magic there, but if the API had been
> built such that the "644" is passed as a string, it would have been
> completely sane and entirely useful.

Or indeed if it was passed as 0644 or 0o644 as an octal literal.
The issue is not *why* Rasmus did this - that's obvious - the issue is
that he didn't know why he *shouldn't* make a language where 1234 is a
decimal integer literal except sometimes it isn't. The PHP manual even
recommended that you write the second parameter as 0644 to "remind you"
that it was treated as octal, although the leading 0 made no actual
semantic difference to the way the code was parsed by the language.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Leading 0's syntax error in datetime.date module (Python 3.6)

2018-05-11 Thread Jon Ribbens
On 2018-05-11, Grant Edwards  wrote:
> On 2018-05-11, Gene Heskett  wrote:
>> Computers haven't read a single 8 bit byte in years, some reading
>> 128 or 256 bits in a single read cycle today.
>
> Nonsense.  All modern CPUs that I'm aware of still still support
> single byte reads, and compilers still use those instructions when the
> size of the object being read is 8 bits.

It's not nonsense. The CPU might have a 'load a byte' instruction but
it will actually read more than a byte and then throw away the extra.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: urllib3 1.23 breaks API

2018-06-06 Thread Jon Ribbens
On 2018-06-06, Cecil Westerhof  wrote:
> I had installed urllib3 1.22 for Python3. I upgraded it to 1.23. This
> broke the requirements for requests 2.18.4:
> requests 2.18.4 has requirement urllib3<1.23,>=1.21.1, but you'll have 
> urllib3 1.23 which is incompatible
>
> I downgraded to 1.22, but this should not happen I think.

For some reason requests is weirdly specific about which versions
of urllib3 it will accept. The latest version in github allows
urllib3 1.23, but for some reason requests also appears to have
stopped issuing new releases mid last year.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Stefan's headers [was:Names and identifiers]

2018-06-10 Thread Jon Ribbens
On 2018-06-08, Chris Angelico  wrote:
> Yes, this is true. It's not copyright that is unenforceable, but the
> copyright notice in his message. Nobody is denying that he owns his
> own words; but by posting them on a public forum, he - like everyone
> else here - is implicitly granting us the right to read them.

Copyright law protects copying - you don't need permission to read
things, except inasmuch as the words must be copied onto your screen
in order for you to see them.

The question is whether he's implicitly granting the right for his
posts to be copied to all the places that Usenet posts will generally
get copied to when one posts them, or whether his header message
explicitly disavowing such permission overrides the implicit grant.

I'd suggest that since the processes he's purporting to disallow are
entirely standard and automated and he knows full well they exist and
that there is no mechanism by which they could be affected by his
notice, the notice has little effect.

> Right. Imagine if I write a poem, just like you say, and then I have
> the words posted on a gigantic billboard. In small print in the bottom
> corner of the billboard, I say "Copyright 2018 Chris Angelico. Taking
> photographs of this billboard is forbidden.". Do I still own copyright
> in the poem? Definitely. Can I stop people from (or sue people for)
> taking photos of the billboard? Probably not, although that's one for
> the lawyers to argue.

You probably can actually. I'm not an expert but I seem to recall the
rules are along the lines that you can't complain if your billboard
happens to appear incidentally in the background of a photograph,
but if someone takes a photo specifically *of* the billboard, your
copyright is infringed.

>> PS IMO copyright laws should be abolished altogether. At the very least
>> one should pay for copyright protection. One €1 for the first year, €2
>> for the second, €4 for the third and so on exponentially.
>
> Why should I have to pay money for the right to own my own creations?

Because ideas are not inherently property. Why should you get to "own"
a particular sequence of notes, or words, or colours? Why should the
government grant you and enforce an ability to prevent other people
singing those notes, or writing those words, or painting those colours?

> Copyright laws and international treaties are there to protect content
> creators and encourage creation. They need to have set expiration time
> (IMO 50 years is long enough - not "50 years since author's death" but
> 50 years since publication) after which the work becomes free to use,
> but the protections are important and extremely useful.

That was the original intention of copyright certainly, but I'd
hope that it is relatively non-controversial that the terms limits
on copyright these days have skewed the balance far too much in
favour of copyright owners and away from the public.

> Open source would not exist without copyright, because it is
> copyright law that gives license terms their meaning

That's patent nonsense. The only reason, in general, that open source
even requires any licence terms because of the existence of copyright
law. Sure, you couldn't do tricks like the GPL without copyright law,
but then there would be much less *need* for the GPL without copyright
law.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Stefan's headers [was:Names and identifiers]

2018-06-10 Thread Jon Ribbens
On 2018-06-10, Ben Bacarisse  wrote:
> Jon Ribbens  writes:
>
>> I'd suggest that since the processes he's purporting to disallow are
>> entirely standard and automated and he knows full well they exist and
>> that there is no mechanism by which they could be affected by his
>> notice, the notice has little effect.
>
> The Copyright notice is probably intended for human eyes.  IIRC his
> posts don't show up on Google groups, for example, so there *is* a
> mechanism by which *some* of the headers (it may be X-no-archive) do get
> acted on.

True - many Usenet headers are intended for automated processing - but
the meaning of X-No-Archive is not even slightly similar to what he
says in his copyright notice, and so any overlap between the effect of
the former and the intention of the latter is merely coincidental.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Reading EmailMessage from file

2018-07-15 Thread Jon Ribbens
On 2018-07-15, Skip Montanaro  wrote:
> I have an email message in a file (see attached).

Attachments don't work here.

> something like this should construct an email message from the file:
>
 from email.message import EmailMessage
 msg = EmailMessage()
 fp = open("/home/skip/tmp/79487694")
 msg.set_content(fp.read())

What are you actually trying to do? You're talking like you're trying
to read an existing RFC822 email-with-headers from a file, but you're
showing code that creates a new email with body content set from
a file, which is a completely different thing.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Users banned

2018-07-15 Thread Jon Ribbens
On 2018-07-15, Chris Angelico  wrote:
> On Mon, Jul 16, 2018 at 7:35 AM, Marko Rauhamaa  wrote:
>> Christian Gollwitzer :
>>> Am 15.07.18 um 19:25 schrieb Ethan Furman:
 The following users are now banned from Python List:
 ...
 BartC
>>>
>>> I don't really think that this is appropriate. Bart may have deviant
>>> optinions, mostly he thinks that his own work is superior to Python -
>>> but he has always argued in a calm and technical manner.
>>
>> +1
>
> How about we trust the moderators to moderate wisely?

Do you have any reason to believe the message at the top of the
thread purporting to ban users was genuinely from the moderators?
Because there are obvious reasons to believe otherwise.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Reading EmailMessage from file

2018-07-16 Thread Jon Ribbens
On 2018-07-16, Skip Montanaro  wrote:
>> What are you actually trying to do? You're talking like you're trying
>> to read an existing RFC822 email-with-headers from a file, but you're
>> showing code that creates a new email with body content set from
>> a file, which is a completely different thing.
>
> Yes, that's exactly what I'm trying to do.

That's not entirely helpful; I said I couldn't tell what you were
trying to do, was it (a) or (b), and you've replied "Yes".

> A bit more context... I'm trying to port SpamBayes from Python 2 to
> Python 3. The file I attached which failed to come through was
> exactly what you suggested, an email in a file. That is what the
> example from the 3.7 docs suggested I should be able to do

If you are actually trying to read an RFC822 message-with-headers
from a file, which the above suggests you are, then the example has
nothing to do with your situation and as has been suggested you want
the email.message_from_binary_file(fp) function (the documentation
for which is cunningly hidden near the bottom of
https://docs.python.org/3/library/email.parser.html).
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Users banned

2018-07-17 Thread Jon Ribbens
On 2018-07-17, Steven D'Aprano  wrote:
> But neither of these are prohibited by the CoC, neither of these should 
> be banning offense, and even if they were, he should have had a formal 
> warning first.
>
> Preferably TWO formal warnings: the first privately, the second publicly, 
> and only on the third offence a ban.
>
> And I question the fairness of a six month ban, rather than (let's say) 
> an initial one month ban.
>
> As for banning Rick, when he isn't even posting at the moment, I don't 
> even have words for that. There's no statute of limitation for murder, 
> but surely "being obnoxious on the internet" ought to come with a fairly 
> short period of forgiveness.

Why is anyone responding as if the original "Users banned" message was
genuine, rather than the obvious troll it actually was?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Users banned

2018-07-17 Thread Jon Ribbens
On 2018-07-17, Thomas Jollans  wrote:
> On 2018-07-16 01:29, Jon Ribbens wrote:
>> Do you have any reason to believe the message at the top of the
>> thread purporting to ban users was genuinely from the moderators?
>> Because there are obvious reasons to believe otherwise.
>
> Care to elaborate?

Anyone can trivially forge a message from anyone, so there is no
reason to believe the message is genuine. Reasons to believe it is
not genuine include the poor formatting, poorly-written content,
inconsistent and insulting way the 'banned users' are referred to,
and the fact that out of the three people it purports to ban, one
was apparently already banned and another appears not to be a current
poster anyway.

If it is a genuine message from the moderators then they really need
to improve their policy to give clear warnings to people before they
are banned, and they need to PGP-sign official messages so that they
can be recognised.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Cookies not showing up in environ

2018-07-21 Thread Jon Ribbens
On 2018-07-20, abc abc  wrote:
> Well, I'm so messed up between so many sources and tutorials I don't
> know which way is up. 

I think one of the main issues is that you don't seem to have decided
whether you're writing a WSGI application or a Django application.

WSGI:

def application(environ, start_response):
start_response('200 OK',
   [('Content-Type', 'text/plain; charset=utf-8')])
return [environ.get('HTTP_COOKIE', '').encode('utf-8')]


Django:

views.py:

from django.http import HttpResponse

def cookies(request):
return HttpResponse(repr(request.COOKIES),
'text/plain; charset=utf-8')

urls.py:

from django.urls import path

from . import views

urlpatterns = [
path('cookies', views.cookies),
]

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


Re: Cookies not showing up in environ

2018-07-21 Thread Jon Ribbens
On 2018-07-21, abc abc  wrote:
>> I think one of the main issues is that you don't seem to have decided
>> whether you're writing a WSGI application or a Django application.
>
> Yes, I suppose I thought Django had to use wsgi to process requests,
> I didn't know there were 'two' options here.

Django does use wsgi to process requests. But if you've written
an application in Django, you don't need to then write it again
without Django - Django has its own wsgi app that will call the
Django app for you.

> Does your example represent one or the other?

Both - I gave two alternatives, and labelled each. You only need one.

> project_folder/app/wsgi.py
>
> def application(environ, start_response):
> start_response('200 OK',
>[('Content-Type', 'text/plain; charset=utf-8')])
> return [environ.get('HTTP_COOKIE', '').encode('utf-8')]

You should delete that and change it back to whatever 'django
startproject' gave you originally for wsgi.py. If you're writing
a django app then you don't need to also write a wsgi app.

> Cleared all cookies in the browser, and went to
> localhost:8000/cookies which loaded with no error in the console or
> browser. No cookies were created in the browser preferences.

Well, you're not setting any cookies. You'd need to do something like:

 def cookies(request):
 response = HttpResponse(repr(request.COOKIES),
 'text/plain; charset=utf-8')
 response.set_cookie('mycookie', 'value')
 return response

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


Re: Pylint false positives

2018-08-14 Thread Jon Ribbens
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"...

> 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. It also
doesn't like the `del inner, name` because theoretically neither of
those names might be defined, if the loop executed zero times.
-- 
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 +0000, 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: Pylint false positives

2018-08-17 Thread Jon Ribbens
On 2018-08-17, Steven D'Aprano  wrote:
> On the other hand, your objection to the following three idioms is as 
> good an example of the Blurb Paradox as I've ever seen.

Do you mean the Blub Paradox? If so, you're misunderstanding or at
least misapplying it.

>>   * 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() 
>
> Each of these are standard Python techniques, utterly unexceptional.

I guess we'll have to agree to disagree there.

> "Code running directly under the class" describes every use of the class 
> keyword (except those with an empty body). If you write:
>
> class Spam:
> x = 1
>
> you are running code under the class. This is not just a pedantic 
> technicality,

Yes, it absolutely is, in this context. Having code other than
assignments and function definitions under the class statement
is extremely rare.

>>   * dynamically adding @abstractmethod methods to a class
>
> I simply don't get this objection at all. All methods are added 
> dynamically to classes (that's how Python's execution model works, def is 
> an executable statement not a declaration). Making them abstract doesn't 
> change this.
>
> You might be thinking of the warning in the docs:
>
> "Dynamically adding abstract methods to a class, [...] 
> [is] not supported."
>
> but that is talking about the case where you add the method to the class 
> after the class is created, from the outside:

Yes, I was referring to that. You may well be right about what it
means to say, but it's not what it actually says.

>> (Not to mention your code means the methods cannot have meaningful
>> docstrings.)
>
> Of course they can, provided they're all identical, give or take some 
> simple string substitutions.

Hence "meaningful".
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [OT] master/slave debate in Python

2018-09-25 Thread Jon Ribbens
On 2018-09-25, Chris Angelico  wrote:
> On Tue, Sep 25, 2018 at 11:01 PM Calvin Spealman  wrote:
>> This entire conversation is inappropriate for this mailing list. Please
>> leave this free for people who need to ask and give help with Python,
>> regardless of which side of this argument you are on.
>
> Considering that the conversation is specifically about changes to the
> code and documentation of the language and its reference
> implementation, I don't see that it's off topic.

Those things might be on topic on python-dev - although I am sure
no-one would thank you for continuing this discussion there - but
this is comp.lang.python/python-list and here this is off-topic.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [OT] master/slave debate in Python

2018-09-25 Thread Jon Ribbens
On 2018-09-25, Chris Angelico  wrote:
> On Wed, Sep 26, 2018 at 1:56 AM Jon Ribbens  wrote:
>> Those things might be on topic on python-dev - although I am sure
>> no-one would thank you for continuing this discussion there - but
>> this is comp.lang.python/python-list and here this is off-topic.
>
> Okay. What *is* on-topic for python-list?

https://www.python.org/community/lists/#comp-lang-python says
 
  "Pretty much anything Python-related is fair game for discussion"

*however* it also says

  "Most discussion on comp.lang.python is about developing with
   Python, not about development of the Python interpreter itself"

and python-dev is clearly the on-topic place for such discussion.

I suggest you also read what the above link says about flamebait,
and the Python Community Code of Conduct at
https://www.python.org/psf/codeofconduct/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: So apparently I've been banned from this list

2018-10-01 Thread Jon Ribbens
On 2018-10-01, Roel Schroeven  wrote:
> I'm not very active here, but I've been lurking for years. In my eyes 
> Steven has always been active and helpful. Now he has *once* been a 
> *tiny bit* rude, and he's banned for that?

It's not "once", it's a long-standing pattern of behaviour.

> As far as I can see the moderators do a pretty good job overall, but 
> this decision is ... weird.

It's not "weird" so much as it is "long overdue", but even I would say
that two months seems a little excessive.
-- 
https://mail.python.org/mailman/listinfo/python-list


Untrusted code execution

2016-04-03 Thread Jon Ribbens
I'd just like to say up front that this is more of a thought experiment
than anything else, I don't have any plans to use this idea on any
genuinely untrusted code. Apart from anything else, there's the
denial-of-service issue.

That said, is there any way that the following Python 3.4 code could
result in a arbitrary code execution security hole?

tree = compile(untrusted_code, "

Re: Untrusted code execution

2016-04-05 Thread Jon Ribbens
On 2016-04-03, Jon Ribbens  wrote:
> I'd just like to say up front that this is more of a thought experiment
> than anything else, I don't have any plans to use this idea on any
> genuinely untrusted code. Apart from anything else, there's the
> denial-of-service issue.
>
> That said, is there any way that the following Python 3.4 code could
> result in a arbitrary code execution security hole?
>
> tree = compile(untrusted_code, "

Re: Untrusted code execution

2016-04-05 Thread Jon Ribbens
On 2016-04-05, Rustom Mody  wrote:
> On Tuesday, April 5, 2016 at 7:19:39 PM UTC+5:30, Jon Ribbens wrote:
>> On 2016-04-03, Jon Ribbens wrote:
>> > I'd just like to say up front that this is more of a thought experiment
>> > than anything else, I don't have any plans to use this idea on any
>> > genuinely untrusted code. Apart from anything else, there's the
>> > denial-of-service issue.
>> >
>> > That said, is there any way that the following Python 3.4 code could
>> > result in a arbitrary code execution security hole?
>> >
>> > tree = compile(untrusted_code, "

Re: Untrusted code execution

2016-04-05 Thread Jon Ribbens
On 2016-04-05, Chris Angelico  wrote:
> On Wed, Apr 6, 2016 at 12:50 AM, Ian Kelly  wrote:
>> Same here, although it looks to me like this approach could work. Or
>> I'm just not clever enough to see how it could be exploited.
>
> Having been bitten in the past (our test box was compromised by
> python-list white hats within 20 minutes of the invitation being sent
> out), I would go with the second of your options. Nearly anything is
> vulnerable if it's permitted to execute arbitrary code; all it takes
> is a sufficiently smart operator.

I am inviting sufficiently smart operators to demonstrate the flaw in
my suggested code ;-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Untrusted code execution

2016-04-05 Thread Jon Ribbens
On 2016-04-05, Chris Angelico  wrote:
> On Wed, Apr 6, 2016 at 3:26 AM, Jon Ribbens
> wrote:
>> The received wisdom is that restricted code execution in Python is
>> an insolubly hard problem, but it looks a bit like my 7-line example
>> above disproves this theory, provided you choose carefully what you
>> provide in your restricted __builtins__ - but people who knows more
>> than me about Python seem to have thought about this problem for
>> longer than I have and come up with the opposite conclusion so I'm
>> curious what I'm missing.
>
> No, it doesn't disprove anything. All you've shown is "here's a piece
> of code that hasn't yet been compromised". :)

Yes, obviously. I wasn't asking for pedantry.

> Your code is a *lot* safer for using 'eval' rather than 'exec'.
> Otherwise, you'd be easily exploited using exceptions, which carry a
> ton of info.

... but all in attributes that don't start with "_", as far as I can see.

I think a very similar approach would work with 'exec' too, just you
would obviously have to disallow ast.Import and ast.ImportFrom.

> But even so, I would not bet money (much less the security of my
> systems) on this being safe.

I wasn't planning on betting any money ;-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Untrusted code execution

2016-04-05 Thread Jon Ribbens
On 2016-04-05, Chris Angelico  wrote:
> You can also create objects of various types using literal/display
> syntax, and that might let you craft some weird construct that
> effectively access those attributes without actually having an
> attribute that starts with an underscore. (Think of "getattr(x,
> '\x5f_class__')", although obviously it'll take more work than that,
> since getattr itself isn't available.)

Indeed. Although I think it would be safe to add a "proxy" getattr()
to the namespace's __builtins__ that just checked if the first
character of "name" was "_" and if so raised an AttributeError or
somesuch, and otherwise passed straight through to the real getattr(),
e.g.:

def proxy_getattr(obj, name, *args):
if type(name) is str and not name.startswith("_"):
return getattr(obj, name, *args)
raise AttributeError("Not allowed to access private attributes")
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Untrusted code execution

2016-04-05 Thread Jon Ribbens
On 2016-04-05, Jon Ribbens  wrote:
> On 2016-04-05, Chris Angelico  wrote:
>> Your code is a *lot* safer for using 'eval' rather than 'exec'.
>> Otherwise, you'd be easily exploited using exceptions, which carry a
>> ton of info.
>
> ... but all in attributes that don't start with "_", as far as I can see.

Sorry, obviously I meant "that *do* start with '_'".
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Untrusted code execution

2016-04-05 Thread Jon Ribbens
On 2016-04-05, Paul Rubin  wrote:
> Jon Ribbens  writes:
>>> isinstance(node, ast.Attribute) and node.attr.startswith("_")):
>>> raise ValueError("Access to private values is not allowed.")
>>> namespace = {"__builtins__": {"int": int, "str": str, "len": len}}
>
>> Nobody has any thoughts on this at all?
>
> What happens with foo.get("5F5F70726976617465".decode("hex")) ?
> That string decodes to "__private".

Yes, and? My code wasn't trying to prevent anyone building a string
object starting with an underline, merely to prevent anyone accessing
identifiers and attributes that start with an underline. The namespace
I was suggesting didn't provide access to any objects which have a
'get()' method which would access attributes.

> The Bastion module was removed some time ago because every attempt
> to do something like this has failed...

Bastion was removed because rexec was removed. rexec was very
ambitious - it was trying to allow completely arbitrary Python code
to run in a restricted namespace. That's basically impossible since
Python 2.2.

My method is doing something different - it's inspecting the code
before it's run, to prevent the methods by which people would easily
escape rexec's environment.

Originally, rexec existed and was thought to be 'safe'. Then the
new-style classes were added in Python 2.2, which made rexec unsafe,
so it was disabled because there was no easy way to fix it. Then
in Python 2.5 the new AST parser was added, which I think perhaps
does provide a way to fix rexec (or at least something rexec-like),
but nobody was clamoring for rexec to be reinstated so nobody looked
into what ast could do for rexec.

... unless I'm missing something obvious (or subtle!)
-- 
https://mail.python.org/mailman/listinfo/python-list


  1   2   3   4   5   6   7   >