Barry Warsaw | 18 Jun 2013 18:41
Favicon

Adding zope.testrunner test selections to unittest

(Maybe this should better go to the TIP mailing list?)

One of the last things from zope.testrunner that I really rely on is its
highly flexible support for test selection:

https://pypi.python.org/pypi/zope.testrunner/4.4.0#test-selection

Michael and I talked briefly about adding something like this to unittest's
discover, where --pattern is a pale ghost of related functionality.

Has anybody looked into this before?  Is it something that we could feasibly
add to Python 3.4?  (and/or unittest2)

-Barry
_______________________________________________
Python-ideas mailing list
Python-ideas@...
http://mail.python.org/mailman/listinfo/python-ideas
Giampaolo Rodola' | 17 Jun 2013 02:32
Picon
Gravatar

unittest and warnings

One of the features I like the most in the new unittest2 module is the possibility to skip tests and how they are included in the final result (e.g. FAILED (errors=2, failures=3, skipped=5)).

After http://bugs.python.org/issue10093 it is not rare that different ResourceWarnings appear while running tests.
Personally I consider these warnings as something which needs to be fixed so after I run tests I often scroll my console window back up to see whether there were warnings.
Would it make sense for unittest module to keep track of them so that they get included in the final test result as it currently happens for skipped tests?

Side note: unittest provides some "skip-related" APIs such unittest.skip*, TestResult.skipped and others but I don't think something similar would be necessary except maybe a TestResult.warnings list similar to TestResult.skipped.

Regards,

- Giampaolo

_______________________________________________
Python-ideas mailing list
Python-ideas@...
http://mail.python.org/mailman/listinfo/python-ideas
Jan Wrobel | 13 Jun 2013 20:06
Gravatar

Elixir inspired pipe to apply a series of functions

Hello,

I've recently stumbled upon a Joe Armstrong's (of Erlang) blog post
that praises an Elixir pipe operator:

http://joearms.github.io/2013/05/31/a-week-with-elixir.html

The operator allows to nicely structure code that applies a series of
functions to transform an input value to some output.

I often end up writing code like:

pkcs7_unpad(
  reduce(lambda result, block: result.append(block),
    map(decrypt_block,
      pairwise([iv] + secret_blocks))))

Which is dense, and needs to be read backwards (last operation is
written first), but as Joe notes, the alternative is also not very
compelling:

  decrypted_blocks = map(decrypt_block, pairwise([iv] + secret_blocks))
  combined_blocks = reduce(lambda result, block: result.append(block))
  return pkcs7_unpad(combined_blocks)

The pipe operator nicely separates subsequent operations and allows to
read them in a natural order without the need for temporary variables.
Something like:

      [iv] + secret_blocks |> pairwise |> map, decrypt_block |> \
         reduce, lambda result, block: result.append(block) |> \
         pkcs7_unpad

I'm not sure introducing pipes like this at the Python level would be
a good idea. Is there already a library level support for such
constructs? If not, what would be a good way to express them? I've
tried a bit an figured out a following API
(https://gist.github.com/wrr/5775808):

       Pipe([iv] + secret_blocks)\
        (pairwise)\
        (map, decrypt_block)\
        (reduce, lambda result, block: result.append(block))\
        (pkcs7_unpad)\
        ()

The API is more verbose than the language level operator. I initially
tried to overload `>>`, but it doesn't allow for additional arguments.
It is also somehow smelly, because `()` returns a different type of
value if it is invoked without an argument. Any suggestions how this
could be improved?

Best regards,
Jan
Wolfgang Maier | 13 Jun 2013 10:50

duck typing for io write methods

Dear all,
currently - and referring to Python 3 - the write methods of the different
io module objects work on bytes and str objects only. The built-in functions
print() and bytes(), on the other hand, use an arbitrary object's __str__
and __bytes__ methods to compute the str and bytes they should work with.
Wouldn't it be more consistent and pythonic if the io write methods behaved
the same way?
Best,
Wolfgang
anatoly techtonik | 12 Jun 2013 21:32
Picon
Gravatar

Suprocess functionality partitioning

Something needs to be done about subprocess API, which got overly complicated.

The idea is to have:
  shutil.run()  - run command through shell, unsafe
  sys.run()    - run command directly in operating system, ?safe

Both should be API compatible (unblocking stdin/stdout read etc.).
Currently, subprocess calls are unreadable in any Python code - many
conditions makes its behaviour hard to predict and memorize. By
partitioning shell and out-of-shell execution, the documentation will be
easier to grasp and reference to. Maybe it will be even possible to add
some 2D table of various subprocess states that affect behavior.
--
anatoly t.
_______________________________________________
Python-ideas mailing list
Python-ideas@...
http://mail.python.org/mailman/listinfo/python-ideas
Steven D'Aprano | 11 Jun 2013 18:22

Add \e escape code

Should Python support \e in strings for the ESC control character, ASCII 0x1B (27)?

\e is supported by Perl, PHP, Ruby, and although it is not standard C, gcc:

http://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Character-Escapes.html

I have the Python Pocket Reference, by Mark Lutz, 1st Edition from 1998, which lists \e as a string escape
code. I don't know if that was a mistake, or if \e used to be supported prior to 1.5 but was then removed.

--

-- 
Steven
Ronald Oussoren | 11 Jun 2013 16:54
Picon

Hooks into super()'s __getattribute__

Hi,

Super() currently does not have a way to hook into the behavior of attribute lookup, the __getattribute__
method of super peeks in the __dict__ of types along the MRO until it finds what it is looking for.

That can be a problem when a class implements __getattribute__ and doesn't necessarily store (all)
attributes in the type __dict__.  PyObjC is an example where the current behavior causes problems: PyObjC
defines proxy classes for classes in the Objective-C runtime. The __dict__ of those classes is filled on
demand, whenever a method is called that isn't in the __dict__ yet PyObjC looks in the Objective-C runtime
datastructures for the method and adds it to __dict__. This works fine for normal method resolution, but
can fail with super: super will only return the correct value when the superclass method happens to be in
__dict__ already.  My current solution for this is a custom subclass of super that must be used with Cocoa
subclasses, and that's something I'd like to get rid off.

I'd therefore like to propose adding a slot to PyTypeObject that is called by super's __getattribute__
when present, instead of peeking in the type's tp_dict slot. Does this look like a sane solution? 

I've filed an issue about this that includes a proof of concept patch:
http://bugs.python.org/issue18181. That patch is incomplete, but does make it possible to use the
builtin super for Cocoa classes (with a suitably patched version of PyObjC). 

An earlier issue mentions that the current behavior of super can be inconsistent with the behavior of
__getattribute__, see http://bugs.python.org/issue783528 (that issue is closed, but IMHO for the
wrong reason). I'm appearently not the only one running into this problem ;-)

Ronald
Serhiy Storchaka | 11 Jun 2013 16:49
Picon

Add "htmlcharrefreplace" error handler

I propose to add "htmlcharrefreplace" error handler which is similar to 
"xmlcharrefreplace" error handler but use html entity names if possible.

 >>> '∀ x∈ℜ'.encode('ascii', 'xmlcharrefreplace')
b'∀ x∈ℜ'
 >>> '∀ x∈ℜ'.encode('ascii', 'htmlcharrefreplace')
b'∀ x∈ℜ'

Possible implementation:

import codecs
from html.entities import codepoint2name

def htmlcharrefreplace_errors(exc):
     if not isinstance(exc, UnicodeEncodeError):
         raise exc
     try:
         replace = r'&%s;' % codepoint2name[ord(exc.object[exc.start])]
     except KeyError:
         return codecs.xmlcharrefreplace_errors(exc)
     return replace, exc.start + 1

codecs.register_error('htmlcharrefreplace', htmlcharrefreplace_errors)

Even if do not register this handler from the start, it may be worth to 
provide htmlcharrefreplace_errors() in the html or html.entities module.

_______________________________________________
Python-ideas mailing list
Python-ideas <at> python.org
http://mail.python.org/mailman/listinfo/python-ideas
Serhiy Storchaka | 11 Jun 2013 13:21
Picon

Add "namereplace" error handler

I propose to add "namereplace" error handler which is similar to 
"backslashreplace" error handler but use \N escapes instead of \x/\u/\U 
escapes.

 >>> '−1'.encode('ascii', 'backslashreplace')
b'\\u22121'
 >>> '−1'.encode('ascii', 'namereplace')
b'\\N{MINUS SIGN}1'

In some cases such representation is more readable.

What are you think about this? Are there suggestions for better name?

_______________________________________________
Python-ideas mailing list
Python-ideas <at> python.org
http://mail.python.org/mailman/listinfo/python-ideas
Alexander Belopolsky | 11 Jun 2013 04:28
Picon

Mixed script numbers. Was: Unicode minus sign in numeric conversions

I am changing the subject because the issue of mixing digits from different scripts is quite different from the issue of accepting MINUS SIGN.  I left a comment on the original subject at the issue tracker: <http://bugs.python.org/issue6632#msg190881>.


On Mon, Jun 10, 2013 at 8:53 PM, Steven D'Aprano <steve-iDnA/YwAAsAk+I/owrrOrA@public.gmane.org> wrote:
>
> On 10/06/13 05:35, Alexander Belopolsky wrote:
>>
>> ...  Consider this case:
>>
>>>>> float('123٠95')
>> 123095.0
>>
>> Depending on your font, '123٠95' may be indistinguishable from '123.95'.
>
>
> Indistinguishable *by eye* maybe, but the same applies to ASCII,
> 365lO98, and there are plenty of ways to distinguish them other
> than by a careless glance at the screen.
>
> [Aside: I have seen users type I or O for digits, based on the fact
> that it works fine when using a typewriter, and I've read books from
> the 1970s that recommended that number parsers accept I, L and O
> for just that reason.]

I am not sure why your example is relevant.  There is little harm from accepting O for zero, but accepting it for say 8 would be a different story.

>
> It would be a pretty awful font that made ٠ look like . But even if it did, what is the concern here?
> If somebody enters a mixed script number, presumably they have some reason for it.

Sure, say someone who wants to sell you a $23.95 gadget for $23,095. :-)




_______________________________________________
Python-ideas mailing list
Python-ideas@...
http://mail.python.org/mailman/listinfo/python-ideas
Nick Coghlan | 10 Jun 2013 07:14
Picon
Gravatar

Re: Ordering keyword dicts

(migrating thread from python-dev to python-ideas)

On 10 June 2013 13:13, Alexander Belopolsky
<alexander.belopolsky@...> wrote:
>
> On Sun, May 19, 2013 at 1:47 AM, Guido van Rossum <guido@...> wrote:
>>
>> I'm slow at warming up to the idea. My main concern is speed -- since
>> most code doesn't need it and function calls are already slow (and
>> obviously very common :-) it would be a shame if this slowed down
>> function calls that don't need it noticeably.
>
>
> Here is an idea that will not affect functions that don't need to know the
> order of keywords: a special __kworder__ local variable.  The use of this
> variable inside the function will signal compiler to generate additional
> bytecode to copy keyword names from the stack to a tuple and save it in
> __kworder__.    With that feature, an OrderedDict constructor, for example
> can be written as
>
> def odict(**kwargs):
>       return OrderedDict([(key, kwargs[key]) for key in __kworder__])

The problem is that this is too late to help. To help folks understand
the *technical* (rather than conceptual) limitations that are at issue
in only *sometimes* ordering the keyword arguments here's an overview
of the way the binding of arguments to parameters currently works:

1. In the calling bytecode, the arguments are collected together on
the stack as positional arguments and keyword arguments:

>>> def f():
...     return call(1, 2, *(3, 4), x=1, y=2, **{'z':3})
...
>>> dis(f)
  2           0 LOAD_GLOBAL              0 (call)
              3 LOAD_CONST               1 (1)
              6 LOAD_CONST               2 (2)
              9 LOAD_CONST               3 ('x')
             12 LOAD_CONST               1 (1)
             15 LOAD_CONST               4 ('y')
             18 LOAD_CONST               2 (2)
             21 LOAD_CONST               8 ((3, 4))
             24 BUILD_MAP                1
             27 LOAD_CONST               5 (3)
             30 LOAD_CONST               7 ('z')
             33 STORE_MAP
             34 CALL_FUNCTION_VAR_KW   514 (2 positional, 2 keyword
pair)
             37 RETURN_VALUE

The various "CALL_FUNCTION*" opcodes in CPython almost always end up
passing through a snippet like the following in ceval.c [1,2] (there
are a couple of exceptions related to optimisation of calls that only
involve positional arguments and parameters):

    if (PyCFunction_Check(func)) {
        PyThreadState *tstate = PyThreadState_GET();
        C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
    }
    else
        result = PyObject_Call(func, callargs, kwdict);

[1] http://hg.python.org/cpython/file/default/Python/ceval.c#l4389
[2] http://hg.python.org/cpython/file/default/Python/ceval.c#l4484

You can see a couple of things here:

* That *any* collection of arguments, regardless of syntax, is reduced
to a positional argument tuple and a keyword argument dictionary
before handing it over to the callable to handle the binding of
arguments to parameters.
* That this applies even to the optimised fast path that lets
functions implemented in C avoid some of the overhead associated with
the method dispatch machinery.

2. In the called object, the supplied arguments are bound
appropriately as parameters. There's a lot more variability in how
this happens. C functions usually use PyArg_ParseTuple or
PyArg_ParseTupleAndKeywords. Python functions handle it as an implicit
part of the frame initialization based on the function metadata.

Guido's speed concern is specifically with any approach which requires
the calling code to *always* check callables to see whether they want
an ordered dictionary or not. Before we proceed to considering more
exotic design ideas that require an "ordered or not" decision at the
call sites, this concern should be validated by someone trying it out
and checking the macro benchmark suite for the consequences.

This can be done without actually making it possible to define
functions that require order preservation - since we're mostly
interested in the performance consequences when such a flag *isn't*
set on the callables, an extra redundant check against
"PyCFunction_GET_FLAGS(func) & 0x8000" (for PyCFunction instances),
falling back to something like "PyObject_GetAttrId(__name__)" (for
everything else), for all code paths in ceval.c that lead to creation
of a kwdict instance should suffice.

It may be that the cost of the flag check is swamped by the cost of
actually creating the keyword dictionary, in which case the runtime
check would be a preferable design choice, since function *invocation*
wouldn't need to change, only function declarations.

Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan@...   |   Brisbane, Australia

Gmane