Improve Python tree-shaking

This commit is contained in:
Justine Tunney 2021-09-06 19:24:10 -07:00
parent 5bb2275788
commit 4f41f2184d
169 changed files with 4182 additions and 2411 deletions

Binary file not shown.

View file

@ -631,7 +631,7 @@ static void *__asan_memalign(size_t align, size_t size) {
} }
static void *__asan_malloc(size_t size) { static void *__asan_malloc(size_t size) {
return __asan_memalign(16, size); return __asan_memalign(__BIGGEST_ALIGNMENT__, size);
} }
static void *__asan_calloc(size_t n, size_t m) { static void *__asan_calloc(size_t n, size_t m) {
@ -641,44 +641,64 @@ static void *__asan_calloc(size_t n, size_t m) {
return p; return p;
} }
static void *__asan_realloc(void *p, size_t n) { static void *__asan_realloc_nogrow(void *p, size_t n, size_t m) {
char *q, *f; return 0;
size_t c, m; }
if (p) {
if (n) { static void *__asan_realloc_grow(void *p, size_t n, size_t m) {
if ((c = weaken(dlmalloc_usable_size)(p)) >= 8) { char *q;
f = (char *)p + c - 8; if ((q = __asan_malloc(n))) {
if ((m = READ64BE(f)) <= c) { __asan_memcpy(q, p, m);
if (n <= m) { /* shrink */ __asan_deallocate(p, kAsanRelocated);
__asan_poison((uintptr_t)p + n, m - n, kAsanHeapOverrun);
WRITE64BE(f, n);
q = p;
} else if (n <= c - 8) { /* small growth */
__asan_unpoison((uintptr_t)p + m, n - m);
WRITE64BE(f, n);
q = p;
} else if ((q = __asan_malloc(n))) { /* exponential growth */
__asan_memcpy(q, p, m);
__asan_deallocate(p, kAsanRelocated);
}
} else {
__asan_report_heap_fault(p, m);
}
} else {
__asan_report_heap_fault(p, 0);
}
} else {
__asan_free(p);
q = NULL;
}
} else {
q = __asan_malloc(n);
} }
return q; return q;
} }
static void *__asan_realloc_impl(void *p, size_t n,
void *grow(void *, size_t, size_t)) {
char *f;
size_t c, m;
if ((c = weaken(dlmalloc_usable_size)(p)) >= 8) {
f = (char *)p + c - 8;
if ((m = READ64BE(f)) <= c) {
if (n <= m) { /* shrink */
__asan_poison((uintptr_t)p + n, m - n, kAsanHeapOverrun);
WRITE64BE(f, n);
return p;
} else if (n <= c - 8) { /* small growth */
__asan_unpoison((uintptr_t)p + m, n - m);
WRITE64BE(f, n);
return p;
} else { /* exponential growth */
return grow(p, n, m);
}
} else {
__asan_report_heap_fault(p, m);
}
} else {
__asan_report_heap_fault(p, 0);
}
}
static void *__asan_realloc(void *p, size_t n) {
if (p) {
if (n) {
return __asan_realloc_impl(p, n, __asan_realloc_grow);
} else {
__asan_free(p);
return 0;
}
} else {
return __asan_malloc(n);
}
}
static void *__asan_realloc_in_place(void *p, size_t n) { static void *__asan_realloc_in_place(void *p, size_t n) {
return 0; if (p) {
return __asan_realloc_impl(p, n, __asan_realloc_nogrow);
} else {
return 0;
}
} }
static void *__asan_valloc(size_t n) { static void *__asan_valloc(size_t n) {

View file

@ -16,6 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/bits/bits.h"
#include "libc/dce.h"
#include "libc/intrin/pcmpeqb.h" #include "libc/intrin/pcmpeqb.h"
#include "libc/intrin/pmovmskb.h" #include "libc/intrin/pmovmskb.h"
#include "libc/nexgen32e/bsf.h" #include "libc/nexgen32e/bsf.h"
@ -29,25 +31,116 @@
*/ */
int memcmp(const void *a, const void *b, size_t n) { int memcmp(const void *a, const void *b, size_t n) {
int c; int c;
size_t i; uint64_t w;
unsigned m; unsigned m;
uint8_t *p1, *p2; uint8_t A[16], B[16];
uint8_t v1[16], v2[16]; const uint8_t *p = a, *q = b;
if (n) { if (p == q) return 0;
for (p1 = a, p2 = b, i = 0; i + 16 <= n; i += 16) { if (IsTiny()) {
memcpy(v1, p1 + i, 16); for (; n >= 8; p += 8, q += 8, n -= 8) {
memcpy(v2, p2 + i, 16); w = READ64LE(p) ^ READ64LE(q);
pcmpeqb(v1, v1, v2); if (w) {
if ((m = pmovmskb(v1) - 0xffff)) { m = bsfl(w) >> 3;
i += bsf(m); return p[m] - q[m];
return p1[i] - p2[i];
} }
} }
for (; i < n; ++i) { for (; n; ++p, ++q, --n) {
if ((c = p1[i] - p2[i])) { if ((c = *p - *q)) {
return c; return c;
} }
} }
return 0;
} }
return 0; StartOver:
switch (n) {
case 0:
return 0;
case 1:
return *p - *q;
case 2:
w = (p[0] << 000 | p[1] << 010) ^ (q[0] << 000 | q[1] << 010);
break;
case 3:
w = (p[0] << 000 | p[1] << 010 | p[2] << 020) ^
(q[0] << 000 | q[1] << 010 | q[2] << 020);
break;
case 4:
w = ((uint32_t)p[0] << 000 | (uint32_t)p[1] << 010 |
(uint32_t)p[2] << 020 | (uint32_t)p[3] << 030) ^
((uint32_t)q[0] << 000 | (uint32_t)q[1] << 010 |
(uint32_t)q[2] << 020 | (uint32_t)q[3] << 030);
break;
case 5:
w = ((uint64_t)p[0] << 000 | (uint64_t)p[1] << 010 |
(uint64_t)p[2] << 020 | (uint64_t)p[3] << 030 |
(uint64_t)p[4] << 040) ^
((uint64_t)q[0] << 000 | (uint64_t)q[1] << 010 |
(uint64_t)q[2] << 020 | (uint64_t)q[3] << 030 |
(uint64_t)q[4] << 040);
break;
case 6:
w = ((uint64_t)p[0] << 000 | (uint64_t)p[1] << 010 |
(uint64_t)p[2] << 020 | (uint64_t)p[3] << 030 |
(uint64_t)p[4] << 040 | (uint64_t)p[5] << 050) ^
((uint64_t)q[0] << 000 | (uint64_t)q[1] << 010 |
(uint64_t)q[2] << 020 | (uint64_t)q[3] << 030 |
(uint64_t)q[4] << 040 | (uint64_t)q[5] << 050);
break;
case 7:
w = ((uint64_t)p[0] << 000 | (uint64_t)p[1] << 010 |
(uint64_t)p[2] << 020 | (uint64_t)p[3] << 030 |
(uint64_t)p[4] << 040 | (uint64_t)p[5] << 050 |
(uint64_t)p[6] << 060) ^
((uint64_t)q[0] << 000 | (uint64_t)q[1] << 010 |
(uint64_t)q[2] << 020 | (uint64_t)q[3] << 030 |
(uint64_t)q[4] << 040 | (uint64_t)q[5] << 050 |
(uint64_t)q[6] << 060);
break;
case 8:
w = ((uint64_t)p[0] << 000 | (uint64_t)p[1] << 010 |
(uint64_t)p[2] << 020 | (uint64_t)p[3] << 030 |
(uint64_t)p[4] << 040 | (uint64_t)p[5] << 050 |
(uint64_t)p[6] << 060 | (uint64_t)p[7] << 070) ^
((uint64_t)q[0] << 000 | (uint64_t)q[1] << 010 |
(uint64_t)q[2] << 020 | (uint64_t)q[3] << 030 |
(uint64_t)q[4] << 040 | (uint64_t)q[5] << 050 |
(uint64_t)q[6] << 060 | (uint64_t)q[7] << 070);
break;
default:
for (; n >= 16; p += 16, q += 16, n -= 16) {
memcpy(A, p, 16);
memcpy(B, q, 16);
pcmpeqb(A, A, B);
if ((m = pmovmskb(A) - 0xffff)) {
m = bsf(m);
return p[m] - q[m];
}
}
if (n > 8) {
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
w = ((uint64_t)p[0] << 000 | (uint64_t)p[1] << 010 |
(uint64_t)p[2] << 020 | (uint64_t)p[3] << 030 |
(uint64_t)p[4] << 040 | (uint64_t)p[5] << 050 |
(uint64_t)p[6] << 060 | (uint64_t)p[7] << 070) ^
((uint64_t)q[0] << 000 | (uint64_t)q[1] << 010 |
(uint64_t)q[2] << 020 | (uint64_t)q[3] << 030 |
(uint64_t)q[4] << 040 | (uint64_t)q[5] << 050 |
(uint64_t)q[6] << 060 | (uint64_t)q[7] << 070);
if (w) goto ItsDifferent;
p += 8;
q += 8;
n -= 8;
}
goto StartOver;
}
if (!w) return 0;
ItsDifferent:
m = bsfl(w) >> 3;
return p[m] - q[m];
} }

View file

@ -56,6 +56,7 @@ o/$(MODE)/libc/str/dosdatetimetounix.o: \
OVERRIDE_CFLAGS += \ OVERRIDE_CFLAGS += \
-O3 -O3
o//libc/str/memcmp.o \
o/$(MODE)/libc/str/getzipcdir.o \ o/$(MODE)/libc/str/getzipcdir.o \
o/$(MODE)/libc/str/getzipcdircomment.o \ o/$(MODE)/libc/str/getzipcdircomment.o \
o/$(MODE)/libc/str/getzipcdircommentsize.o \ o/$(MODE)/libc/str/getzipcdircommentsize.o \

View file

@ -0,0 +1,16 @@
#ifndef COSMOPOLITAN_LIBC_TESTLIB_FASTRANDOMSTRING_H_
#define COSMOPOLITAN_LIBC_TESTLIB_FASTRANDOMSTRING_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
static inline const char *FastRandomString(void) {
static unsigned long t;
static union {
unsigned long x;
char b[sizeof(unsigned long)];
} u;
u.x = (t = (t * 0xdeaadead) + 0xdeaadead) & 0x7e7e7e7e7e7e7e;
return u.b;
}
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_TESTLIB_FASTRANDOMSTRING_H_ */

View file

@ -21,6 +21,7 @@ LIBC_TESTLIB_A_HDRS = \
libc/testlib/bench.h \ libc/testlib/bench.h \
libc/testlib/blocktronics.h \ libc/testlib/blocktronics.h \
libc/testlib/ezbench.h \ libc/testlib/ezbench.h \
libc/testlib/fastrandomstring.h \
libc/testlib/hyperion.h \ libc/testlib/hyperion.h \
libc/testlib/moby.h \ libc/testlib/moby.h \
libc/testlib/testlib.h libc/testlib/testlib.h

View file

@ -36,21 +36,29 @@
*/ */
char *(xstrcat)(const char *s, ...) { char *(xstrcat)(const char *s, ...) {
va_list va; va_list va;
size_t n, m; intptr_t q;
char *p, b[2]; char *p, b[2];
p = NULL; size_t n, m, c;
n = 0; n = 0;
c = 32;
p = xmalloc(c);
va_start(va, s); va_start(va, s);
do { do {
if ((intptr_t)s > 0 && (intptr_t)s <= 255) { q = (intptr_t)s;
b[0] = (unsigned char)(intptr_t)s; if (q > 0 && q <= 255) {
b[0] = q;
b[1] = '\0'; b[1] = '\0';
s = b; s = b;
m = 1; m = 1;
} else { } else {
m = strlen(s); m = strlen(s);
} }
p = xrealloc(p, n + m + 1); if (n + m + 1 > c) {
do {
c += c >> 1;
} while (n + m + 1 > c);
p = xrealloc(p, c);
}
memcpy(p + n, s, m + 1); memcpy(p + n, s, m + 1);
n += m; n += m;
} while ((s = va_arg(va, const char *))); } while ((s = va_arg(va, const char *)));

View file

@ -0,0 +1,42 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "libc/runtime/gc.internal.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(realloc_in_place, test) {
char *x = malloc(16);
EXPECT_EQ(x, realloc_in_place(x, 0));
EXPECT_EQ(x, realloc_in_place(x, 1));
*x = 2;
free(x);
}
BENCH(realloc_in_place, bench) {
volatile int i = 1000;
volatile char *x = malloc(i);
EZBENCH2("malloc", donothing, free(malloc(i)));
EZBENCH2("malloc", donothing, free(malloc(i)));
EZBENCH2("memalign", donothing, free(memalign(16, i)));
EZBENCH2("memalign", donothing, free(memalign(32, i)));
EZBENCH2("realloc", donothing, x = realloc(x, --i));
EZBENCH2("realloc_in_place", donothing, realloc_in_place(x, --i));
free(x);
}

View file

@ -44,4 +44,5 @@ TEST(crc32c, test) {
BENCH(crc32c, bench) { BENCH(crc32c, bench) {
EZBENCH2("crc32c", donothing, crc32c(0, kHyperion, kHyperionSize)); EZBENCH2("crc32c", donothing, crc32c(0, kHyperion, kHyperionSize));
EZBENCH2("crc32_z", donothing, crc32_z(0, kHyperion, kHyperionSize));
} }

View file

@ -0,0 +1,74 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/rand/rand.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/fastrandomstring.h"
#include "libc/testlib/testlib.h"
int unfancy_memcmp(const void *a, const void *b, size_t n) {
int c;
size_t i;
const unsigned char *x, *y;
for (x = a, y = b, i = 0; i < n; ++i) {
if ((c = x[i] - y[i])) {
return c;
}
}
return 0;
}
TEST(memcmp, test) {
EXPECT_EQ(0, memcmp("hi", "hi", 2));
EXPECT_NE(0, memcmp("hi", "HI", 2));
EXPECT_EQ(-1, memcmp("a", "b", 1));
EXPECT_EQ(+1, memcmp("b", "a", 1));
}
TEST(memcmp, fuzz) {
int i, n;
char a[32], b[32];
for (i = 0; i < 1000; ++i) {
n = rand() & 31;
rngset(a, n, rand64, -1);
rngset(b, n, rand64, -1);
ASSERT_EQ(unfancy_memcmp(a, b, n), memcmp(a, b, n), "n=%d", n);
}
}
BENCH(memcmp, bench) {
extern int funcmp(const void *a, const void *b, size_t n) asm("memcmp");
volatile int v;
const char *volatile a;
const char *volatile b;
b = a = "123456789123456789123456789123456789123456789123456789";
EZBENCH2("memcmp same", donothing, v = funcmp(a, b, 7));
b = gc(strdup(b));
EZBENCH2("memcmp 1", donothing, v = funcmp(a, b, 1));
EZBENCH2("memcmp 2", donothing, v = funcmp(a, b, 2));
EZBENCH2("memcmp 3", donothing, v = funcmp(a, b, 3));
EZBENCH2("memcmp 4", donothing, v = funcmp(a, b, 4));
EZBENCH2("memcmp 5", donothing, v = funcmp(a, b, 5));
EZBENCH2("memcmp 6", donothing, v = funcmp(a, b, 6));
EZBENCH2("memcmp 7", donothing, v = funcmp(a, b, 7));
EZBENCH2("memcmp 8", donothing, v = funcmp(a, b, 8));
EZBENCH2("memcmp 9", donothing, v = funcmp(a, b, 9));
EZBENCH2("memcmp 16", donothing, v = funcmp(a, b, 16));
EZBENCH2("memcmp 32", donothing, v = funcmp(a, b, 32));
}

View file

@ -17,15 +17,50 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/runtime/gc.internal.h" #include "libc/runtime/gc.internal.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "libc/x/x.h" #include "libc/x/x.h"
TEST(xstrcat, test) { TEST(xstrcat, test) {
EXPECT_STREQ("hi", gc(xstrcat("hi"))); EXPECT_STREQ("hi", gc(xstrcat("hi")));
EXPECT_STREQ("hithere", gc(xstrcat("hi", "there"))); EXPECT_STREQ("hithere", gc(xstrcat("hi", "there")));
EXPECT_STREQ("einszweidrei", gc(xstrcat("eins", "zwei", "drei")));
} }
TEST(xstrcat, pointerAbuse) { TEST(xstrcat, pointerAbuse) {
EXPECT_STREQ("hi there", gc(xstrcat("hi", ' ', "there"))); EXPECT_STREQ("hi there", gc(xstrcat("hi", ' ', "there")));
EXPECT_STREQ("hi there\n", gc(xstrcat("hi", ' ', "there", '\n'))); EXPECT_STREQ("hi there\n", gc(xstrcat("hi", ' ', "there", '\n')));
} }
int hard_static(void) {
char *b, *p;
p = b = malloc(16);
p = stpcpy(p, "eins");
p = stpcpy(p, "zwei");
p = stpcpy(p, "drei");
free(b);
return (intptr_t)b;
}
int hard_dynamic(void) {
char *b, *p;
p = b = malloc(16);
p = stpcpy(p, VEIL("r", "eins"));
p = stpcpy(p, VEIL("r", "zwei"));
p = stpcpy(p, VEIL("r", "drei"));
free(b);
return (intptr_t)b;
}
BENCH(xstrcat, bench) {
EZBENCH2("hard_static", donothing, EXPROPRIATE(hard_static()));
EZBENCH2("hard_dynamic", donothing, EXPROPRIATE(hard_dynamic()));
EZBENCH2("xstrcat", donothing, free(xstrcat("eins", "zwei", "drei")));
EZBENCH2("xasprintf", donothing,
free(xasprintf("%s%s%s", "eins", "zwei", "drei")));
EZBENCH2("xstrcat2", donothing,
free(xstrcat("einseinseins", "zweizweizwei", "dreidreidrei")));
EZBENCH2("xasprintf2", donothing,
free(xasprintf("%s%s%s", "einseinseins", "zweizweizwei",
"dreidreidrei")));
}

View file

@ -16,9 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/bits/bits.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/gc.internal.h" #include "libc/runtime/gc.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/fastrandomstring.h"
#include "libc/testlib/hyperion.h" #include "libc/testlib/hyperion.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "tool/build/lib/interner.h" #include "tool/build/lib/interner.h"
@ -33,6 +37,13 @@ TEST(interner, test) {
EXPECT_EQ(strlen("hi") + 1 + strlen("there") + 1, t->i); EXPECT_EQ(strlen("hi") + 1 + strlen("there") + 1, t->i);
} }
TEST(isinterned, test) {
struct Interner *t = defer(freeinterner, newinterner());
ASSERT_FALSE(isinterned(t, "doge"));
intern(t, "doge");
ASSERT_TRUE(isinterned(t, "doge"));
}
TEST(interner, testWordCount) { TEST(interner, testWordCount) {
struct Interner *t = defer(freeinterner, newinterner()); struct Interner *t = defer(freeinterner, newinterner());
size_t i, j; size_t i, j;
@ -53,3 +64,12 @@ TEST(interner, testWordCount) {
EXPECT_LT(t->i, t->n); EXPECT_LT(t->i, t->n);
EXPECT_EQ('\0', t->p[t->i]); EXPECT_EQ('\0', t->p[t->i]);
} }
BENCH(interner, bench) {
struct Interner *t = defer(freeinterner, newinterner());
intern(t, "hellos");
EZBENCH2("intern hit", donothing, intern(t, "hellos"));
EZBENCH2("intern miss", donothing, intern(t, FastRandomString()));
EZBENCH2("isinterned hit", donothing, isinterned(t, "hellos"));
EZBENCH2("isinterned miss", donothing, isinterned(t, FastRandomString()));
}

View file

@ -19,12 +19,10 @@
#endif #endif
/* hash functions */ /* hash functions */
#define MBEDTLS_MD5_C
#define MBEDTLS_SHA1_C #define MBEDTLS_SHA1_C
#define MBEDTLS_SHA256_C #define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C #define MBEDTLS_SHA512_C
#ifdef MBEDTLS_SSL_PROTO_TLS1
#define MBEDTLS_MD5_C
#endif
/* random numbers */ /* random numbers */
#define ENTROPY_HAVE_STRONG #define ENTROPY_HAVE_STRONG

View file

@ -94,49 +94,78 @@ static const uint8_t supported_digests[] = {
MBEDTLS_MD_NONE MBEDTLS_MD_NONE
}; };
/**
* \brief This function returns the list of digests supported by the
* generic digest module.
*
* \note The list starts with the strongest available hashes.
*
* \return A statically allocated array of digests. Each element
* in the returned list is an integer belonging to the
* message-digest enumeration #mbedtls_md_type_t.
* The last entry is 0.
*/
const uint8_t *mbedtls_md_list( void ) const uint8_t *mbedtls_md_list( void )
{ {
return( supported_digests ); return( supported_digests );
} }
/**
* \brief This function returns the message-digest information
* associated with the given digest name.
*
* \param md_name The name of the digest to search for.
*
* \return The message-digest information associated with \p md_name.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
{ {
if( NULL == md_name ) if( NULL == md_name )
return( NULL ); return( NULL );
/* Get the appropriate digest information */ /* Get the appropriate digest information */
#if defined(MBEDTLS_MD2_C) #if defined(MBEDTLS_MD2_C)
if( !strcmp( "MD2", md_name ) ) if( !strcasecmp( "MD2", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
#endif #endif
#if defined(MBEDTLS_MD4_C) #if defined(MBEDTLS_MD4_C)
if( !strcmp( "MD4", md_name ) ) if( !strcasecmp( "MD4", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
#endif #endif
#if defined(MBEDTLS_MD5_C) #if defined(MBEDTLS_MD5_C)
if( !strcmp( "MD5", md_name ) ) if( !strcasecmp( "MD5", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
#endif #endif
#if defined(MBEDTLS_SHA1_C) #if defined(MBEDTLS_SHA1_C)
if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
#endif #endif
#if defined(MBEDTLS_SHA256_C) #if defined(MBEDTLS_SHA256_C)
if( !strcmp( "SHA224", md_name ) ) if( !strcasecmp( "SHA224", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
if( !strcmp( "SHA256", md_name ) ) if( !strcasecmp( "SHA256", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
#endif #endif
#if defined(MBEDTLS_SHA512_C) #if defined(MBEDTLS_SHA512_C)
#if !defined(MBEDTLS_SHA512_NO_SHA384) #if !defined(MBEDTLS_SHA512_NO_SHA384)
if( !strcmp( "SHA384", md_name ) ) if( !strcasecmp( "SHA384", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
#endif #endif
if( !strcmp( "SHA512", md_name ) ) if( !strcasecmp( "SHA512", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
#endif #endif
return( NULL ); return( NULL );
} }
/**
* \brief This function returns the message-digest information
* associated with the given digest type.
*
* \param md_type The type of digest to search for.
*
* \return The message-digest information associated with \p md_type.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
{ {
switch( md_type ) switch( md_type )
@ -213,11 +242,32 @@ static int16_t GetMdContextSize(mbedtls_md_type_t t)
} }
} }
/**
* \brief This function initializes a message-digest context without
* binding it to a particular message-digest algorithm.
*
* This function should always be called first. It prepares the
* context for mbedtls_md_setup() for binding it to a
* message-digest algorithm.
*/
void mbedtls_md_init( mbedtls_md_context_t *ctx ) void mbedtls_md_init( mbedtls_md_context_t *ctx )
{ {
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
} }
/**
* \brief This function clears the internal structure of \p ctx and
* frees any embedded internal structure, but does not free
* \p ctx itself.
*
* If you have called mbedtls_md_setup() on \p ctx, you must
* call mbedtls_md_free() when you are no longer using the
* context.
* Calling this function if you have previously
* called mbedtls_md_init() and nothing else is optional.
* You must not call this function if you have not called
* mbedtls_md_init().
*/
void mbedtls_md_free( mbedtls_md_context_t *ctx ) void mbedtls_md_free( mbedtls_md_context_t *ctx )
{ {
int16_t csize; int16_t csize;
@ -238,6 +288,25 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx )
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
} }
/**
* \brief This function clones the state of an message-digest
* context.
*
* \note You must call mbedtls_md_setup() on \c dst before calling
* this function.
*
* \note The two contexts must have the same type,
* for example, both are SHA-256.
*
* \warning This function clones the message-digest state, not the
* HMAC state.
*
* \param dst The destination context.
* \param src The context to be cloned.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
*/
int mbedtls_md_clone( mbedtls_md_context_t *dst, int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src ) const mbedtls_md_context_t *src )
{ {
@ -261,6 +330,25 @@ int mbedtls_md_clone( mbedtls_md_context_t *dst,
} \ } \
while( 0 ) while( 0 )
/**
* \brief This function selects the message digest algorithm to use,
* and allocates internal structures.
*
* It should be called after mbedtls_md_init() or
* mbedtls_md_free(). Makes it necessary to call
* mbedtls_md_free() later.
*
* \param ctx The context to set up.
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory),
* or non-zero: HMAC is used with this context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
*/
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
{ {
int16_t csize; int16_t csize;
@ -285,6 +373,23 @@ int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_inf
return( 0 ); return( 0 );
} }
/**
* \brief This function calculates the message-digest checksum
* result of the contents of the provided file.
*
* The result is calculated as
* Output = message_digest(file contents).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param path The input file name.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
* the file pointed by \p path.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
*/
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
{ {
int ret = MBEDTLS_ERR_THIS_CORRUPTION; int ret = MBEDTLS_ERR_THIS_CORRUPTION;
@ -312,6 +417,24 @@ cleanup:
return( ret ); return( ret );
} }
/**
* \brief This function sets the HMAC key and prepares to
* authenticate a new message.
*
* Call this function after mbedtls_md_setup(), to use
* the MD context for an HMAC calculation, then call
* mbedtls_md_hmac_update() to provide the input data, and
* mbedtls_md_hmac_finish() to get the HMAC value.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC key in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
{ {
int ret = MBEDTLS_ERR_THIS_CORRUPTION; int ret = MBEDTLS_ERR_THIS_CORRUPTION;
@ -344,6 +467,24 @@ cleanup:
return( ret ); return( ret );
} }
/**
* \brief This function finishes the HMAC operation, and writes
* the result to the output buffer.
*
* Call this function after mbedtls_md_hmac_starts() and
* mbedtls_md_hmac_update() to get the HMAC value. Afterwards
* you may either call mbedtls_md_free() to clear the context,
* or call mbedtls_md_hmac_reset() to reuse the context with
* the same HMAC key.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param output The generic HMAC checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{ {
int ret = MBEDTLS_ERR_THIS_CORRUPTION; int ret = MBEDTLS_ERR_THIS_CORRUPTION;
@ -361,6 +502,21 @@ cleanup:
return( ret ); return( ret );
} }
/**
* \brief This function prepares to authenticate a new message with
* the same key as the previous HMAC operation.
*
* You may call this function after mbedtls_md_hmac_finish().
* Afterwards call mbedtls_md_hmac_update() to pass the new
* input.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
{ {
int ret = MBEDTLS_ERR_THIS_CORRUPTION; int ret = MBEDTLS_ERR_THIS_CORRUPTION;
@ -373,6 +529,28 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) ); return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
} }
/**
* \brief This function calculates the full generic HMAC
* on the input buffer with the provided key.
*
* The function allocates the context, performs the
* calculation, and frees the context.
*
* The HMAC result is calculated as
* output = generic HMAC(hmac key, input buffer).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC secret key in Bytes.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
* \param output The generic HMAC result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
const unsigned char *key, size_t keylen, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen, const unsigned char *input, size_t ilen,

View file

@ -70,108 +70,13 @@ typedef struct mbedtls_md_context_t {
void *hmac_ctx; /** The HMAC part of the context. */ void *hmac_ctx; /** The HMAC part of the context. */
} mbedtls_md_context_t; } mbedtls_md_context_t;
/** const mbedtls_md_info_t *mbedtls_md_info_from_string( const char * );
* \brief This function returns the list of digests supported by the const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t );
* generic digest module.
*
* \note The list starts with the strongest available hashes.
*
* \return A statically allocated array of digests. Each element
* in the returned list is an integer belonging to the
* message-digest enumeration #mbedtls_md_type_t.
* The last entry is 0.
*/
const uint8_t *mbedtls_md_list( void ); const uint8_t *mbedtls_md_list( void );
int mbedtls_md_clone( mbedtls_md_context_t *, const mbedtls_md_context_t * );
/** int mbedtls_md_setup( mbedtls_md_context_t *, const mbedtls_md_info_t *, int );
* \brief This function returns the message-digest information void mbedtls_md_free( mbedtls_md_context_t * );
* associated with the given digest name. void mbedtls_md_init( mbedtls_md_context_t * );
*
* \param md_name The name of the digest to search for.
*
* \return The message-digest information associated with \p md_name.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
/**
* \brief This function returns the message-digest information
* associated with the given digest type.
*
* \param md_type The type of digest to search for.
*
* \return The message-digest information associated with \p md_type.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
/**
* \brief This function initializes a message-digest context without
* binding it to a particular message-digest algorithm.
*
* This function should always be called first. It prepares the
* context for mbedtls_md_setup() for binding it to a
* message-digest algorithm.
*/
void mbedtls_md_init( mbedtls_md_context_t *ctx );
/**
* \brief This function clears the internal structure of \p ctx and
* frees any embedded internal structure, but does not free
* \p ctx itself.
*
* If you have called mbedtls_md_setup() on \p ctx, you must
* call mbedtls_md_free() when you are no longer using the
* context.
* Calling this function if you have previously
* called mbedtls_md_init() and nothing else is optional.
* You must not call this function if you have not called
* mbedtls_md_init().
*/
void mbedtls_md_free( mbedtls_md_context_t *ctx );
/**
* \brief This function selects the message digest algorithm to use,
* and allocates internal structures.
*
* It should be called after mbedtls_md_init() or
* mbedtls_md_free(). Makes it necessary to call
* mbedtls_md_free() later.
*
* \param ctx The context to set up.
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory),
* or non-zero: HMAC is used with this context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
*/
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/**
* \brief This function clones the state of an message-digest
* context.
*
* \note You must call mbedtls_md_setup() on \c dst before calling
* this function.
*
* \note The two contexts must have the same type,
* for example, both are SHA-256.
*
* \warning This function clones the message-digest state, not the
* HMAC state.
*
* \param dst The destination context.
* \param src The context to be cloned.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
*/
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src );
/** /**
* \brief This function extracts the message-digest size from the * \brief This function extracts the message-digest size from the
@ -189,6 +94,22 @@ forceinline unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info
return md_info->size; return md_info->size;
} }
/**
* \brief This function extracts the message-digest size from the
* message-digest information structure.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The size of the message-digest output in Bytes.
*/
forceinline unsigned char mbedtls_md_get_block_size( const mbedtls_md_info_t *md_info )
{
if( !md_info )
return( 0 );
return md_info->size;
}
/** /**
* \brief This function extracts the message-digest type from the * \brief This function extracts the message-digest type from the
* message-digest information structure. * message-digest information structure.
@ -318,46 +239,11 @@ forceinline int mbedtls_md( const mbedtls_md_info_t *md_info,
return md_info->f_md(input, ilen, output ); return md_info->f_md(input, ilen, output );
} }
/**
* \brief This function calculates the message-digest checksum
* result of the contents of the provided file.
*
* The result is calculated as
* Output = message_digest(file contents).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param path The input file name.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
* the file pointed by \p path.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
*/
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output ); unsigned char *output );
/**
* \brief This function sets the HMAC key and prepares to
* authenticate a new message.
*
* Call this function after mbedtls_md_setup(), to use
* the MD context for an HMAC calculation, then call
* mbedtls_md_hmac_update() to provide the input data, and
* mbedtls_md_hmac_finish() to get the HMAC value.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC key in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen ); size_t keylen );
/** /**
* \brief This function feeds an input buffer into an ongoing HMAC * \brief This function feeds an input buffer into an ongoing HMAC
@ -387,68 +273,9 @@ forceinline int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx,
return( mbedtls_md_update( ctx, input, ilen ) ); return( mbedtls_md_update( ctx, input, ilen ) );
} }
/** int mbedtls_md_hmac_finish( mbedtls_md_context_t *, unsigned char *);
* \brief This function finishes the HMAC operation, and writes int mbedtls_md_hmac_reset( mbedtls_md_context_t * );
* the result to the output buffer. int mbedtls_md_hmac( const mbedtls_md_info_t *, const unsigned char *, size_t, const unsigned char *, size_t, unsigned char * );
*
* Call this function after mbedtls_md_hmac_starts() and
* mbedtls_md_hmac_update() to get the HMAC value. Afterwards
* you may either call mbedtls_md_free() to clear the context,
* or call mbedtls_md_hmac_reset() to reuse the context with
* the same HMAC key.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param output The generic HMAC checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
/**
* \brief This function prepares to authenticate a new message with
* the same key as the previous HMAC operation.
*
* You may call this function after mbedtls_md_hmac_finish().
* Afterwards call mbedtls_md_hmac_update() to pass the new
* input.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
/**
* \brief This function calculates the full generic HMAC
* on the input buffer with the provided key.
*
* The function allocates the context, performs the
* calculation, and frees the context.
*
* The HMAC result is calculated as
* output = generic HMAC(hmac key, input buffer).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC secret key in Bytes.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
* \param output The generic HMAC result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
forceinline int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) forceinline int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
{ {

View file

@ -19,7 +19,33 @@ else:
_setmode = None _setmode = None
import io import io
from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END) from io import (SEEK_SET, SEEK_CUR, SEEK_END)
__all__ = [
'BlockingIOError',
'BufferedIOBase',
'BufferedRWPair',
'BufferedRandom',
'BufferedReader',
'BufferedWriter',
'BytesIO',
'DEFAULT_BUFFER_SIZE',
'FileIO',
'IOBase',
'IncrementalNewlineDecoder',
'OpenWrapper',
'RawIOBase',
'SEEK_CUR',
'SEEK_END',
'SEEK_SET',
'StringIO',
'TextIOBase',
'TextIOWrapper',
'UnsupportedOperation',
'_io',
'abc',
'open',
]
valid_seek_flags = {0, 1, 2} # Hardwired values valid_seek_flags = {0, 1, 2} # Hardwired values
if hasattr(os, 'SEEK_HOLE') : if hasattr(os, 'SEEK_HOLE') :

View file

@ -11,10 +11,7 @@ import builtins, sys
### Registry and builtin stateless codec functions ### Registry and builtin stateless codec functions
try: from _codecs import _forget_codec, ascii_decode, ascii_encode, charmap_build, charmap_decode, charmap_encode, decode, encode, escape_decode, escape_encode, latin_1_decode, latin_1_encode, lookup, lookup_error, raw_unicode_escape_decode, raw_unicode_escape_encode, readbuffer_encode, register, register_error, unicode_escape_decode, unicode_escape_encode, unicode_internal_decode, unicode_internal_encode, utf_16_be_decode, utf_16_be_encode, utf_16_decode, utf_16_encode, utf_16_ex_decode, utf_16_le_decode, utf_16_le_encode, utf_32_be_decode, utf_32_be_encode, utf_32_decode, utf_32_encode, utf_32_ex_decode, utf_32_le_decode, utf_32_le_encode, utf_7_decode, utf_7_encode, utf_8_decode, utf_8_encode
from _codecs import *
except ImportError as why:
raise SystemError('Failed to load the builtin codecs: %s' % why)
__all__ = ["register", "lookup", "open", "EncodedFile", "BOM", "BOM_BE", __all__ = ["register", "lookup", "open", "EncodedFile", "BOM", "BOM_BE",
"BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", "BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE",

View file

@ -15,13 +15,21 @@ list, set, and tuple.
''' '''
__all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',
'UserString', 'Counter', 'OrderedDict', 'ChainMap'] 'UserString', 'Counter', 'OrderedDict', 'ChainMap',
'Awaitable', 'Coroutine',
'AsyncIterable', 'AsyncIterator', 'AsyncGenerator',
'Hashable', 'Iterable', 'Iterator', 'Generator', 'Reversible',
'Sized', 'Container', 'Callable', 'Collection',
'Set', 'MutableSet',
'Mapping', 'MutableMapping',
'MappingView', 'KeysView', 'ItemsView', 'ValuesView',
'Sequence', 'MutableSequence',
'ByteString']
# For backwards compatibility, continue to make the collections ABCs # For backwards compatibility, continue to make the collections ABCs
# available through the collections module. # available through the collections module.
from _collections_abc import * from _collections_abc import ABCMeta, AsyncGenerator, AsyncIterable, AsyncIterator, Awaitable, ByteString, Callable, Collection, Container, Coroutine, Generator, Hashable, ItemsView, Iterable, Iterator, KeysView, Mapping, MappingView, MutableMapping, MutableSequence, MutableSet, Reversible, Sequence, Set, Sized, ValuesView, _check_methods, abstractmethod, async_generator, bytearray_iterator, bytes_iterator, coroutine, dict_itemiterator, dict_items, dict_keyiterator, dict_keys, dict_valueiterator, dict_values, generator, list_iterator, list_reverseiterator, longrange_iterator, mappingproxy, range_iterator, set_iterator, str_iterator, sys, tuple_iterator, zip_iterator
import _collections_abc import _collections_abc
__all__ += _collections_abc.__all__
from operator import itemgetter as _itemgetter, eq as _eq from operator import itemgetter as _itemgetter, eq as _eq
from keyword import iskeyword as _iskeyword from keyword import iskeyword as _iskeyword

View file

@ -1,2 +1,27 @@
from _collections_abc import * from _collections_abc import (
from _collections_abc import __all__ Awaitable,
Coroutine,
AsyncIterable,
AsyncIterator,
AsyncGenerator,
Hashable,
Iterable,
Iterator,
Generator,
Reversible,
Sized,
Container,
Callable,
Collection,
Set,
MutableSet,
Mapping,
MutableMapping,
MappingView,
KeysView,
ItemsView,
ValuesView,
Sequence,
MutableSequence,
ByteString,
)

View file

@ -1,11 +1,10 @@
# try:
try: from _decimal import BasicContext, Clamped, Context, ConversionSyntax, Decimal, DecimalException, DecimalTuple, DefaultContext, DivisionByZero, DivisionImpossible, DivisionUndefined, ExtendedContext, FloatOperation, HAVE_THREADS, Inexact, InvalidContext, InvalidOperation, MAX_EMAX, MAX_PREC, MIN_EMIN, MIN_ETINY, Overflow, ROUND_05UP, ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP, Rounded, Subnormal, Underflow, getcontext, localcontext, setcontext
from _decimal import * from _decimal import __doc__
from _decimal import __doc__ from _decimal import __version__
from _decimal import __version__ from _decimal import __libmpdec_version__
from _decimal import __libmpdec_version__ # except ImportError:
except ImportError: # from _pydecimal import *
from _pydecimal import * # from _pydecimal import __doc__
from _pydecimal import __doc__ # from _pydecimal import __version__
from _pydecimal import __version__ # from _pydecimal import __libmpdec_version__
from _pydecimal import __libmpdec_version__

View file

@ -2090,8 +2090,13 @@ def restore(delta, which):
yield line[2:] yield line[2:]
def _test(): def _test():
import doctest, difflib import sys
return doctest.testmod(difflib) try:
import doctest, difflib
except ImportError:
sys.exit(1)
print(doctest.testmod(difflib))
if __name__ == "__main__": if __name__ == "__main__":
_test() _test()

View file

@ -6,12 +6,13 @@ import collections
import io import io
from opcode import * from opcode import *
from opcode import __all__ as _opcodes_all
__all__ = ["code_info", "dis", "disassemble", "distb", "disco", __all__ = ["code_info", "dis", "disassemble", "distb", "disco",
"findlinestarts", "findlabels", "show_code", "findlinestarts", "findlabels", "show_code",
"get_instructions", "Instruction", "Bytecode"] + _opcodes_all "get_instructions", "Instruction", "Bytecode",
del _opcodes_all "cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
"haslocal", "hascompare", "hasfree", "opname", "opmap",
"HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs", 'stack_effect']
_have_code = (types.MethodType, types.FunctionType, types.CodeType, _have_code = (types.MethodType, types.FunctionType, types.CodeType,
classmethod, staticmethod, type) classmethod, staticmethod, type)

View file

@ -488,7 +488,10 @@ def run_2to3(files, fixer_names=None, options=None, explicit=None):
return return
# Make this class local, to delay import of 2to3 # Make this class local, to delay import of 2to3
from lib2to3.refactor import RefactoringTool, get_fixers_from_package try:
from lib2to3.refactor import RefactoringTool, get_fixers_from_package
except ImportError:
raise
class DistutilsRefactoringTool(RefactoringTool): class DistutilsRefactoringTool(RefactoringTool):
def log_error(self, msg, *args, **kw): def log_error(self, msg, *args, **kw):
log.error(msg, *args) log.error(msg, *args)

View file

@ -76,3 +76,27 @@ finally:
del _dummy_thread del _dummy_thread
del sys_modules del sys_modules
Barrier = Barrier
BoundedSemaphore = BoundedSemaphore
BrokenBarrierError = BrokenBarrierError
Condition = Condition
Event = Event
Lock = Lock
RLock = RLock
Semaphore = Semaphore
TIMEOUT_MAX = TIMEOUT_MAX
Thread = Thread
ThreadError = ThreadError
Timer = Timer
WeakSet = WeakSet
activeCount = activeCount
active_count = active_count
currentThread = currentThread
current_thread = current_thread
get_ident = get_ident
local = local
main_thread = main_thread
setprofile = setprofile
settrace = settrace
stack_size = stack_size

View file

@ -17,6 +17,7 @@ from email import errors
from email._policybase import Policy, compat32 from email._policybase import Policy, compat32
from email import charset as _charset from email import charset as _charset
from email._encoded_words import decode_b from email._encoded_words import decode_b
from email.iterators import walk
Charset = _charset.Charset Charset = _charset.Charset
SEMISPACE = '; ' SEMISPACE = '; '
@ -939,7 +940,6 @@ class Message:
return c_d return c_d
# I.e. def walk(self): ... # I.e. def walk(self): ...
from email.iterators import walk
class MIMEPart(Message): class MIMEPart(Message):

View file

@ -154,16 +154,3 @@ def search_function(encoding):
# Register the search_function in the Python codec registry # Register the search_function in the Python codec registry
codecs.register(search_function) codecs.register(search_function)
if sys.platform == 'win32':
def _alias_mbcs(encoding):
try:
import _bootlocale
if encoding == _bootlocale.getpreferredencoding(False):
import encodings.mbcs
return encodings.mbcs.getregentry()
except ImportError:
# Imports may fail while we are shutting down
pass
codecs.register(_alias_mbcs)

View file

@ -1,205 +0,0 @@
import os
import os.path
import pkgutil
import sys
import tempfile
__all__ = ["version", "bootstrap"]
_SETUPTOOLS_VERSION = "40.6.2"
_PIP_VERSION = "18.1"
_PROJECTS = [
("setuptools", _SETUPTOOLS_VERSION),
("pip", _PIP_VERSION),
]
def _run_pip(args, additional_paths=None):
# Add our bundled software to the sys.path so we can import it
if additional_paths is not None:
sys.path = additional_paths + sys.path
# Install the bundled software
import pip._internal
return pip._internal.main(args)
def version():
"""
Returns a string specifying the bundled version of pip.
"""
return _PIP_VERSION
def _disable_pip_configuration_settings():
# We deliberately ignore all pip environment variables
# when invoking pip
# See http://bugs.python.org/issue19734 for details
keys_to_remove = [k for k in os.environ if k.startswith("PIP_")]
for k in keys_to_remove:
del os.environ[k]
# We also ignore the settings in the default pip configuration file
# See http://bugs.python.org/issue20053 for details
os.environ['PIP_CONFIG_FILE'] = os.devnull
def bootstrap(*, root=None, upgrade=False, user=False,
altinstall=False, default_pip=False,
verbosity=0):
"""
Bootstrap pip into the current Python installation (or the given root
directory).
Note that calling this function will alter both sys.path and os.environ.
"""
# Discard the return value
_bootstrap(root=root, upgrade=upgrade, user=user,
altinstall=altinstall, default_pip=default_pip,
verbosity=verbosity)
def _bootstrap(*, root=None, upgrade=False, user=False,
altinstall=False, default_pip=False,
verbosity=0):
"""
Bootstrap pip into the current Python installation (or the given root
directory). Returns pip command status code.
Note that calling this function will alter both sys.path and os.environ.
"""
if altinstall and default_pip:
raise ValueError("Cannot use altinstall and default_pip together")
_disable_pip_configuration_settings()
# By default, installing pip and setuptools installs all of the
# following scripts (X.Y == running Python version):
#
# pip, pipX, pipX.Y, easy_install, easy_install-X.Y
#
# pip 1.5+ allows ensurepip to request that some of those be left out
if altinstall:
# omit pip, pipX and easy_install
os.environ["ENSUREPIP_OPTIONS"] = "altinstall"
elif not default_pip:
# omit pip and easy_install
os.environ["ENSUREPIP_OPTIONS"] = "install"
with tempfile.TemporaryDirectory() as tmpdir:
# Put our bundled wheels into a temporary directory and construct the
# additional paths that need added to sys.path
additional_paths = []
for project, version in _PROJECTS:
wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version)
whl = pkgutil.get_data(
"ensurepip",
"_bundled/{}".format(wheel_name),
)
with open(os.path.join(tmpdir, wheel_name), "wb") as fp:
fp.write(whl)
additional_paths.append(os.path.join(tmpdir, wheel_name))
# Construct the arguments to be passed to the pip command
args = ["install", "--no-index", "--find-links", tmpdir]
if root:
args += ["--root", root]
if upgrade:
args += ["--upgrade"]
if user:
args += ["--user"]
if verbosity:
args += ["-" + "v" * verbosity]
return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
def _uninstall_helper(*, verbosity=0):
"""Helper to support a clean default uninstall process on Windows
Note that calling this function may alter os.environ.
"""
# Nothing to do if pip was never installed, or has been removed
try:
import pip
except ImportError:
return
# If the pip version doesn't match the bundled one, leave it alone
if pip.__version__ != _PIP_VERSION:
msg = ("ensurepip will only uninstall a matching version "
"({!r} installed, {!r} bundled)")
print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr)
return
_disable_pip_configuration_settings()
# Construct the arguments to be passed to the pip command
args = ["uninstall", "-y", "--disable-pip-version-check"]
if verbosity:
args += ["-" + "v" * verbosity]
return _run_pip(args + [p[0] for p in reversed(_PROJECTS)])
def _main(argv=None):
import argparse
parser = argparse.ArgumentParser(prog="python -m ensurepip")
parser.add_argument(
"--version",
action="version",
version="pip {}".format(version()),
help="Show the version of pip that is bundled with this Python.",
)
parser.add_argument(
"-v", "--verbose",
action="count",
default=0,
dest="verbosity",
help=("Give more output. Option is additive, and can be used up to 3 "
"times."),
)
parser.add_argument(
"-U", "--upgrade",
action="store_true",
default=False,
help="Upgrade pip and dependencies, even if already installed.",
)
parser.add_argument(
"--user",
action="store_true",
default=False,
help="Install using the user scheme.",
)
parser.add_argument(
"--root",
default=None,
help="Install everything relative to this alternate root directory.",
)
parser.add_argument(
"--altinstall",
action="store_true",
default=False,
help=("Make an alternate install, installing only the X.Y versioned "
"scripts (Default: pipX, pipX.Y, easy_install-X.Y)."),
)
parser.add_argument(
"--default-pip",
action="store_true",
default=False,
help=("Make a default pip install, installing the unqualified pip "
"and easy_install in addition to the versioned scripts."),
)
args = parser.parse_args(argv)
return _bootstrap(
root=args.root,
upgrade=args.upgrade,
user=args.user,
verbosity=args.verbosity,
altinstall=args.altinstall,
default_pip=args.default_pip,
)

View file

@ -1,5 +0,0 @@
import ensurepip
import sys
if __name__ == "__main__":
sys.exit(ensurepip._main())

View file

@ -1,31 +0,0 @@
"""Basic pip uninstallation support, helper for the Windows uninstaller"""
import argparse
import ensurepip
import sys
def _main(argv=None):
parser = argparse.ArgumentParser(prog="python -m ensurepip._uninstall")
parser.add_argument(
"--version",
action="version",
version="pip {}".format(ensurepip.version()),
help="Show the version of pip this will attempt to uninstall.",
)
parser.add_argument(
"-v", "--verbose",
action="count",
default=0,
dest="verbosity",
help=("Give more output. Option is additive, and can be used up to 3 "
"times."),
)
args = parser.parse_args(argv)
return ensurepip._uninstall_helper(verbosity=args.verbosity)
if __name__ == "__main__":
sys.exit(_main())

View file

@ -66,7 +66,6 @@ algorithms_available = set(__always_supported)
__all__ = __always_supported + ('new', 'algorithms_guaranteed', __all__ = __always_supported + ('new', 'algorithms_guaranteed',
'algorithms_available', 'pbkdf2_hmac') 'algorithms_available', 'pbkdf2_hmac')
__builtin_constructor_cache = {} __builtin_constructor_cache = {}
def __get_builtin_constructor(name): def __get_builtin_constructor(name):
@ -223,16 +222,20 @@ except ImportError:
pass pass
for __func_name in __always_supported: md5 = __get_hash('md5')
# try them all, some may not work due to the OpenSSL sha1 = __get_hash('sha1')
# version not supporting that algorithm. sha224 = __get_hash('sha224')
try: sha256 = __get_hash('sha256')
globals()[__func_name] = __get_hash(__func_name) sha384 = __get_hash('sha384')
except ValueError: sha512 = __get_hash('sha512')
import logging sha3_224 = __get_hash('sha3_224')
logging.exception('code for hash %s was not found.', __func_name) sha3_256 = __get_hash('sha3_256')
sha3_384 = __get_hash('sha3_384')
sha3_512 = __get_hash('sha3_512')
shake_128 = __get_hash('shake_128')
shake_256 = __get_hash('shake_256')
# Cleanup locals() # Cleanup locals()
del __always_supported, __func_name, __get_hash del __always_supported, __get_hash
del __py_new, __hash_new, __get_openssl_constructor del __py_new, __hash_new, __get_openssl_constructor

View file

@ -600,8 +600,10 @@ try:
except ImportError: except ImportError:
pass pass
if __name__ == "__main__": if __name__ == "__main__":
import sys
import doctest try:
import doctest
except ImportError:
sys.exit(1)
print(doctest.testmod()) print(doctest.testmod())

View file

@ -77,6 +77,7 @@ import re
import socket import socket
import collections import collections
from urllib.parse import urlsplit from urllib.parse import urlsplit
from encodings import idna, iso8859_1
# HTTPMessage, parse_headers(), and the HTTP status code constants are # HTTPMessage, parse_headers(), and the HTTP status code constants are
# intentionally omitted for simplicity # intentionally omitted for simplicity

View file

@ -105,6 +105,7 @@ import copy
import argparse import argparse
from http import HTTPStatus from http import HTTPStatus
from encodings import idna, iso8859_1
# Default error message template # Default error message template

View file

@ -33,7 +33,6 @@ __author__ = ('Ka-Ping Yee <ping@lfw.org>',
import abc import abc
import ast import ast
import dis
import collections.abc import collections.abc
import enum import enum
import importlib.machinery import importlib.machinery
@ -51,11 +50,17 @@ import builtins
from operator import attrgetter from operator import attrgetter
from collections import namedtuple, OrderedDict from collections import namedtuple, OrderedDict
# Create constants for the compiler flags in Include/code.h # dis.COMPILER_FLAG_NAMES
# We try to get them from dis to avoid duplication CO_OPTIMIZED = 1
mod_dict = globals() CO_NEWLOCALS = 2
for k, v in dis.COMPILER_FLAG_NAMES.items(): CO_VARARGS = 4
mod_dict["CO_" + v] = k CO_VARKEYWORDS = 8
CO_NESTED = 16
CO_GENERATOR = 32
CO_NOFREE = 64
CO_COROUTINE = 128
CO_ITERABLE_COROUTINE = 256
CO_ASYNC_GENERATOR = 512
# See Include/object.h # See Include/object.h
TPFLAGS_IS_ABSTRACT = 1 << 20 TPFLAGS_IS_ABSTRACT = 1 << 20
@ -3067,9 +3072,11 @@ def signature(obj, *, follow_wrapped=True):
def _main(): def _main():
""" Logic for inspecting an object given at command line """ """ Logic for inspecting an object given at command line """
import argparse try:
import importlib import argparse
import importlib
except ImportError:
sys.exit(1)
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(
'object', 'object',

View file

@ -19,9 +19,42 @@ from . import context
# Copy stuff from default context # Copy stuff from default context
# #
globals().update((name, getattr(context._default_context, name)) Array = context._default_context.Array
for name in context._default_context.__all__) AuthenticationError = context._default_context.AuthenticationError
__all__ = context._default_context.__all__ Barrier = context._default_context.Barrier
BoundedSemaphore = context._default_context.BoundedSemaphore
BufferTooShort = context._default_context.BufferTooShort
Condition = context._default_context.Condition
Event = context._default_context.Event
JoinableQueue = context._default_context.JoinableQueue
Lock = context._default_context.Lock
Manager = context._default_context.Manager
Pipe = context._default_context.Pipe
Pool = context._default_context.Pool
Process = context._default_context.Process
ProcessError = context._default_context.ProcessError
Queue = context._default_context.Queue
RLock = context._default_context.RLock
RawArray = context._default_context.RawArray
RawValue = context._default_context.RawValue
Semaphore = context._default_context.Semaphore
SimpleQueue = context._default_context.SimpleQueue
TimeoutError = context._default_context.TimeoutError
Value = context._default_context.Value
active_children = context._default_context.active_children
allow_connection_pickling = context._default_context.allow_connection_pickling
cpu_count = context._default_context.cpu_count
current_process = context._default_context.current_process
freeze_support = context._default_context.freeze_support
get_all_start_methods = context._default_context.get_all_start_methods
get_context = context._default_context.get_context
get_logger = context._default_context.get_logger
get_start_method = context._default_context.get_start_method
log_to_stderr = context._default_context.log_to_stderr
reducer = context._default_context.reducer
set_executable = context._default_context.set_executable
set_forkserver_preload = context._default_context.set_forkserver_preload
set_start_method = context._default_context.set_start_method
# #
# XXX These should not really be documented or public. # XXX These should not really be documented or public.

View file

@ -120,23 +120,23 @@ class BaseContext(object):
def RawValue(self, typecode_or_type, *args): def RawValue(self, typecode_or_type, *args):
'''Returns a shared object''' '''Returns a shared object'''
from .sharedctypes import RawValue # from .sharedctypes import RawValue
return RawValue(typecode_or_type, *args) return RawValue(typecode_or_type, *args)
def RawArray(self, typecode_or_type, size_or_initializer): def RawArray(self, typecode_or_type, size_or_initializer):
'''Returns a shared array''' '''Returns a shared array'''
from .sharedctypes import RawArray # from .sharedctypes import RawArray
return RawArray(typecode_or_type, size_or_initializer) return RawArray(typecode_or_type, size_or_initializer)
def Value(self, typecode_or_type, *args, lock=True): def Value(self, typecode_or_type, *args, lock=True):
'''Returns a synchronized shared object''' '''Returns a synchronized shared object'''
from .sharedctypes import Value # from .sharedctypes import Value
return Value(typecode_or_type, *args, lock=lock, return Value(typecode_or_type, *args, lock=lock,
ctx=self.get_context()) ctx=self.get_context())
def Array(self, typecode_or_type, size_or_initializer, *, lock=True): def Array(self, typecode_or_type, size_or_initializer, *, lock=True):
'''Returns a synchronized shared array''' '''Returns a synchronized shared array'''
from .sharedctypes import Array # from .sharedctypes import Array
return Array(typecode_or_type, size_or_initializer, lock=lock, return Array(typecode_or_type, size_or_initializer, lock=lock,
ctx=self.get_context()) ctx=self.get_context())
@ -267,68 +267,48 @@ DefaultContext.__all__ = list(x for x in dir(DefaultContext) if x[0] != '_')
# Context types for fixed start method # Context types for fixed start method
# #
if sys.platform != 'win32': class ForkProcess(process.BaseProcess):
_start_method = 'fork'
@staticmethod
def _Popen(process_obj):
from .popen_fork import Popen
return Popen(process_obj)
class ForkProcess(process.BaseProcess): class SpawnProcess(process.BaseProcess):
_start_method = 'fork' _start_method = 'spawn'
@staticmethod @staticmethod
def _Popen(process_obj): def _Popen(process_obj):
from .popen_fork import Popen from .popen_spawn_posix import Popen
return Popen(process_obj) return Popen(process_obj)
class SpawnProcess(process.BaseProcess): class ForkServerProcess(process.BaseProcess):
_start_method = 'spawn' _start_method = 'forkserver'
@staticmethod @staticmethod
def _Popen(process_obj): def _Popen(process_obj):
from .popen_spawn_posix import Popen from .popen_forkserver import Popen
return Popen(process_obj) return Popen(process_obj)
class ForkServerProcess(process.BaseProcess): class ForkContext(BaseContext):
_start_method = 'forkserver' _name = 'fork'
@staticmethod Process = ForkProcess
def _Popen(process_obj):
from .popen_forkserver import Popen
return Popen(process_obj)
class ForkContext(BaseContext): class SpawnContext(BaseContext):
_name = 'fork' _name = 'spawn'
Process = ForkProcess Process = SpawnProcess
class SpawnContext(BaseContext): class ForkServerContext(BaseContext):
_name = 'spawn' _name = 'forkserver'
Process = SpawnProcess Process = ForkServerProcess
def _check_available(self):
if not reduction.HAVE_SEND_HANDLE:
raise ValueError('forkserver start method not available')
class ForkServerContext(BaseContext): _concrete_contexts = {
_name = 'forkserver' 'fork': ForkContext(),
Process = ForkServerProcess 'spawn': SpawnContext(),
def _check_available(self): 'forkserver': ForkServerContext(),
if not reduction.HAVE_SEND_HANDLE: }
raise ValueError('forkserver start method not available') _default_context = DefaultContext(_concrete_contexts['fork'])
_concrete_contexts = {
'fork': ForkContext(),
'spawn': SpawnContext(),
'forkserver': ForkServerContext(),
}
_default_context = DefaultContext(_concrete_contexts['fork'])
else:
class SpawnProcess(process.BaseProcess):
_start_method = 'spawn'
@staticmethod
def _Popen(process_obj):
from .popen_spawn_win32 import Popen
return Popen(process_obj)
class SpawnContext(BaseContext):
_name = 'spawn'
Process = SpawnProcess
_concrete_contexts = {
'spawn': SpawnContext(),
}
_default_context = DefaultContext(_concrete_contexts['spawn'])
# #
# Force the start method # Force the start method

View file

@ -6,7 +6,7 @@ operate on bytecodes (e.g. peephole optimizers).
__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs", __all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
"haslocal", "hascompare", "hasfree", "opname", "opmap", "haslocal", "hascompare", "hasfree", "opname", "opmap",
"HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"] "HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs", 'stack_effect']
# It's a chicken-and-egg I'm afraid: # It's a chicken-and-egg I'm afraid:
# We're imported before _opcode's made. # We're imported before _opcode's made.
@ -15,14 +15,10 @@ __all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
# Both our chickens and eggs are allayed. # Both our chickens and eggs are allayed.
# --Larry Hastings, 2013/11/23 # --Larry Hastings, 2013/11/23
try: from _opcode import stack_effect
from _opcode import stack_effect
__all__.append('stack_effect')
except ImportError:
pass
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
'is not', 'exception match', 'BAD') 'is not', 'exception match', 'BAD')
hasconst = [] hasconst = []
hasname = [] hasname = []

View file

@ -32,7 +32,7 @@ _names = sys.builtin_module_names
__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
"defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR", "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR",
"SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen", "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen",
"popen", "extsep"] "popen", "extsep", "_exit"]
def _exists(name): def _exists(name):
return name in globals() return name in globals()
@ -45,48 +45,235 @@ def _get_exports_list(module):
# Any new dependencies of the os module and/or changes in path separator # Any new dependencies of the os module and/or changes in path separator
# requires updating importlib as well. # requires updating importlib as well.
if 'posix' in _names: name = 'posix'
name = 'posix' linesep = '\n'
linesep = '\n'
from posix import *
try:
from posix import _exit
__all__.append('_exit')
except ImportError:
pass
import posixpath as path
try: import posixpath as path
from posix import _have_functions import posix
except ImportError:
pass
import posix CLD_CONTINUED = posix.CLD_CONTINUED
__all__.extend(_get_exports_list(posix)) CLD_DUMPED = posix.CLD_DUMPED
del posix CLD_EXITED = posix.CLD_EXITED
CLD_TRAPPED = posix.CLD_TRAPPED
DirEntry = posix.DirEntry
EX_CANTCREAT = posix.EX_CANTCREAT
EX_CONFIG = posix.EX_CONFIG
EX_DATAERR = posix.EX_DATAERR
EX_IOERR = posix.EX_IOERR
EX_NOHOST = posix.EX_NOHOST
EX_NOINPUT = posix.EX_NOINPUT
EX_NOPERM = posix.EX_NOPERM
EX_NOUSER = posix.EX_NOUSER
EX_OK = posix.EX_OK
EX_OSERR = posix.EX_OSERR
EX_OSFILE = posix.EX_OSFILE
EX_PROTOCOL = posix.EX_PROTOCOL
EX_SOFTWARE = posix.EX_SOFTWARE
EX_TEMPFAIL = posix.EX_TEMPFAIL
EX_UNAVAILABLE = posix.EX_UNAVAILABLE
EX_USAGE = posix.EX_USAGE
F_LOCK = posix.F_LOCK
F_OK = posix.F_OK
F_TEST = posix.F_TEST
F_TLOCK = posix.F_TLOCK
F_ULOCK = posix.F_ULOCK
GRND_NONBLOCK = posix.GRND_NONBLOCK
GRND_NORDRND = posix.GRND_NORDRND
GRND_NOSYSTEM = posix.GRND_NOSYSTEM
GRND_RANDOM = posix.GRND_RANDOM
O_ACCMODE = posix.O_ACCMODE
O_APPEND = posix.O_APPEND
O_ASYNC = posix.O_ASYNC
O_CLOEXEC = posix.O_CLOEXEC
O_CREAT = posix.O_CREAT
O_DIRECT = posix.O_DIRECT
O_DIRECTORY = posix.O_DIRECTORY
O_DSYNC = posix.O_DSYNC
O_EXCL = posix.O_EXCL
O_LARGEFILE = posix.O_LARGEFILE
O_NDELAY = posix.O_NDELAY
O_NOATIME = posix.O_NOATIME
O_NOCTTY = posix.O_NOCTTY
O_NOFOLLOW = posix.O_NOFOLLOW
O_NONBLOCK = posix.O_NONBLOCK
O_PATH = posix.O_PATH
O_RDONLY = posix.O_RDONLY
O_RDWR = posix.O_RDWR
O_RSYNC = posix.O_RSYNC
O_SYNC = posix.O_SYNC
O_TMPFILE = posix.O_TMPFILE
O_TRUNC = posix.O_TRUNC
O_WRONLY = posix.O_WRONLY
POSIX_FADV_DONTNEED = posix.POSIX_FADV_DONTNEED
POSIX_FADV_NOREUSE = posix.POSIX_FADV_NOREUSE
POSIX_FADV_NORMAL = posix.POSIX_FADV_NORMAL
POSIX_FADV_RANDOM = posix.POSIX_FADV_RANDOM
POSIX_FADV_SEQUENTIAL = posix.POSIX_FADV_SEQUENTIAL
POSIX_FADV_WILLNEED = posix.POSIX_FADV_WILLNEED
PRIO_PGRP = posix.PRIO_PGRP
PRIO_PROCESS = posix.PRIO_PROCESS
PRIO_USER = posix.PRIO_USER
RTLD_GLOBAL = posix.RTLD_GLOBAL
RTLD_LAZY = posix.RTLD_LAZY
RTLD_LOCAL = posix.RTLD_LOCAL
RTLD_NOW = posix.RTLD_NOW
R_OK = posix.R_OK
SCHED_BATCH = posix.SCHED_BATCH
SCHED_FIFO = posix.SCHED_FIFO
SCHED_IDLE = posix.SCHED_IDLE
SCHED_OTHER = posix.SCHED_OTHER
SCHED_RESET_ON_FORK = posix.SCHED_RESET_ON_FORK
SCHED_RR = posix.SCHED_RR
ST_APPEND = posix.ST_APPEND
ST_MANDLOCK = posix.ST_MANDLOCK
ST_NOATIME = posix.ST_NOATIME
ST_NODEV = posix.ST_NODEV
ST_NODIRATIME = posix.ST_NODIRATIME
ST_NOEXEC = posix.ST_NOEXEC
ST_NOSUID = posix.ST_NOSUID
ST_RDONLY = posix.ST_RDONLY
ST_RELATIME = posix.ST_RELATIME
ST_SYNCHRONOUS = posix.ST_SYNCHRONOUS
ST_WRITE = posix.ST_WRITE
WCONTINUED = posix.WCONTINUED
WCOREDUMP = posix.WCOREDUMP
WEXITED = posix.WEXITED
WEXITSTATUS = posix.WEXITSTATUS
WIFCONTINUED = posix.WIFCONTINUED
WIFEXITED = posix.WIFEXITED
WIFSIGNALED = posix.WIFSIGNALED
WIFSTOPPED = posix.WIFSTOPPED
WNOHANG = posix.WNOHANG
WNOWAIT = posix.WNOWAIT
WSTOPPED = posix.WSTOPPED
WSTOPSIG = posix.WSTOPSIG
WTERMSIG = posix.WTERMSIG
WUNTRACED = posix.WUNTRACED
W_OK = posix.W_OK
X_OK = posix.X_OK
_exit = posix._exit
_have_functions = posix._have_functions
abort = posix.abort
access = posix.access
chdir = posix.chdir
chmod = posix.chmod
chown = posix.chown
chroot = posix.chroot
close = posix.close
closerange = posix.closerange
cpu_count = posix.cpu_count
device_encoding = posix.device_encoding
dup = posix.dup
dup2 = posix.dup2
environ = posix.environ
error = posix.error
execv = posix.execv
execve = posix.execve
fchdir = posix.fchdir
fchmod = posix.fchmod
fchown = posix.fchown
fdatasync = posix.fdatasync
fork = posix.fork
fpathconf = posix.fpathconf
fspath = posix.fspath
fstat = posix.fstat
fsync = posix.fsync
ftruncate = posix.ftruncate
get_blocking = posix.get_blocking
get_inheritable = posix.get_inheritable
get_terminal_size = posix.get_terminal_size
getcwd = posix.getcwd
getcwdb = posix.getcwdb
getgrouplist = posix.getgrouplist
getgroups = posix.getgroups
getlogin = posix.getlogin
getpgid = posix.getpgid
getpgrp = posix.getpgrp
getpid = posix.getpid
getpriority = posix.getpriority
getsid = posix.getsid
getuid = posix.getuid
initgroups = posix.initgroups
isatty = posix.isatty
kill = posix.kill
killpg = posix.killpg
lchown = posix.lchown
link = posix.link
listdir = posix.listdir
lseek = posix.lseek
lstat = posix.lstat
major = posix.major
makedev = posix.makedev
minor = posix.minor
mkdir = posix.mkdir
mkfifo = posix.mkfifo
mknod = posix.mknod
nice = posix.nice
open = posix.open
openpty = posix.openpty
pathconf = posix.pathconf
pathconf_names = posix.pathconf_names
pipe = posix.pipe
pipe2 = posix.pipe2
posix_fadvise = posix.posix_fadvise
pread = posix.pread
putenv = posix.putenv
pwrite = posix.pwrite
read = posix.read
readlink = posix.readlink
readv = posix.readv
remove = posix.remove
rename = posix.rename
replace = posix.replace
rmdir = posix.rmdir
scandir = posix.scandir
sched_yield = posix.sched_yield
sendfile = posix.sendfile
set_blocking = posix.set_blocking
set_inheritable = posix.set_inheritable
setegid = posix.setegid
seteuid = posix.seteuid
setgid = posix.setgid
setpgid = posix.setpgid
setpriority = posix.setpriority
setregid = posix.setregid
setresgid = posix.setresgid
setresuid = posix.setresuid
setreuid = posix.setreuid
setsid = posix.setsid
setuid = posix.setuid
stat = posix.stat
stat_float_times = posix.stat_float_times
stat_result = posix.stat_result
statvfs_result = posix.statvfs_result
strerror = posix.strerror
symlink = posix.symlink
sync = posix.sync
sysconf = posix.sysconf
sysconf_names = posix.sysconf_names
system = posix.system
tcgetpgrp = posix.tcgetpgrp
tcsetpgrp = posix.tcsetpgrp
terminal_size = posix.terminal_size
times = posix.times
times_result = posix.times_result
truncate = posix.truncate
umask = posix.umask
uname = posix.uname
uname_result = posix.uname_result
unlink = posix.unlink
unsetenv = posix.unsetenv
urandom = posix.urandom
utime = posix.utime
wait = posix.wait
wait3 = posix.wait3
wait4 = posix.wait4
waitpid = posix.waitpid
write = posix.write
writev = posix.writev
elif 'nt' in _names: __all__.extend(_get_exports_list(posix))
name = 'nt' del posix
linesep = '\r\n'
from nt import *
try:
from nt import _exit
__all__.append('_exit')
except ImportError:
pass
import ntpath as path
import nt
__all__.extend(_get_exports_list(nt))
del nt
try:
from nt import _have_functions
except ImportError:
pass
else:
raise ImportError('no os specific module found')
sys.modules['os.path'] = path sys.modules['os.path'] = path
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
@ -95,91 +282,90 @@ from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
del _names del _names
if _exists("_have_functions"): _globals = globals()
_globals = globals() def _add(str, fn):
def _add(str, fn): if (fn in _globals) and (str in _have_functions):
if (fn in _globals) and (str in _have_functions): _set.add(_globals[fn])
_set.add(_globals[fn])
_set = set() _set = set()
_add("HAVE_FACCESSAT", "access") _add("HAVE_FACCESSAT", "access")
_add("HAVE_FCHMODAT", "chmod") _add("HAVE_FCHMODAT", "chmod")
_add("HAVE_FCHOWNAT", "chown") _add("HAVE_FCHOWNAT", "chown")
_add("HAVE_FSTATAT", "stat") _add("HAVE_FSTATAT", "stat")
_add("HAVE_FUTIMESAT", "utime") _add("HAVE_FUTIMESAT", "utime")
_add("HAVE_LINKAT", "link") _add("HAVE_LINKAT", "link")
_add("HAVE_MKDIRAT", "mkdir") _add("HAVE_MKDIRAT", "mkdir")
_add("HAVE_MKFIFOAT", "mkfifo") _add("HAVE_MKFIFOAT", "mkfifo")
_add("HAVE_MKNODAT", "mknod") _add("HAVE_MKNODAT", "mknod")
_add("HAVE_OPENAT", "open") _add("HAVE_OPENAT", "open")
_add("HAVE_READLINKAT", "readlink") _add("HAVE_READLINKAT", "readlink")
_add("HAVE_RENAMEAT", "rename") _add("HAVE_RENAMEAT", "rename")
_add("HAVE_SYMLINKAT", "symlink") _add("HAVE_SYMLINKAT", "symlink")
_add("HAVE_UNLINKAT", "unlink") _add("HAVE_UNLINKAT", "unlink")
_add("HAVE_UNLINKAT", "rmdir") _add("HAVE_UNLINKAT", "rmdir")
_add("HAVE_UTIMENSAT", "utime") _add("HAVE_UTIMENSAT", "utime")
supports_dir_fd = _set supports_dir_fd = _set
_set = set() _set = set()
_add("HAVE_FACCESSAT", "access") _add("HAVE_FACCESSAT", "access")
supports_effective_ids = _set supports_effective_ids = _set
_set = set() _set = set()
_add("HAVE_FCHDIR", "chdir") _add("HAVE_FCHDIR", "chdir")
_add("HAVE_FCHMOD", "chmod") _add("HAVE_FCHMOD", "chmod")
_add("HAVE_FCHOWN", "chown") _add("HAVE_FCHOWN", "chown")
_add("HAVE_FDOPENDIR", "listdir") _add("HAVE_FDOPENDIR", "listdir")
_add("HAVE_FEXECVE", "execve") _add("HAVE_FEXECVE", "execve")
_set.add(stat) # fstat always works _set.add(stat) # fstat always works
_add("HAVE_FTRUNCATE", "truncate") _add("HAVE_FTRUNCATE", "truncate")
_add("HAVE_FUTIMENS", "utime") _add("HAVE_FUTIMENS", "utime")
_add("HAVE_FUTIMES", "utime") _add("HAVE_FUTIMES", "utime")
_add("HAVE_FPATHCONF", "pathconf") _add("HAVE_FPATHCONF", "pathconf")
if _exists("statvfs") and _exists("fstatvfs"): # mac os x10.3 if _exists("statvfs") and _exists("fstatvfs"): # mac os x10.3
_add("HAVE_FSTATVFS", "statvfs") _add("HAVE_FSTATVFS", "statvfs")
supports_fd = _set supports_fd = _set
_set = set() _set = set()
_add("HAVE_FACCESSAT", "access") _add("HAVE_FACCESSAT", "access")
# Some platforms don't support lchmod(). Often the function exists # Some platforms don't support lchmod(). Often the function exists
# anyway, as a stub that always returns ENOSUP or perhaps EOPNOTSUPP. # anyway, as a stub that always returns ENOSUP or perhaps EOPNOTSUPP.
# (No, I don't know why that's a good design.) ./configure will detect # (No, I don't know why that's a good design.) ./configure will detect
# this and reject it--so HAVE_LCHMOD still won't be defined on such # this and reject it--so HAVE_LCHMOD still won't be defined on such
# platforms. This is Very Helpful. # platforms. This is Very Helpful.
# #
# However, sometimes platforms without a working lchmod() *do* have # However, sometimes platforms without a working lchmod() *do* have
# fchmodat(). (Examples: Linux kernel 3.2 with glibc 2.15, # fchmodat(). (Examples: Linux kernel 3.2 with glibc 2.15,
# OpenIndiana 3.x.) And fchmodat() has a flag that theoretically makes # OpenIndiana 3.x.) And fchmodat() has a flag that theoretically makes
# it behave like lchmod(). So in theory it would be a suitable # it behave like lchmod(). So in theory it would be a suitable
# replacement for lchmod(). But when lchmod() doesn't work, fchmodat()'s # replacement for lchmod(). But when lchmod() doesn't work, fchmodat()'s
# flag doesn't work *either*. Sadly ./configure isn't sophisticated # flag doesn't work *either*. Sadly ./configure isn't sophisticated
# enough to detect this condition--it only determines whether or not # enough to detect this condition--it only determines whether or not
# fchmodat() minimally works. # fchmodat() minimally works.
# #
# Therefore we simply ignore fchmodat() when deciding whether or not # Therefore we simply ignore fchmodat() when deciding whether or not
# os.chmod supports follow_symlinks. Just checking lchmod() is # os.chmod supports follow_symlinks. Just checking lchmod() is
# sufficient. After all--if you have a working fchmodat(), your # sufficient. After all--if you have a working fchmodat(), your
# lchmod() almost certainly works too. # lchmod() almost certainly works too.
# #
# _add("HAVE_FCHMODAT", "chmod") # _add("HAVE_FCHMODAT", "chmod")
_add("HAVE_FCHOWNAT", "chown") _add("HAVE_FCHOWNAT", "chown")
_add("HAVE_FSTATAT", "stat") _add("HAVE_FSTATAT", "stat")
_add("HAVE_LCHFLAGS", "chflags") _add("HAVE_LCHFLAGS", "chflags")
_add("HAVE_LCHMOD", "chmod") _add("HAVE_LCHMOD", "chmod")
if _exists("lchown"): # mac os x10.3 if _exists("lchown"): # mac os x10.3
_add("HAVE_LCHOWN", "chown") _add("HAVE_LCHOWN", "chown")
_add("HAVE_LINKAT", "link") _add("HAVE_LINKAT", "link")
_add("HAVE_LUTIMES", "utime") _add("HAVE_LUTIMES", "utime")
_add("HAVE_LSTAT", "stat") _add("HAVE_LSTAT", "stat")
_add("HAVE_FSTATAT", "stat") _add("HAVE_FSTATAT", "stat")
_add("HAVE_UTIMENSAT", "utime") _add("HAVE_UTIMENSAT", "utime")
_add("MS_WINDOWS", "stat") _add("MS_WINDOWS", "stat")
supports_follow_symlinks = _set supports_follow_symlinks = _set
del _set del _set
del _have_functions del _have_functions
del _globals del _globals
del _add del _add
# Python uses fixed values for the SEEK_ constants; they are mapped # Python uses fixed values for the SEEK_ constants; they are mapped

View file

@ -1576,8 +1576,12 @@ except ImportError:
# Doctest # Doctest
def _test(): def _test():
import doctest import sys
return doctest.testmod() try:
import doctest
except ImportError:
sys.exit(1)
print(doctest.testmod())
if __name__ == "__main__": if __name__ == "__main__":
import argparse import argparse

View file

@ -2786,8 +2786,12 @@ __test__ = {'disassembler_test': _dis_test,
} }
def _test(): def _test():
import doctest import sys
return doctest.testmod() try:
import doctest
except ImportError:
sys.exit(1)
print(doctest.testmod())
if __name__ == "__main__": if __name__ == "__main__":
import argparse import argparse

View file

@ -535,10 +535,10 @@ def win32_ver(release='', version='', csd='', ptype=''):
from sys import getwindowsversion from sys import getwindowsversion
except ImportError: except ImportError:
return release, version, csd, ptype return release, version, csd, ptype
try: # try:
from winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE # from winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE
except ImportError: # except ImportError:
from _winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE # from _winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE
winver = getwindowsversion() winver = getwindowsversion()
maj, min, build = winver.platform_version or winver[:3] maj, min, build = winver.platform_version or winver[:3]
@ -621,7 +621,7 @@ def mac_ver(release='', versioninfo=('', '', ''), machine=''):
def _java_getprop(name, default): def _java_getprop(name, default):
from java.lang import System # from java.lang import System
try: try:
value = System.getProperty(name) value = System.getProperty(name)
if value is None: if value is None:

View file

@ -158,7 +158,24 @@ class RegexFlag(enum.IntFlag):
TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking
T = TEMPLATE T = TEMPLATE
DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation
globals().update(RegexFlag.__members__)
ASCII = RegexFlag.ASCII
IGNORECASE = RegexFlag.IGNORECASE
LOCALE = RegexFlag.LOCALE
UNICODE = RegexFlag.UNICODE
MULTILINE = RegexFlag.MULTILINE
DOTALL = RegexFlag.DOTALL
VERBOSE = RegexFlag.VERBOSE
A = RegexFlag.A
I = RegexFlag.I
L = RegexFlag.L
U = RegexFlag.U
M = RegexFlag.M
S = RegexFlag.S
X = RegexFlag.X
TEMPLATE = RegexFlag.TEMPLATE
T = RegexFlag.T
DEBUG = RegexFlag.DEBUG
# sre exception # sre exception
error = sre_compile.error error = sre_compile.error

View file

@ -223,7 +223,7 @@ class DbfilenameShelf(Shelf):
""" """
def __init__(self, filename, flag='c', protocol=None, writeback=False): def __init__(self, filename, flag='c', protocol=None, writeback=False):
import dbm # import dbm
Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback) Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)

View file

@ -350,7 +350,8 @@ def setcopyright():
builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright) builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright)
builtins.credits = _sitebuiltins._Printer("credits", """\ builtins.credits = _sitebuiltins._Printer("credits", """\
Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
for supporting Python development. See www.python.org for more information.""") for supporting Python development. See www.python.org for more information.
Thanks go to github.com/ahgamut for porting Python to Cosmopolitan Libc.""")
files, dirs = [], [] files, dirs = [], []
# Not all modules are required to have a __file__ attribute. See # Not all modules are required to have a __file__ attribute. See
# PEP 420 for more details. # PEP 420 for more details.
@ -377,8 +378,8 @@ def enablerlcompleter():
or in a PYTHONSTARTUP file. or in a PYTHONSTARTUP file.
""" """
def register_readline(): def register_readline():
import atexit
try: try:
import atexit
import readline import readline
import rlcompleter import rlcompleter
except ImportError: except ImportError:
@ -592,8 +593,11 @@ def _script():
else: else:
sys.exit(3) sys.exit(3)
else: else:
import textwrap try:
print(textwrap.dedent(help % (sys.argv[0], os.pathsep))) import textwrap
print(textwrap.dedent(help % (sys.argv[0], os.pathsep)))
except ImportError:
pass
sys.exit(10) sys.exit(10)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -785,9 +785,9 @@ class MailmanProxy(PureProxy):
def process_message(self, peer, mailfrom, rcpttos, data): def process_message(self, peer, mailfrom, rcpttos, data):
from io import StringIO from io import StringIO
from Mailman import Utils # from Mailman import Utils
from Mailman import Message # from Mailman import Message
from Mailman import MailList # from Mailman import MailList
# If the message is to a Mailman mailing list, then we'll invoke the # If the message is to a Mailman mailing list, then we'll invoke the
# Mailman script directly, without going through the real smtpd. # Mailman script directly, without going through the real smtpd.
# Otherwise we'll forward it to the local proxy for disposition. # Otherwise we'll forward it to the local proxy for disposition.

View file

@ -47,7 +47,7 @@ the setsockopt() and getsockopt() methods.
""" """
import _socket import _socket
from _socket import * from _socket import AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BRIDGE, AF_CAN, AF_ECONET, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_KEY, AF_LLC, AF_NETBEUI, AF_NETROM, AF_PACKET, AF_PPPOX, AF_RDS, AF_ROSE, AF_ROUTE, AF_SECURITY, AF_SNA, AF_UNIX, AF_UNSPEC, AF_X25, AI_ADDRCONFIG, AI_ALL, AI_CANONNAME, AI_NUMERICHOST, AI_NUMERICSERV, AI_PASSIVE, AI_V4MAPPED, CAPI, EAI_ADDRFAMILY, EAI_AGAIN, EAI_BADFLAGS, EAI_FAIL, EAI_FAMILY, EAI_MEMORY, EAI_NODATA, EAI_NONAME, EAI_OVERFLOW, EAI_SERVICE, EAI_SOCKTYPE, EAI_SYSTEM, INADDR_ALLHOSTS_GROUP, INADDR_ANY, INADDR_BROADCAST, INADDR_LOOPBACK, INADDR_MAX_LOCAL_GROUP, INADDR_NONE, INADDR_UNSPEC_GROUP, IPPORT_RESERVED, IPPORT_USERRESERVED, IPPROTO_AH, IPPROTO_DSTOPTS, IPPROTO_EGP, IPPROTO_ESP, IPPROTO_FRAGMENT, IPPROTO_GRE, IPPROTO_HOPOPTS, IPPROTO_ICMP, IPPROTO_ICMPV6, IPPROTO_IDP, IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IPIP, IPPROTO_IPV6, IPPROTO_MAX, IPPROTO_NONE, IPPROTO_PIM, IPPROTO_PUP, IPPROTO_RAW, IPPROTO_ROUTING, IPPROTO_RSVP, IPPROTO_SCTP, IPPROTO_TCP, IPPROTO_TP, IPPROTO_UDP, IP_ADD_MEMBERSHIP, IP_DEFAULT_MULTICAST_LOOP, IP_DEFAULT_MULTICAST_TTL, IP_DROP_MEMBERSHIP, IP_HDRINCL, IP_MAX_MEMBERSHIPS, IP_MULTICAST_IF, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_OPTIONS, IP_RECVOPTS, IP_RECVRETOPTS, IP_RETOPTS, IP_TOS, IP_TRANSPARENT, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_CTRUNC, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOF, MSG_EOR, MSG_ERRQUEUE, MSG_FASTOPEN, MSG_MORE, MSG_NOSIGNAL, MSG_NOTIFICATION, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, NI_DGRAM, NI_MAXHOST, NI_MAXSERV, NI_NAMEREQD, NI_NOFQDN, NI_NUMERICHOST, NI_NUMERICSERV, PF_CAN, PF_PACKET, PF_RDS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_CLOEXEC, SOCK_DGRAM, SOCK_NONBLOCK, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_STREAM, SOL_IP, SOL_RDS, SOL_SOCKET, SOL_TCP, SOL_UDP, SOMAXCONN, SO_ACCEPTCONN, SO_BINDTODEVICE, SO_BROADCAST, SO_DEBUG, SO_DOMAIN, SO_DONTROUTE, SO_ERROR, SO_KEEPALIVE, SO_LINGER, SO_MARK, SO_OOBINLINE, SO_PASSCRED, SO_PASSSEC, SO_PEERCRED, SO_PEERSEC, SO_PRIORITY, SO_PROTOCOL, SO_RCVBUF, SO_RCVLOWAT, SO_RCVTIMEO, SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, SO_SNDLOWAT, SO_SNDTIMEO, SO_TYPE, SocketType, TCP_CONGESTION, TCP_CORK, TCP_DEFER_ACCEPT, TCP_FASTOPEN, TCP_FASTOPEN_CONNECT, TCP_INFO, TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_LINGER2, TCP_MAXSEG, TCP_NODELAY, TCP_QUICKACK, TCP_SAVED_SYN, TCP_SAVE_SYN, TCP_SYNCNT, TCP_USER_TIMEOUT, TCP_WINDOW_CLAMP, dup, error, gaierror, getaddrinfo, getdefaulttimeout, gethostbyaddr, gethostbyname, gethostbyname_ex, gethostname, getnameinfo, getprotobyname, getservbyname, getservbyport, has_ipv6, herror, htonl, htons, inet_aton, inet_ntoa, inet_ntop, inet_pton, ntohl, ntohs, setdefaulttimeout, sethostname, socket, socketpair, timeout
import os, sys, io, selectors import os, sys, io, selectors
from enum import IntEnum, IntFlag from enum import IntEnum, IntFlag

View file

@ -64,67 +64,145 @@ class _NamedIntConstant(int):
MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT') MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT')
def _makecodes(names): FAILURE = _NamedIntConstant(0, 'FAILURE')
names = names.strip().split() SUCCESS = _NamedIntConstant(1, 'SUCCESS')
items = [_NamedIntConstant(i, name) for i, name in enumerate(names)] ANY = _NamedIntConstant(2, 'ANY')
globals().update({item.name: item for item in items}) ANY_ALL = _NamedIntConstant(3, 'ANY_ALL')
return items ASSERT = _NamedIntConstant(4, 'ASSERT')
ASSERT_NOT = _NamedIntConstant(5, 'ASSERT_NOT')
AT = _NamedIntConstant(6, 'AT')
BRANCH = _NamedIntConstant(7, 'BRANCH')
CALL = _NamedIntConstant(8, 'CALL')
CATEGORY = _NamedIntConstant(9, 'CATEGORY')
CHARSET = _NamedIntConstant(10, 'CHARSET')
BIGCHARSET = _NamedIntConstant(11, 'BIGCHARSET')
GROUPREF = _NamedIntConstant(12, 'GROUPREF')
GROUPREF_EXISTS = _NamedIntConstant(13, 'GROUPREF_EXISTS')
GROUPREF_IGNORE = _NamedIntConstant(14, 'GROUPREF_IGNORE')
IN = _NamedIntConstant(15, 'IN')
IN_IGNORE = _NamedIntConstant(16, 'IN_IGNORE')
INFO = _NamedIntConstant(17, 'INFO')
JUMP = _NamedIntConstant(18, 'JUMP')
LITERAL = _NamedIntConstant(19, 'LITERAL')
LITERAL_IGNORE = _NamedIntConstant(20, 'LITERAL_IGNORE')
MARK = _NamedIntConstant(21, 'MARK')
MAX_UNTIL = _NamedIntConstant(22, 'MAX_UNTIL')
MIN_UNTIL = _NamedIntConstant(23, 'MIN_UNTIL')
NOT_LITERAL = _NamedIntConstant(24, 'NOT_LITERAL')
NOT_LITERAL_IGNORE = _NamedIntConstant(25, 'NOT_LITERAL_IGNORE')
NEGATE = _NamedIntConstant(26, 'NEGATE')
RANGE = _NamedIntConstant(27, 'RANGE')
REPEAT = _NamedIntConstant(28, 'REPEAT')
REPEAT_ONE = _NamedIntConstant(29, 'REPEAT_ONE')
SUBPATTERN = _NamedIntConstant(30, 'SUBPATTERN')
MIN_REPEAT_ONE = _NamedIntConstant(31, 'MIN_REPEAT_ONE')
RANGE_IGNORE = _NamedIntConstant(32, 'RANGE_IGNORE')
MIN_REPEAT = _NamedIntConstant(33, 'MIN_REPEAT')
MAX_REPEAT = _NamedIntConstant(34, 'MAX_REPEAT')
# operators OPCODES = [
# failure=0 success=1 (just because it looks better that way :-) FAILURE,
OPCODES = _makecodes(""" SUCCESS,
FAILURE SUCCESS ANY,
ANY_ALL,
ASSERT,
ASSERT_NOT,
AT,
BRANCH,
CALL,
CATEGORY,
CHARSET,
BIGCHARSET,
GROUPREF,
GROUPREF_EXISTS,
GROUPREF_IGNORE,
IN,
IN_IGNORE,
INFO,
JUMP,
LITERAL,
LITERAL_IGNORE,
MARK,
MAX_UNTIL,
MIN_UNTIL,
NOT_LITERAL,
NOT_LITERAL_IGNORE,
NEGATE,
RANGE,
REPEAT,
REPEAT_ONE,
SUBPATTERN,
MIN_REPEAT_ONE,
RANGE_IGNORE,
]
ANY ANY_ALL AT_BEGINNING = _NamedIntConstant( 0, 'AT_BEGINNING')
ASSERT ASSERT_NOT AT_BEGINNING_LINE = _NamedIntConstant( 1, 'AT_BEGINNING_LINE')
AT AT_BEGINNING_STRING = _NamedIntConstant( 2, 'AT_BEGINNING_STRING')
BRANCH AT_BOUNDARY = _NamedIntConstant( 3, 'AT_BOUNDARY')
CALL AT_NON_BOUNDARY = _NamedIntConstant( 4, 'AT_NON_BOUNDARY')
CATEGORY AT_END = _NamedIntConstant( 5, 'AT_END')
CHARSET BIGCHARSET AT_END_LINE = _NamedIntConstant( 6, 'AT_END_LINE')
GROUPREF GROUPREF_EXISTS GROUPREF_IGNORE AT_END_STRING = _NamedIntConstant( 7, 'AT_END_STRING')
IN IN_IGNORE AT_LOC_BOUNDARY = _NamedIntConstant( 8, 'AT_LOC_BOUNDARY')
INFO AT_LOC_NON_BOUNDARY = _NamedIntConstant( 9, 'AT_LOC_NON_BOUNDARY')
JUMP AT_UNI_BOUNDARY = _NamedIntConstant(10, 'AT_UNI_BOUNDARY')
LITERAL LITERAL_IGNORE AT_UNI_NON_BOUNDARY = _NamedIntConstant(11, 'AT_UNI_NON_BOUNDARY')
MARK
MAX_UNTIL
MIN_UNTIL
NOT_LITERAL NOT_LITERAL_IGNORE
NEGATE
RANGE
REPEAT
REPEAT_ONE
SUBPATTERN
MIN_REPEAT_ONE
RANGE_IGNORE
MIN_REPEAT MAX_REPEAT ATCODES = [
""") AT_BEGINNING,
del OPCODES[-2:] # remove MIN_REPEAT and MAX_REPEAT AT_BEGINNING_LINE,
AT_BEGINNING_STRING,
AT_BOUNDARY,
AT_NON_BOUNDARY,
AT_END,
AT_END_LINE,
AT_END_STRING,
AT_LOC_BOUNDARY,
AT_LOC_NON_BOUNDARY,
AT_UNI_BOUNDARY,
AT_UNI_NON_BOUNDARY,
]
# positions CATEGORY_DIGIT = _NamedIntConstant( 1, 'CATEGORY_DIGIT')
ATCODES = _makecodes(""" CATEGORY_NOT_DIGIT = _NamedIntConstant( 2, 'CATEGORY_NOT_DIGIT')
AT_BEGINNING AT_BEGINNING_LINE AT_BEGINNING_STRING CATEGORY_SPACE = _NamedIntConstant( 3, 'CATEGORY_SPACE')
AT_BOUNDARY AT_NON_BOUNDARY CATEGORY_NOT_SPACE = _NamedIntConstant( 4, 'CATEGORY_NOT_SPACE')
AT_END AT_END_LINE AT_END_STRING CATEGORY_WORD = _NamedIntConstant( 5, 'CATEGORY_WORD')
AT_LOC_BOUNDARY AT_LOC_NON_BOUNDARY CATEGORY_NOT_WORD = _NamedIntConstant( 6, 'CATEGORY_NOT_WORD')
AT_UNI_BOUNDARY AT_UNI_NON_BOUNDARY CATEGORY_LINEBREAK = _NamedIntConstant( 7, 'CATEGORY_LINEBREAK')
""") CATEGORY_NOT_LINEBREAK = _NamedIntConstant( 8, 'CATEGORY_NOT_LINEBREAK')
CATEGORY_LOC_WORD = _NamedIntConstant( 9, 'CATEGORY_LOC_WORD')
# categories CATEGORY_LOC_NOT_WORD = _NamedIntConstant(10, 'CATEGORY_LOC_NOT_WORD')
CHCODES = _makecodes(""" CATEGORY_UNI_DIGIT = _NamedIntConstant(11, 'CATEGORY_UNI_DIGIT')
CATEGORY_DIGIT CATEGORY_NOT_DIGIT CATEGORY_UNI_NOT_DIGIT = _NamedIntConstant(12, 'CATEGORY_UNI_NOT_DIGIT')
CATEGORY_SPACE CATEGORY_NOT_SPACE CATEGORY_UNI_SPACE = _NamedIntConstant(13, 'CATEGORY_UNI_SPACE')
CATEGORY_WORD CATEGORY_NOT_WORD CATEGORY_UNI_NOT_SPACE = _NamedIntConstant(14, 'CATEGORY_UNI_NOT_SPACE')
CATEGORY_LINEBREAK CATEGORY_NOT_LINEBREAK CATEGORY_UNI_WORD = _NamedIntConstant(15, 'CATEGORY_UNI_WORD')
CATEGORY_LOC_WORD CATEGORY_LOC_NOT_WORD CATEGORY_UNI_NOT_WORD = _NamedIntConstant(16, 'CATEGORY_UNI_NOT_WORD')
CATEGORY_UNI_DIGIT CATEGORY_UNI_NOT_DIGIT CATEGORY_UNI_LINEBREAK = _NamedIntConstant(17, 'CATEGORY_UNI_LINEBREAK')
CATEGORY_UNI_SPACE CATEGORY_UNI_NOT_SPACE CATEGORY_UNI_NOT_LINEBREAK = _NamedIntConstant(18, 'CATEGORY_UNI_NOT_LINEBREAK')
CATEGORY_UNI_WORD CATEGORY_UNI_NOT_WORD
CATEGORY_UNI_LINEBREAK CATEGORY_UNI_NOT_LINEBREAK
""")
CHCODES = [
CATEGORY_DIGIT,
CATEGORY_NOT_DIGIT,
CATEGORY_SPACE,
CATEGORY_NOT_SPACE,
CATEGORY_WORD,
CATEGORY_NOT_WORD,
CATEGORY_LINEBREAK,
CATEGORY_NOT_LINEBREAK,
CATEGORY_LOC_WORD,
CATEGORY_LOC_NOT_WORD,
CATEGORY_UNI_DIGIT,
CATEGORY_UNI_NOT_DIGIT,
CATEGORY_UNI_SPACE,
CATEGORY_UNI_NOT_SPACE,
CATEGORY_UNI_WORD,
CATEGORY_UNI_NOT_WORD,
CATEGORY_UNI_LINEBREAK,
CATEGORY_UNI_NOT_LINEBREAK,
]
# replacement operations for "ignore case" mode # replacement operations for "ignore case" mode
OP_IGNORE = { OP_IGNORE = {

View file

@ -10,6 +10,6 @@ __all__ = [
'error' 'error'
] ]
from _struct import * from _struct import Struct, calcsize, error, iter_unpack, pack, pack_into, unpack, unpack_from
from _struct import _clearcache from _struct import _clearcache
from _struct import __doc__ from _struct import __doc__

View file

@ -161,38 +161,31 @@ __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput",
# NOTE: We intentionally exclude list2cmdline as it is # NOTE: We intentionally exclude list2cmdline as it is
# considered an internal implementation detail. issue10838. # considered an internal implementation detail. issue10838.
if _mswindows: # if _mswindows:
from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP, # from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP,
STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, # STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
STD_ERROR_HANDLE, SW_HIDE, # STD_ERROR_HANDLE, SW_HIDE,
STARTF_USESTDHANDLES, STARTF_USESHOWWINDOW) # STARTF_USESTDHANDLES, STARTF_USESHOWWINDOW)
# __all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP",
__all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP", # "STD_INPUT_HANDLE", "STD_OUTPUT_HANDLE",
"STD_INPUT_HANDLE", "STD_OUTPUT_HANDLE", # "STD_ERROR_HANDLE", "SW_HIDE",
"STD_ERROR_HANDLE", "SW_HIDE", # "STARTF_USESTDHANDLES", "STARTF_USESHOWWINDOW",
"STARTF_USESTDHANDLES", "STARTF_USESHOWWINDOW", # "STARTUPINFO"])
"STARTUPINFO"]) # class Handle(int):
# closed = False
class Handle(int): # def Close(self, CloseHandle=_winapi.CloseHandle):
closed = False # if not self.closed:
# self.closed = True
def Close(self, CloseHandle=_winapi.CloseHandle): # CloseHandle(self)
if not self.closed: # def Detach(self):
self.closed = True # if not self.closed:
CloseHandle(self) # self.closed = True
# return int(self)
def Detach(self): # raise ValueError("already closed")
if not self.closed: # def __repr__(self):
self.closed = True # return "%s(%d)" % (self.__class__.__name__, int(self))
return int(self) # __del__ = Close
raise ValueError("already closed") # __str__ = __repr__
def __repr__(self):
return "%s(%d)" % (self.__class__.__name__, int(self))
__del__ = Close
__str__ = __repr__
# This lists holds Popen instances for which the underlying process had not # This lists holds Popen instances for which the underlying process had not
# exited at the time its __del__ method got called: those processes are wait()ed # exited at the time its __del__ method got called: those processes are wait()ed

View file

@ -577,7 +577,7 @@ def get_config_vars(*args):
# OS X platforms require special customization to handle # OS X platforms require special customization to handle
# multi-architecture, multi-os-version installers # multi-architecture, multi-os-version installers
if sys.platform == 'darwin': if sys.platform == 'darwin':
import _osx_support # import _osx_support
_osx_support.customize_config_vars(_CONFIG_VARS) _osx_support.customize_config_vars(_CONFIG_VARS)
if args: if args:
@ -684,7 +684,7 @@ def get_platform():
if m: if m:
release = m.group() release = m.group()
elif osname[:6] == "darwin": elif osname[:6] == "darwin":
import _osx_support # import _osx_support
osname, release, machine = _osx_support.get_platform_osx( osname, release, machine = _osx_support.get_platform_osx(
get_config_vars(), get_config_vars(),
osname, release, machine) osname, release, machine)

View file

@ -471,8 +471,8 @@ def _is_gui_available():
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
# if Python is running as a service (such as the buildbot service), # if Python is running as a service (such as the buildbot service),
# gui interaction may be disallowed # gui interaction may be disallowed
import ctypes # import ctypes
import ctypes.wintypes # import ctypes.wintypes
UOI_FLAGS = 1 UOI_FLAGS = 1
WSF_VISIBLE = 0x0001 WSF_VISIBLE = 0x0001
class USEROBJECTFLAGS(ctypes.Structure): class USEROBJECTFLAGS(ctypes.Structure):
@ -501,8 +501,8 @@ def _is_gui_available():
# process not running under the same user id as the current console # process not running under the same user id as the current console
# user. To avoid that, raise an exception if the window manager # user. To avoid that, raise an exception if the window manager
# connection is not available. # connection is not available.
from ctypes import cdll, c_int, pointer, Structure # from ctypes import cdll, c_int, pointer, Structure
from ctypes.util import find_library # from ctypes.util import find_library
app_services = cdll.LoadLibrary(find_library("ApplicationServices")) app_services = cdll.LoadLibrary(find_library("ApplicationServices"))
@ -2707,7 +2707,7 @@ def missing_compiler_executable(cmd_names=[]):
missing. missing.
""" """
from distutils import ccompiler, sysconfig, spawn # from distutils import ccompiler, sysconfig, spawn
compiler = ccompiler.new_compiler() compiler = ccompiler.new_compiler()
sysconfig.customize_compiler(compiler) sysconfig.customize_compiler(compiler)
for name in compiler.executables: for name in compiler.executables:

View file

@ -415,18 +415,18 @@ if 1:
s %= ', '.join('a%d:%d' % (i,i) for i in range(255)) s %= ', '.join('a%d:%d' % (i,i) for i in range(255))
compile(s, '?', 'exec') compile(s, '?', 'exec')
def test_mangling(self): # def test_mangling(self):
class A: # class A:
def f(): # def f():
__mangled = 1 # __mangled = 1
__not_mangled__ = 2 # __not_mangled__ = 2
import __mangled_mod # import __mangled_mod
import __package__.module # import __package__.module
self.assertIn("_A__mangled", A.f.__code__.co_varnames) # self.assertIn("_A__mangled", A.f.__code__.co_varnames)
self.assertIn("__not_mangled__", A.f.__code__.co_varnames) # self.assertIn("__not_mangled__", A.f.__code__.co_varnames)
self.assertIn("_A__mangled_mod", A.f.__code__.co_varnames) # self.assertIn("_A__mangled_mod", A.f.__code__.co_varnames)
self.assertIn("__package__", A.f.__code__.co_varnames) # self.assertIn("__package__", A.f.__code__.co_varnames)
def test_compile_ast(self): def test_compile_ast(self):
fname = __file__ fname = __file__

View file

@ -5,7 +5,8 @@ import email
from email.message import Message from email.message import Message
from email._policybase import compat32 from email._policybase import compat32
from test.support import load_package_tests from test.support import load_package_tests
from test.test_email import __file__ as landmark
landmark = __file__
# Load all tests in package # Load all tests in package
def load_tests(*args): def load_tests(*args):

View file

@ -42,6 +42,7 @@ from email import quoprimime
from test.support import unlink, start_threads from test.support import unlink, start_threads
from test.test_email import openfile, TestEmailBase from test.test_email import openfile, TestEmailBase
from encodings import iso2022_jp
# These imports are documented to work, but we are testing them using a # These imports are documented to work, but we are testing them using a
# different path, so we import them here just to make sure they are importable. # different path, so we import them here just to make sure they are importable.

View file

@ -1,310 +0,0 @@
import unittest
import unittest.mock
import test.support
import os
import os.path
import contextlib
import sys
import ensurepip
import ensurepip._uninstall
class TestEnsurePipVersion(unittest.TestCase):
def test_returns_version(self):
self.assertEqual(ensurepip._PIP_VERSION, ensurepip.version())
class EnsurepipMixin:
def setUp(self):
run_pip_patch = unittest.mock.patch("ensurepip._run_pip")
self.run_pip = run_pip_patch.start()
self.run_pip.return_value = 0
self.addCleanup(run_pip_patch.stop)
# Avoid side effects on the actual os module
real_devnull = os.devnull
os_patch = unittest.mock.patch("ensurepip.os")
patched_os = os_patch.start()
self.addCleanup(os_patch.stop)
patched_os.devnull = real_devnull
patched_os.path = os.path
self.os_environ = patched_os.environ = os.environ.copy()
class TestBootstrap(EnsurepipMixin, unittest.TestCase):
def test_basic_bootstrapping(self):
ensurepip.bootstrap()
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "setuptools", "pip",
],
unittest.mock.ANY,
)
additional_paths = self.run_pip.call_args[0][1]
self.assertEqual(len(additional_paths), 2)
def test_bootstrapping_with_root(self):
ensurepip.bootstrap(root="/foo/bar/")
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "--root", "/foo/bar/",
"setuptools", "pip",
],
unittest.mock.ANY,
)
def test_bootstrapping_with_user(self):
ensurepip.bootstrap(user=True)
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "--user", "setuptools", "pip",
],
unittest.mock.ANY,
)
def test_bootstrapping_with_upgrade(self):
ensurepip.bootstrap(upgrade=True)
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "--upgrade", "setuptools", "pip",
],
unittest.mock.ANY,
)
def test_bootstrapping_with_verbosity_1(self):
ensurepip.bootstrap(verbosity=1)
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "-v", "setuptools", "pip",
],
unittest.mock.ANY,
)
def test_bootstrapping_with_verbosity_2(self):
ensurepip.bootstrap(verbosity=2)
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "-vv", "setuptools", "pip",
],
unittest.mock.ANY,
)
def test_bootstrapping_with_verbosity_3(self):
ensurepip.bootstrap(verbosity=3)
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "-vvv", "setuptools", "pip",
],
unittest.mock.ANY,
)
def test_bootstrapping_with_regular_install(self):
ensurepip.bootstrap()
self.assertEqual(self.os_environ["ENSUREPIP_OPTIONS"], "install")
def test_bootstrapping_with_alt_install(self):
ensurepip.bootstrap(altinstall=True)
self.assertEqual(self.os_environ["ENSUREPIP_OPTIONS"], "altinstall")
def test_bootstrapping_with_default_pip(self):
ensurepip.bootstrap(default_pip=True)
self.assertNotIn("ENSUREPIP_OPTIONS", self.os_environ)
def test_altinstall_default_pip_conflict(self):
with self.assertRaises(ValueError):
ensurepip.bootstrap(altinstall=True, default_pip=True)
self.assertFalse(self.run_pip.called)
def test_pip_environment_variables_removed(self):
# ensurepip deliberately ignores all pip environment variables
# See http://bugs.python.org/issue19734 for details
self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
ensurepip.bootstrap()
self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
def test_pip_config_file_disabled(self):
# ensurepip deliberately ignores the pip config file
# See http://bugs.python.org/issue20053 for details
ensurepip.bootstrap()
self.assertEqual(self.os_environ["PIP_CONFIG_FILE"], os.devnull)
@contextlib.contextmanager
def fake_pip(version=ensurepip._PIP_VERSION):
if version is None:
pip = None
else:
class FakePip():
__version__ = version
pip = FakePip()
sentinel = object()
orig_pip = sys.modules.get("pip", sentinel)
sys.modules["pip"] = pip
try:
yield pip
finally:
if orig_pip is sentinel:
del sys.modules["pip"]
else:
sys.modules["pip"] = orig_pip
class TestUninstall(EnsurepipMixin, unittest.TestCase):
def test_uninstall_skipped_when_not_installed(self):
with fake_pip(None):
ensurepip._uninstall_helper()
self.assertFalse(self.run_pip.called)
def test_uninstall_skipped_with_warning_for_wrong_version(self):
with fake_pip("not a valid version"):
with test.support.captured_stderr() as stderr:
ensurepip._uninstall_helper()
warning = stderr.getvalue().strip()
self.assertIn("only uninstall a matching version", warning)
self.assertFalse(self.run_pip.called)
def test_uninstall(self):
with fake_pip():
ensurepip._uninstall_helper()
self.run_pip.assert_called_once_with(
[
"uninstall", "-y", "--disable-pip-version-check", "pip",
"setuptools",
]
)
def test_uninstall_with_verbosity_1(self):
with fake_pip():
ensurepip._uninstall_helper(verbosity=1)
self.run_pip.assert_called_once_with(
[
"uninstall", "-y", "--disable-pip-version-check", "-v", "pip",
"setuptools",
]
)
def test_uninstall_with_verbosity_2(self):
with fake_pip():
ensurepip._uninstall_helper(verbosity=2)
self.run_pip.assert_called_once_with(
[
"uninstall", "-y", "--disable-pip-version-check", "-vv", "pip",
"setuptools",
]
)
def test_uninstall_with_verbosity_3(self):
with fake_pip():
ensurepip._uninstall_helper(verbosity=3)
self.run_pip.assert_called_once_with(
[
"uninstall", "-y", "--disable-pip-version-check", "-vvv",
"pip", "setuptools",
]
)
def test_pip_environment_variables_removed(self):
# ensurepip deliberately ignores all pip environment variables
# See http://bugs.python.org/issue19734 for details
self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder"
with fake_pip():
ensurepip._uninstall_helper()
self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ)
def test_pip_config_file_disabled(self):
# ensurepip deliberately ignores the pip config file
# See http://bugs.python.org/issue20053 for details
with fake_pip():
ensurepip._uninstall_helper()
self.assertEqual(self.os_environ["PIP_CONFIG_FILE"], os.devnull)
# Basic testing of the main functions and their argument parsing
EXPECTED_VERSION_OUTPUT = "pip " + ensurepip._PIP_VERSION
class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
def test_bootstrap_version(self):
with test.support.captured_stdout() as stdout:
with self.assertRaises(SystemExit):
ensurepip._main(["--version"])
result = stdout.getvalue().strip()
self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
self.assertFalse(self.run_pip.called)
def test_basic_bootstrapping(self):
exit_code = ensurepip._main([])
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "setuptools", "pip",
],
unittest.mock.ANY,
)
additional_paths = self.run_pip.call_args[0][1]
self.assertEqual(len(additional_paths), 2)
self.assertEqual(exit_code, 0)
def test_bootstrapping_error_code(self):
self.run_pip.return_value = 2
exit_code = ensurepip._main([])
self.assertEqual(exit_code, 2)
class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
def test_uninstall_version(self):
with test.support.captured_stdout() as stdout:
with self.assertRaises(SystemExit):
ensurepip._uninstall._main(["--version"])
result = stdout.getvalue().strip()
self.assertEqual(result, EXPECTED_VERSION_OUTPUT)
self.assertFalse(self.run_pip.called)
def test_basic_uninstall(self):
with fake_pip():
exit_code = ensurepip._uninstall._main([])
self.run_pip.assert_called_once_with(
[
"uninstall", "-y", "--disable-pip-version-check", "pip",
"setuptools",
]
)
self.assertEqual(exit_code, 0)
def test_uninstall_error_code(self):
with fake_pip():
self.run_pip.return_value = 2
exit_code = ensurepip._uninstall._main([])
self.assertEqual(exit_code, 2)
if __name__ == "__main__":
unittest.main()

View file

@ -33,45 +33,45 @@ class FutureTest(unittest.TestCase):
with support.CleanImport('test_future3'): with support.CleanImport('test_future3'):
from test import test_future3 from test import test_future3
def test_badfuture3(self): # def test_badfuture3(self):
with self.assertRaises(SyntaxError) as cm: # with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future3 # from test import badsyntax_future3
self.check_syntax_error(cm.exception, "badsyntax_future3", 3) # self.check_syntax_error(cm.exception, "badsyntax_future3", 3)
def test_badfuture4(self): # def test_badfuture4(self):
with self.assertRaises(SyntaxError) as cm: # with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future4 # from test import badsyntax_future4
self.check_syntax_error(cm.exception, "badsyntax_future4", 3) # self.check_syntax_error(cm.exception, "badsyntax_future4", 3)
def test_badfuture5(self): # def test_badfuture5(self):
with self.assertRaises(SyntaxError) as cm: # with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future5 # from test import badsyntax_future5
self.check_syntax_error(cm.exception, "badsyntax_future5", 4) # self.check_syntax_error(cm.exception, "badsyntax_future5", 4)
def test_badfuture6(self): # def test_badfuture6(self):
with self.assertRaises(SyntaxError) as cm: # with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future6 # from test import badsyntax_future6
self.check_syntax_error(cm.exception, "badsyntax_future6", 3) # self.check_syntax_error(cm.exception, "badsyntax_future6", 3)
def test_badfuture7(self): # def test_badfuture7(self):
with self.assertRaises(SyntaxError) as cm: # with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future7 # from test import badsyntax_future7
self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53) # self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53)
def test_badfuture8(self): # def test_badfuture8(self):
with self.assertRaises(SyntaxError) as cm: # with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future8 # from test import badsyntax_future8
self.check_syntax_error(cm.exception, "badsyntax_future8", 3) # self.check_syntax_error(cm.exception, "badsyntax_future8", 3)
def test_badfuture9(self): # def test_badfuture9(self):
with self.assertRaises(SyntaxError) as cm: # with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future9 # from test import badsyntax_future9
self.check_syntax_error(cm.exception, "badsyntax_future9", 3, 0) # self.check_syntax_error(cm.exception, "badsyntax_future9", 3, 0)
def test_badfuture10(self): # def test_badfuture10(self):
with self.assertRaises(SyntaxError) as cm: # with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future10 # from test import badsyntax_future10
self.check_syntax_error(cm.exception, "badsyntax_future10", 3, 0) # self.check_syntax_error(cm.exception, "badsyntax_future10", 3, 0)
def test_parserhack(self): def test_parserhack(self):
# test that the parser.c::future_hack function works as expected # test that the parser.c::future_hack function works as expected

View file

@ -1623,7 +1623,7 @@ class HTTPSTest(TestCase):
self.skipTest('ssl support required') self.skipTest('ssl support required')
def make_server(self, certfile): def make_server(self, certfile):
from test.ssl_servers import make_https_server # from test.ssl_servers import make_https_server
return make_https_server(self, certfile=certfile) return make_https_server(self, certfile=certfile)
def test_attributes(self): def test_attributes(self):
@ -1633,7 +1633,7 @@ class HTTPSTest(TestCase):
def test_networked(self): def test_networked(self):
# Default settings: requires a valid cert from a trusted CA # Default settings: requires a valid cert from a trusted CA
import ssl # import ssl
support.requires('network') support.requires('network')
with support.transient_internet('self-signed.pythontest.net'): with support.transient_internet('self-signed.pythontest.net'):
h = client.HTTPSConnection('self-signed.pythontest.net', 443) h = client.HTTPSConnection('self-signed.pythontest.net', 443)
@ -1643,7 +1643,7 @@ class HTTPSTest(TestCase):
def test_networked_noverification(self): def test_networked_noverification(self):
# Switch off cert verification # Switch off cert verification
import ssl # import ssl
support.requires('network') support.requires('network')
with support.transient_internet('self-signed.pythontest.net'): with support.transient_internet('self-signed.pythontest.net'):
context = ssl._create_unverified_context() context = ssl._create_unverified_context()
@ -1670,7 +1670,7 @@ class HTTPSTest(TestCase):
def test_networked_good_cert(self): def test_networked_good_cert(self):
# We feed the server's cert as a validating cert # We feed the server's cert as a validating cert
import ssl # import ssl
support.requires('network') support.requires('network')
with support.transient_internet('self-signed.pythontest.net'): with support.transient_internet('self-signed.pythontest.net'):
context = ssl.SSLContext(ssl.PROTOCOL_TLS) context = ssl.SSLContext(ssl.PROTOCOL_TLS)
@ -1686,7 +1686,7 @@ class HTTPSTest(TestCase):
def test_networked_bad_cert(self): def test_networked_bad_cert(self):
# We feed a "CA" cert that is unrelated to the server's cert # We feed a "CA" cert that is unrelated to the server's cert
import ssl # import ssl
support.requires('network') support.requires('network')
with support.transient_internet('self-signed.pythontest.net'): with support.transient_internet('self-signed.pythontest.net'):
context = ssl.SSLContext(ssl.PROTOCOL_TLS) context = ssl.SSLContext(ssl.PROTOCOL_TLS)
@ -1699,7 +1699,7 @@ class HTTPSTest(TestCase):
def test_local_unknown_cert(self): def test_local_unknown_cert(self):
# The custom cert isn't known to the default trust bundle # The custom cert isn't known to the default trust bundle
import ssl # import ssl
server = self.make_server(CERT_localhost) server = self.make_server(CERT_localhost)
h = client.HTTPSConnection('localhost', server.port) h = client.HTTPSConnection('localhost', server.port)
with self.assertRaises(ssl.SSLError) as exc_info: with self.assertRaises(ssl.SSLError) as exc_info:
@ -1708,7 +1708,7 @@ class HTTPSTest(TestCase):
def test_local_good_hostname(self): def test_local_good_hostname(self):
# The (valid) cert validates the HTTP hostname # The (valid) cert validates the HTTP hostname
import ssl # import ssl
server = self.make_server(CERT_localhost) server = self.make_server(CERT_localhost)
context = ssl.SSLContext(ssl.PROTOCOL_TLS) context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED context.verify_mode = ssl.CERT_REQUIRED
@ -1722,7 +1722,7 @@ class HTTPSTest(TestCase):
def test_local_bad_hostname(self): def test_local_bad_hostname(self):
# The (valid) cert doesn't validate the HTTP hostname # The (valid) cert doesn't validate the HTTP hostname
import ssl # import ssl
server = self.make_server(CERT_fakehostname) server = self.make_server(CERT_fakehostname)
context = ssl.SSLContext(ssl.PROTOCOL_TLS) context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED context.verify_mode = ssl.CERT_REQUIRED

View file

@ -7,6 +7,7 @@ from test import support
from test.support import TESTFN from test.support import TESTFN
import unittest, io, codecs, sys import unittest, io, codecs, sys
import _multibytecodec import _multibytecodec
from encodings import iso2022_jp
ALL_CJKENCODINGS = [ ALL_CJKENCODINGS = [
# _codecs_cn # _codecs_cn

View file

@ -637,7 +637,7 @@ class UtimeTests(unittest.TestCase):
def get_file_system(self, path): def get_file_system(self, path):
if sys.platform == 'win32': if sys.platform == 'win32':
root = os.path.splitdrive(os.path.abspath(path))[0] + '\\' root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'
import ctypes # import ctypes
kernel32 = ctypes.windll.kernel32 kernel32 = ctypes.windll.kernel32
buf = ctypes.create_unicode_buffer("", 100) buf = ctypes.create_unicode_buffer("", 100)
ok = kernel32.GetVolumeInformationW(root, None, 0, ok = kernel32.GetVolumeInformationW(root, None, 0,
@ -1915,361 +1915,6 @@ class Pep383Tests(unittest.TestCase):
for fn in self.unicodefn: for fn in self.unicodefn:
os.stat(os.path.join(self.dir, fn)) os.stat(os.path.join(self.dir, fn))
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
class Win32KillTests(unittest.TestCase):
def _kill(self, sig):
# Start sys.executable as a subprocess and communicate from the
# subprocess to the parent that the interpreter is ready. When it
# becomes ready, send *sig* via os.kill to the subprocess and check
# that the return code is equal to *sig*.
import ctypes
from ctypes import wintypes
import msvcrt
# Since we can't access the contents of the process' stdout until the
# process has exited, use PeekNamedPipe to see what's inside stdout
# without waiting. This is done so we can tell that the interpreter
# is started and running at a point where it could handle a signal.
PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
PeekNamedPipe.restype = wintypes.BOOL
PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle
ctypes.POINTER(ctypes.c_char), # stdout buf
wintypes.DWORD, # Buffer size
ctypes.POINTER(wintypes.DWORD), # bytes read
ctypes.POINTER(wintypes.DWORD), # bytes avail
ctypes.POINTER(wintypes.DWORD)) # bytes left
msg = "running"
proc = subprocess.Popen([sys.executable, "-c",
"import sys;"
"sys.stdout.write('{}');"
"sys.stdout.flush();"
"input()".format(msg)],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
self.addCleanup(proc.stdout.close)
self.addCleanup(proc.stderr.close)
self.addCleanup(proc.stdin.close)
count, max = 0, 100
while count < max and proc.poll() is None:
# Create a string buffer to store the result of stdout from the pipe
buf = ctypes.create_string_buffer(len(msg))
# Obtain the text currently in proc.stdout
# Bytes read/avail/left are left as NULL and unused
rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()),
buf, ctypes.sizeof(buf), None, None, None)
self.assertNotEqual(rslt, 0, "PeekNamedPipe failed")
if buf.value:
self.assertEqual(msg, buf.value.decode())
break
time.sleep(0.1)
count += 1
else:
self.fail("Did not receive communication from the subprocess")
os.kill(proc.pid, sig)
self.assertEqual(proc.wait(), sig)
def test_kill_sigterm(self):
# SIGTERM doesn't mean anything special, but make sure it works
self._kill(signal.SIGTERM)
def test_kill_int(self):
# os.kill on Windows can take an int which gets set as the exit code
self._kill(100)
def _kill_with_event(self, event, name):
tagname = "test_os_%s" % uuid.uuid1()
m = mmap.mmap(-1, 1, tagname)
m[0] = 0
# Run a script which has console control handling enabled.
proc = subprocess.Popen([sys.executable,
os.path.join(os.path.dirname(__file__),
"win_console_handler.py"), tagname],
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
# Let the interpreter startup before we send signals. See #3137.
count, max = 0, 100
while count < max and proc.poll() is None:
if m[0] == 1:
break
time.sleep(0.1)
count += 1
else:
# Forcefully kill the process if we weren't able to signal it.
os.kill(proc.pid, signal.SIGINT)
self.fail("Subprocess didn't finish initialization")
os.kill(proc.pid, event)
# proc.send_signal(event) could also be done here.
# Allow time for the signal to be passed and the process to exit.
time.sleep(0.5)
if not proc.poll():
# Forcefully kill the process if we weren't able to signal it.
os.kill(proc.pid, signal.SIGINT)
self.fail("subprocess did not stop on {}".format(name))
@unittest.skip("subprocesses aren't inheriting Ctrl+C property")
def test_CTRL_C_EVENT(self):
from ctypes import wintypes
import ctypes
# Make a NULL value by creating a pointer with no argument.
NULL = ctypes.POINTER(ctypes.c_int)()
SetConsoleCtrlHandler = ctypes.windll.kernel32.SetConsoleCtrlHandler
SetConsoleCtrlHandler.argtypes = (ctypes.POINTER(ctypes.c_int),
wintypes.BOOL)
SetConsoleCtrlHandler.restype = wintypes.BOOL
# Calling this with NULL and FALSE causes the calling process to
# handle Ctrl+C, rather than ignore it. This property is inherited
# by subprocesses.
SetConsoleCtrlHandler(NULL, 0)
self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT")
def test_CTRL_BREAK_EVENT(self):
self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
class Win32ListdirTests(unittest.TestCase):
"""Test listdir on Windows."""
def setUp(self):
self.created_paths = []
for i in range(2):
dir_name = 'SUB%d' % i
dir_path = os.path.join(support.TESTFN, dir_name)
file_name = 'FILE%d' % i
file_path = os.path.join(support.TESTFN, file_name)
os.makedirs(dir_path)
with open(file_path, 'w') as f:
f.write("I'm %s and proud of it. Blame test_os.\n" % file_path)
self.created_paths.extend([dir_name, file_name])
self.created_paths.sort()
def tearDown(self):
shutil.rmtree(support.TESTFN)
def test_listdir_no_extended_path(self):
"""Test when the path is not an "extended" path."""
# unicode
self.assertEqual(
sorted(os.listdir(support.TESTFN)),
self.created_paths)
# bytes
self.assertEqual(
sorted(os.listdir(os.fsencode(support.TESTFN))),
[os.fsencode(path) for path in self.created_paths])
def test_listdir_extended_path(self):
"""Test when the path starts with '\\\\?\\'."""
# See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
# unicode
path = '\\\\?\\' + os.path.abspath(support.TESTFN)
self.assertEqual(
sorted(os.listdir(path)),
self.created_paths)
# bytes
path = b'\\\\?\\' + os.fsencode(os.path.abspath(support.TESTFN))
self.assertEqual(
sorted(os.listdir(path)),
[os.fsencode(path) for path in self.created_paths])
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
@support.skip_unless_symlink
class Win32SymlinkTests(unittest.TestCase):
filelink = 'filelinktest'
filelink_target = os.path.abspath(__file__)
dirlink = 'dirlinktest'
dirlink_target = os.path.dirname(filelink_target)
missing_link = 'missing link'
def setUp(self):
assert os.path.exists(self.dirlink_target)
assert os.path.exists(self.filelink_target)
assert not os.path.exists(self.dirlink)
assert not os.path.exists(self.filelink)
assert not os.path.exists(self.missing_link)
def tearDown(self):
if os.path.exists(self.filelink):
os.remove(self.filelink)
if os.path.exists(self.dirlink):
os.rmdir(self.dirlink)
if os.path.lexists(self.missing_link):
os.remove(self.missing_link)
def test_directory_link(self):
os.symlink(self.dirlink_target, self.dirlink)
self.assertTrue(os.path.exists(self.dirlink))
self.assertTrue(os.path.isdir(self.dirlink))
self.assertTrue(os.path.islink(self.dirlink))
self.check_stat(self.dirlink, self.dirlink_target)
def test_file_link(self):
os.symlink(self.filelink_target, self.filelink)
self.assertTrue(os.path.exists(self.filelink))
self.assertTrue(os.path.isfile(self.filelink))
self.assertTrue(os.path.islink(self.filelink))
self.check_stat(self.filelink, self.filelink_target)
def _create_missing_dir_link(self):
'Create a "directory" link to a non-existent target'
linkname = self.missing_link
if os.path.lexists(linkname):
os.remove(linkname)
target = r'c:\\target does not exist.29r3c740'
assert not os.path.exists(target)
target_is_dir = True
os.symlink(target, linkname, target_is_dir)
def test_remove_directory_link_to_missing_target(self):
self._create_missing_dir_link()
# For compatibility with Unix, os.remove will check the
# directory status and call RemoveDirectory if the symlink
# was created with target_is_dir==True.
os.remove(self.missing_link)
@unittest.skip("currently fails; consider for improvement")
def test_isdir_on_directory_link_to_missing_target(self):
self._create_missing_dir_link()
# consider having isdir return true for directory links
self.assertTrue(os.path.isdir(self.missing_link))
@unittest.skip("currently fails; consider for improvement")
def test_rmdir_on_directory_link_to_missing_target(self):
self._create_missing_dir_link()
# consider allowing rmdir to remove directory links
os.rmdir(self.missing_link)
def check_stat(self, link, target):
self.assertEqual(os.stat(link), os.stat(target))
self.assertNotEqual(os.lstat(link), os.stat(link))
bytes_link = os.fsencode(link)
self.assertEqual(os.stat(bytes_link), os.stat(target))
self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link))
def test_12084(self):
level1 = os.path.abspath(support.TESTFN)
level2 = os.path.join(level1, "level2")
level3 = os.path.join(level2, "level3")
self.addCleanup(support.rmtree, level1)
os.mkdir(level1)
os.mkdir(level2)
os.mkdir(level3)
file1 = os.path.abspath(os.path.join(level1, "file1"))
create_file(file1)
orig_dir = os.getcwd()
try:
os.chdir(level2)
link = os.path.join(level2, "link")
os.symlink(os.path.relpath(file1), "link")
self.assertIn("link", os.listdir(os.getcwd()))
# Check os.stat calls from the same dir as the link
self.assertEqual(os.stat(file1), os.stat("link"))
# Check os.stat calls from a dir below the link
os.chdir(level1)
self.assertEqual(os.stat(file1),
os.stat(os.path.relpath(link)))
# Check os.stat calls from a dir above the link
os.chdir(level3)
self.assertEqual(os.stat(file1),
os.stat(os.path.relpath(link)))
finally:
os.chdir(orig_dir)
@unittest.skipUnless(os.path.lexists(r'C:\Users\All Users')
and os.path.exists(r'C:\ProgramData'),
'Test directories not found')
def test_29248(self):
# os.symlink() calls CreateSymbolicLink, which creates
# the reparse data buffer with the print name stored
# first, so the offset is always 0. CreateSymbolicLink
# stores the "PrintName" DOS path (e.g. "C:\") first,
# with an offset of 0, followed by the "SubstituteName"
# NT path (e.g. "\??\C:\"). The "All Users" link, on
# the other hand, seems to have been created manually
# with an inverted order.
target = os.readlink(r'C:\Users\All Users')
self.assertTrue(os.path.samefile(target, r'C:\ProgramData'))
def test_buffer_overflow(self):
# Older versions would have a buffer overflow when detecting
# whether a link source was a directory. This test ensures we
# no longer crash, but does not otherwise validate the behavior
segment = 'X' * 27
path = os.path.join(*[segment] * 10)
test_cases = [
# overflow with absolute src
('\\' + path, segment),
# overflow dest with relative src
(segment, path),
# overflow when joining src
(path[:180], path[:180]),
]
for src, dest in test_cases:
try:
os.symlink(src, dest)
except FileNotFoundError:
pass
else:
try:
os.remove(dest)
except OSError:
pass
# Also test with bytes, since that is a separate code path.
try:
os.symlink(os.fsencode(src), os.fsencode(dest))
except FileNotFoundError:
pass
else:
try:
os.remove(dest)
except OSError:
pass
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
class Win32JunctionTests(unittest.TestCase):
junction = 'junctiontest'
junction_target = os.path.dirname(os.path.abspath(__file__))
def setUp(self):
assert os.path.exists(self.junction_target)
assert not os.path.exists(self.junction)
def tearDown(self):
if os.path.exists(self.junction):
# os.rmdir delegates to Windows' RemoveDirectoryW,
# which removes junction points safely.
os.rmdir(self.junction)
def test_create_junction(self):
_winapi.CreateJunction(self.junction_target, self.junction)
self.assertTrue(os.path.exists(self.junction))
self.assertTrue(os.path.isdir(self.junction))
# Junctions are not recognized as links.
self.assertFalse(os.path.islink(self.junction))
def test_unlink_removes_junction(self):
_winapi.CreateJunction(self.junction_target, self.junction)
self.assertTrue(os.path.exists(self.junction))
os.unlink(self.junction)
self.assertFalse(os.path.exists(self.junction))
@support.skip_unless_symlink @support.skip_unless_symlink
class NonLocalSymlinkTests(unittest.TestCase): class NonLocalSymlinkTests(unittest.TestCase):

View file

@ -831,28 +831,28 @@ class PydocImportTest(PydocBaseTest):
finally: finally:
os.chmod(pkgdir, current_mode) os.chmod(pkgdir, current_mode)
def test_url_search_package_error(self): # def test_url_search_package_error(self):
# URL handler search should cope with packages that raise exceptions # # URL handler search should cope with packages that raise exceptions
pkgdir = os.path.join(TESTFN, "test_error_package") # pkgdir = os.path.join(TESTFN, "test_error_package")
os.mkdir(pkgdir) # os.mkdir(pkgdir)
init = os.path.join(pkgdir, "__init__.py") # init = os.path.join(pkgdir, "__init__.py")
with open(init, "wt", encoding="ascii") as f: # with open(init, "wt", encoding="ascii") as f:
f.write("""raise ValueError("ouch")\n""") # f.write("""raise ValueError("ouch")\n""")
with self.restrict_walk_packages(path=[TESTFN]): # with self.restrict_walk_packages(path=[TESTFN]):
# Package has to be importable for the error to have any effect # # Package has to be importable for the error to have any effect
saved_paths = tuple(sys.path) # saved_paths = tuple(sys.path)
sys.path.insert(0, TESTFN) # sys.path.insert(0, TESTFN)
try: # try:
with self.assertRaisesRegex(ValueError, "ouch"): # with self.assertRaisesRegex(ValueError, "ouch"):
import test_error_package # Sanity check # import test_error_package # Sanity check
text = self.call_url_handler("search?key=test_error_package", # text = self.call_url_handler("search?key=test_error_package",
"Pydoc: Search Results") # "Pydoc: Search Results")
found = ('<a href="test_error_package.html">' # found = ('<a href="test_error_package.html">'
'test_error_package</a>') # 'test_error_package</a>')
self.assertIn(found, text) # self.assertIn(found, text)
finally: # finally:
sys.path[:] = saved_paths # sys.path[:] = saved_paths
@unittest.skip('causes undesirable side-effects (#20128)') @unittest.skip('causes undesirable side-effects (#20128)')
def test_modules(self): def test_modules(self):

View file

@ -273,75 +273,75 @@ class LongReprTest(unittest.TestCase):
elif os.name == 'nt' and verbose: elif os.name == 'nt' and verbose:
print("cached_path_len =", cached_path_len) print("cached_path_len =", cached_path_len)
def test_module(self): # def test_module(self):
self.maxDiff = None # self.maxDiff = None
self._check_path_limitations(self.pkgname) # self._check_path_limitations(self.pkgname)
create_empty_file(os.path.join(self.subpkgname, self.pkgname + '.py')) # create_empty_file(os.path.join(self.subpkgname, self.pkgname + '.py'))
importlib.invalidate_caches() # importlib.invalidate_caches()
from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation # from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
module = areallylongpackageandmodulenametotestreprtruncation # module = areallylongpackageandmodulenametotestreprtruncation
self.assertEqual(repr(module), "<module %r from %r>" % (module.__name__, module.__file__)) # self.assertEqual(repr(module), "<module %r from %r>" % (module.__name__, module.__file__))
self.assertEqual(repr(sys), "<module 'sys' (built-in)>") # self.assertEqual(repr(sys), "<module 'sys' (built-in)>")
def test_type(self): # def test_type(self):
self._check_path_limitations('foo') # self._check_path_limitations('foo')
eq = self.assertEqual # eq = self.assertEqual
write_file(os.path.join(self.subpkgname, 'foo.py'), '''\ # write_file(os.path.join(self.subpkgname, 'foo.py'), '''\
class foo(object): # class foo(object):
pass # pass
''') # ''')
importlib.invalidate_caches() # importlib.invalidate_caches()
from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo # from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
eq(repr(foo.foo), # eq(repr(foo.foo),
"<class '%s.foo'>" % foo.__name__) # "<class '%s.foo'>" % foo.__name__)
@unittest.skip('need a suitable object') # @unittest.skip('need a suitable object')
def test_object(self): # def test_object(self):
# XXX Test the repr of a type with a really long tp_name but with no # # XXX Test the repr of a type with a really long tp_name but with no
# tp_repr. WIBNI we had ::Inline? :) # # tp_repr. WIBNI we had ::Inline? :)
pass # pass
def test_class(self): # def test_class(self):
self._check_path_limitations('bar') # self._check_path_limitations('bar')
write_file(os.path.join(self.subpkgname, 'bar.py'), '''\ # write_file(os.path.join(self.subpkgname, 'bar.py'), '''\
class bar: # class bar:
pass # pass
''') # ''')
importlib.invalidate_caches() # importlib.invalidate_caches()
from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar # from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
# Module name may be prefixed with "test.", depending on how run. # # Module name may be prefixed with "test.", depending on how run.
self.assertEqual(repr(bar.bar), "<class '%s.bar'>" % bar.__name__) # self.assertEqual(repr(bar.bar), "<class '%s.bar'>" % bar.__name__)
def test_instance(self): # def test_instance(self):
self._check_path_limitations('baz') # self._check_path_limitations('baz')
write_file(os.path.join(self.subpkgname, 'baz.py'), '''\ # write_file(os.path.join(self.subpkgname, 'baz.py'), '''\
class baz: # class baz:
pass # pass
''') # ''')
importlib.invalidate_caches() # importlib.invalidate_caches()
from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz # from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
ibaz = baz.baz() # ibaz = baz.baz()
self.assertTrue(repr(ibaz).startswith( # self.assertTrue(repr(ibaz).startswith(
"<%s.baz object at 0x" % baz.__name__)) # "<%s.baz object at 0x" % baz.__name__))
def test_method(self): # def test_method(self):
self._check_path_limitations('qux') # self._check_path_limitations('qux')
eq = self.assertEqual # eq = self.assertEqual
write_file(os.path.join(self.subpkgname, 'qux.py'), '''\ # write_file(os.path.join(self.subpkgname, 'qux.py'), '''\
class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: # class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
def amethod(self): pass # def amethod(self): pass
''') # ''')
importlib.invalidate_caches() # importlib.invalidate_caches()
from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux # from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
# Unbound methods first # # Unbound methods first
r = repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod) # r = repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod)
self.assertTrue(r.startswith('<function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod'), r) # self.assertTrue(r.startswith('<function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod'), r)
# Bound method next # # Bound method next
iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() # iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
r = repr(iqux.amethod) # r = repr(iqux.amethod)
self.assertTrue(r.startswith( # self.assertTrue(r.startswith(
'<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \ # '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa object at 0x' \
% (qux.__name__,) ), r) # % (qux.__name__,) ), r)
@unittest.skip('needs a built-in function with a really long name') @unittest.skip('needs a built-in function with a really long name')
def test_builtin_function(self): def test_builtin_function(self):

View file

@ -2544,13 +2544,13 @@ class IOTests(BaseTestCase):
a = stuff.__annotations__['a'] a = stuff.__annotations__['a']
self.assertEqual(a.__parameters__, ()) self.assertEqual(a.__parameters__, ())
def test_io_submodule(self): # def test_io_submodule(self):
from typing.io import IO, TextIO, BinaryIO, __all__, __name__ # from typing.io import IO, TextIO, BinaryIO, __all__, __name__
self.assertIs(IO, typing.IO) # self.assertIs(IO, typing.IO)
self.assertIs(TextIO, typing.TextIO) # self.assertIs(TextIO, typing.TextIO)
self.assertIs(BinaryIO, typing.BinaryIO) # self.assertIs(BinaryIO, typing.BinaryIO)
self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO'])) # self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO']))
self.assertEqual(__name__, 'typing.io') # self.assertEqual(__name__, 'typing.io')
class RETests(BaseTestCase): class RETests(BaseTestCase):
@ -2603,12 +2603,12 @@ class RETests(BaseTestCase):
self.assertEqual(repr(Match[str]), 'Match[str]') self.assertEqual(repr(Match[str]), 'Match[str]')
self.assertEqual(repr(Match[bytes]), 'Match[bytes]') self.assertEqual(repr(Match[bytes]), 'Match[bytes]')
def test_re_submodule(self): # def test_re_submodule(self):
from typing.re import Match, Pattern, __all__, __name__ # from typing.re import Match, Pattern, __all__, __name__
self.assertIs(Match, typing.Match) # self.assertIs(Match, typing.Match)
self.assertIs(Pattern, typing.Pattern) # self.assertIs(Pattern, typing.Pattern)
self.assertEqual(set(__all__), set(['Match', 'Pattern'])) # self.assertEqual(set(__all__), set(['Match', 'Pattern']))
self.assertEqual(__name__, 'typing.re') # self.assertEqual(__name__, 'typing.re')
def test_cannot_subclass(self): def test_cannot_subclass(self):
with self.assertRaises(TypeError) as ex: with self.assertRaises(TypeError) as ex:

View file

@ -15,6 +15,7 @@ import sys
import unittest import unittest
import warnings import warnings
from test import support, string_tests from test import support, string_tests
from encodings import utf_7, utf_16_le, utf_16_be, latin_1, unicode_internal, raw_unicode_escape
# Error handling (bad decoder return) # Error handling (bad decoder return)
def search_function(encoding): def search_function(encoding):
@ -2443,10 +2444,10 @@ class CAPITest(unittest.TestCase):
# Test PyUnicode_FromFormat() # Test PyUnicode_FromFormat()
def test_from_format(self): def test_from_format(self):
support.import_module('ctypes') support.import_module('ctypes')
from ctypes import ( # from ctypes import (
pythonapi, py_object, sizeof, # pythonapi, py_object, sizeof,
c_int, c_long, c_longlong, c_ssize_t, # c_int, c_long, c_longlong, c_ssize_t,
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p) # c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
name = "PyUnicode_FromFormat" name = "PyUnicode_FromFormat"
_PyUnicode_FromFormat = getattr(pythonapi, name) _PyUnicode_FromFormat = getattr(pythonapi, name)
_PyUnicode_FromFormat.restype = py_object _PyUnicode_FromFormat.restype = py_object
@ -2678,7 +2679,7 @@ class CAPITest(unittest.TestCase):
def test_aswidechar(self): def test_aswidechar(self):
from _testcapi import unicode_aswidechar from _testcapi import unicode_aswidechar
support.import_module('ctypes') support.import_module('ctypes')
from ctypes import c_wchar, sizeof # from ctypes import c_wchar, sizeof
wchar, size = unicode_aswidechar('abcdef', 2) wchar, size = unicode_aswidechar('abcdef', 2)
self.assertEqual(size, 2) self.assertEqual(size, 2)
@ -2716,7 +2717,7 @@ class CAPITest(unittest.TestCase):
def test_aswidecharstring(self): def test_aswidecharstring(self):
from _testcapi import unicode_aswidecharstring from _testcapi import unicode_aswidecharstring
support.import_module('ctypes') support.import_module('ctypes')
from ctypes import c_wchar, sizeof # from ctypes import c_wchar, sizeof
wchar, size = unicode_aswidecharstring('abc') wchar, size = unicode_aswidecharstring('abc')
self.assertEqual(size, 3) self.assertEqual(size, 3)

View file

@ -493,7 +493,7 @@ class TestUrlopen(unittest.TestCase):
def start_https_server(self, responses=None, **kwargs): def start_https_server(self, responses=None, **kwargs):
if not hasattr(urllib.request, 'HTTPSHandler'): if not hasattr(urllib.request, 'HTTPSHandler'):
self.skipTest('ssl support required') self.skipTest('ssl support required')
from test.ssl_servers import make_https_server # from test.ssl_servers import make_https_server
if responses is None: if responses is None:
responses = [(200, [], b"we care a bit")] responses = [(200, [], b"we care a bit")]
handler = GetRequestHandler(responses) handler = GetRequestHandler(responses)

View file

@ -14,6 +14,7 @@ import re
import io import io
import contextlib import contextlib
from test import support from test import support
from encodings import iso8559_15
try: try:
import gzip import gzip

View file

@ -32,16 +32,11 @@ from itertools import chain
import itertools as _itertools import itertools as _itertools
import re import re
import sys import sys
from token import * from token import AMPER, AMPEREQUAL, ASYNC, AT, ATEQUAL, AWAIT, CIRCUMFLEX, CIRCUMFLEXEQUAL, COLON, COMMA, DEDENT, DOT, DOUBLESLASH, DOUBLESLASHEQUAL, DOUBLESTAR, DOUBLESTAREQUAL, ELLIPSIS, ENDMARKER, EQEQUAL, EQUAL, ERRORTOKEN, GREATER, GREATEREQUAL, INDENT, ISEOF, ISNONTERMINAL, ISTERMINAL, LBRACE, LEFTSHIFT, LEFTSHIFTEQUAL, LESS, LESSEQUAL, LPAR, LSQB, MINEQUAL, MINUS, NAME, NEWLINE, NOTEQUAL, NT_OFFSET, NUMBER, N_TOKENS, OP, PERCENT, PERCENTEQUAL, PLUS, PLUSEQUAL, RARROW, RBRACE, RIGHTSHIFT, RIGHTSHIFTEQUAL, RPAR, RSQB, SEMI, SLASH, SLASHEQUAL, STAR, STAREQUAL, STRING, TILDE, VBAR, VBAREQUAL, tok_name
cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII) cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII)
blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII)
import token
__all__ = token.__all__ + ["COMMENT", "tokenize", "detect_encoding",
"NL", "untokenize", "ENCODING", "TokenInfo"]
del token
COMMENT = N_TOKENS COMMENT = N_TOKENS
tok_name[COMMENT] = 'COMMENT' tok_name[COMMENT] = 'COMMENT'
NL = N_TOKENS + 1 NL = N_TOKENS + 1

View file

@ -48,10 +48,8 @@ __all__ = ['TestResult', 'TestCase', 'TestSuite',
'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
'expectedFailure', 'TextTestResult', 'installHandler', 'expectedFailure', 'TextTestResult', 'installHandler',
'registerResult', 'removeResult', 'removeHandler'] 'registerResult', 'removeResult', 'removeHandler',
'getTestCaseNames', 'makeSuite', 'findTestCases']
# Expose obsolete functions for backwards compatibility
__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
__unittest = True __unittest = True
@ -61,7 +59,7 @@ from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf,
from .suite import BaseTestSuite, TestSuite from .suite import BaseTestSuite, TestSuite
from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames,
findTestCases) findTestCases)
from .main import TestProgram, main from ._main import TestProgram, main
from .runner import TextTestRunner, TextTestResult from .runner import TextTestRunner, TextTestResult
from .signals import installHandler, registerResult, removeResult, removeHandler from .signals import installHandler, registerResult, removeResult, removeHandler

View file

@ -13,6 +13,6 @@ if sys.argv[0].endswith("__main__.py"):
__unittest = True __unittest = True
from .main import main, TestProgram from ._main import main, TestProgram
main(module=None) main(module=None)

View file

@ -35,11 +35,6 @@ from functools import wraps, partial
_builtins = {name for name in dir(builtins) if not name.startswith('_')} _builtins = {name for name in dir(builtins) if not name.startswith('_')}
BaseExceptions = (BaseException,) BaseExceptions = (BaseException,)
if 'java' in sys.platform:
# jython
import java
BaseExceptions = (BaseException, java.lang.Throwable)
FILTER_DIR = True FILTER_DIR = True

View file

@ -131,6 +131,8 @@ __all__ = [
'pathname2url', 'url2pathname', 'getproxies', 'pathname2url', 'url2pathname', 'getproxies',
# Legacy interface # Legacy interface
'urlretrieve', 'urlcleanup', 'URLopener', 'FancyURLopener', 'urlretrieve', 'urlcleanup', 'URLopener', 'FancyURLopener',
# wut
'HTTPError',
] ]
# used in User-Agent header sent # used in User-Agent header sent
@ -2611,160 +2613,5 @@ def _proxy_bypass_macosx_sysconf(host, proxy_settings):
return False return False
getproxies = getproxies_environment
if sys.platform == 'darwin': proxy_bypass = proxy_bypass_environment
from _scproxy import _get_proxy_settings, _get_proxies
def proxy_bypass_macosx_sysconf(host):
proxy_settings = _get_proxy_settings()
return _proxy_bypass_macosx_sysconf(host, proxy_settings)
def getproxies_macosx_sysconf():
"""Return a dictionary of scheme -> proxy server URL mappings.
This function uses the MacOSX framework SystemConfiguration
to fetch the proxy information.
"""
return _get_proxies()
def proxy_bypass(host):
"""Return True, if host should be bypassed.
Checks proxy settings gathered from the environment, if specified,
or from the MacOSX framework SystemConfiguration.
"""
proxies = getproxies_environment()
if proxies:
return proxy_bypass_environment(host, proxies)
else:
return proxy_bypass_macosx_sysconf(host)
def getproxies():
return getproxies_environment() or getproxies_macosx_sysconf()
elif os.name == 'nt':
def getproxies_registry():
"""Return a dictionary of scheme -> proxy server URL mappings.
Win32 uses the registry to store proxies.
"""
proxies = {}
try:
import winreg
except ImportError:
# Std module, so should be around - but you never know!
return proxies
try:
internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
proxyEnable = winreg.QueryValueEx(internetSettings,
'ProxyEnable')[0]
if proxyEnable:
# Returned as Unicode but problems if not converted to ASCII
proxyServer = str(winreg.QueryValueEx(internetSettings,
'ProxyServer')[0])
if '=' in proxyServer:
# Per-protocol settings
for p in proxyServer.split(';'):
protocol, address = p.split('=', 1)
# See if address has a type:// prefix
if not re.match('^([^/:]+)://', address):
address = '%s://%s' % (protocol, address)
proxies[protocol] = address
else:
# Use one setting for all protocols
if proxyServer[:5] == 'http:':
proxies['http'] = proxyServer
else:
proxies['http'] = 'http://%s' % proxyServer
proxies['https'] = 'https://%s' % proxyServer
proxies['ftp'] = 'ftp://%s' % proxyServer
internetSettings.Close()
except (OSError, ValueError, TypeError):
# Either registry key not found etc, or the value in an
# unexpected format.
# proxies already set up to be empty so nothing to do
pass
return proxies
def getproxies():
"""Return a dictionary of scheme -> proxy server URL mappings.
Returns settings gathered from the environment, if specified,
or the registry.
"""
return getproxies_environment() or getproxies_registry()
def proxy_bypass_registry(host):
try:
import winreg
except ImportError:
# Std modules, so should be around - but you never know!
return 0
try:
internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
proxyEnable = winreg.QueryValueEx(internetSettings,
'ProxyEnable')[0]
proxyOverride = str(winreg.QueryValueEx(internetSettings,
'ProxyOverride')[0])
# ^^^^ Returned as Unicode but problems if not converted to ASCII
except OSError:
return 0
if not proxyEnable or not proxyOverride:
return 0
# try to make a host list from name and IP address.
rawHost, port = splitport(host)
host = [rawHost]
try:
addr = socket.gethostbyname(rawHost)
if addr != rawHost:
host.append(addr)
except OSError:
pass
try:
fqdn = socket.getfqdn(rawHost)
if fqdn != rawHost:
host.append(fqdn)
except OSError:
pass
# make a check value list from the registry entry: replace the
# '<local>' string by the localhost entry and the corresponding
# canonical entry.
proxyOverride = proxyOverride.split(';')
# now check if we match one of the registry values.
for test in proxyOverride:
if test == '<local>':
if '.' not in rawHost:
return 1
test = test.replace(".", r"\.") # mask dots
test = test.replace("*", r".*") # change glob sequence
test = test.replace("?", r".") # change glob char
for val in host:
if re.match(test, val, re.I):
return 1
return 0
def proxy_bypass(host):
"""Return True, if host should be bypassed.
Checks proxy settings gathered from the environment, if specified,
or the registry.
"""
proxies = getproxies_environment()
if proxies:
return proxy_bypass_environment(host, proxies)
else:
return proxy_bypass_registry(host)
else:
# By default use environment variables
getproxies = getproxies_environment
proxy_bypass = proxy_bypass_environment

View file

@ -444,7 +444,7 @@ def _ipconfig_getnode():
def _netbios_getnode(): def _netbios_getnode():
"""Get the hardware address on Windows using NetBIOS calls. """Get the hardware address on Windows using NetBIOS calls.
See http://support.microsoft.com/kb/118623 for details.""" See http://support.microsoft.com/kb/118623 for details."""
import win32wnet, netbios # import win32wnet, netbios
ncb = netbios.NCB() ncb = netbios.NCB()
ncb.Command = netbios.NCBENUM ncb.Command = netbios.NCBENUM
ncb.Buffer = adapters = netbios.LANA_ENUM() ncb.Buffer = adapters = netbios.LANA_ENUM()

View file

@ -1,7 +1,27 @@
"""Interface to the Expat non-validating XML parser.""" """Interface to the Expat non-validating XML parser."""
__all__ = [
'EXPAT_VERSION',
'ErrorString',
'ExpatError',
'ParserCreate',
'XMLParserType',
'XML_PARAM_ENTITY_PARSING_ALWAYS',
'XML_PARAM_ENTITY_PARSING_NEVER',
'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE',
'error',
'errors',
'expat_CAPI',
'features',
'model',
'native_encoding',
'sys',
'version_info',
]
import sys import sys
from pyexpat import * from pyexpat import EXPAT_VERSION, ErrorString, ExpatError, ParserCreate, XMLParserType, XML_PARAM_ENTITY_PARSING_ALWAYS, XML_PARAM_ENTITY_PARSING_NEVER, XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, error, errors, expat_CAPI, features, model, native_encoding, version_info
# provide pyexpat submodules as xml.parsers.expat submodules # provide pyexpat submodules as xml.parsers.expat submodules
sys.modules['xml.parsers.expat.model'] = model sys.modules['xml.parsers.expat.model'] = model

View file

@ -95,7 +95,7 @@ def make_parser(parser_list = []):
if sys.platform[ : 4] == "java": if sys.platform[ : 4] == "java":
def _create_parser(parser_name): def _create_parser(parser_name):
from org.python.core import imp # from org.python.core import imp
drv_module = imp.importName(parser_name, 0, globals()) drv_module = imp.importName(parser_name, 0, globals())
return drv_module.create_parser() return drv_module.create_parser()

View file

@ -1,8 +1,4 @@
"""Different kinds of SAX Exceptions""" """Different kinds of SAX Exceptions"""
import sys
if sys.platform[:4] == "java":
from java.lang import Exception
del sys
# ===== SAXEXCEPTION ===== # ===== SAXEXCEPTION =====

View file

@ -24,6 +24,8 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_asyncio"); PYTHON_PROVIDE("_asyncio");
PYTHON_PROVIDE("_asyncio.Future");
PYTHON_PROVIDE("_asyncio.Task");
/*[clinic input] /*[clinic input]
module _asyncio module _asyncio

View file

@ -15,6 +15,12 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_bisect"); PYTHON_PROVIDE("_bisect");
PYTHON_PROVIDE("_bisect.bisect");
PYTHON_PROVIDE("_bisect.bisect_left");
PYTHON_PROVIDE("_bisect.bisect_right");
PYTHON_PROVIDE("_bisect.insort");
PYTHON_PROVIDE("_bisect.insort_left");
PYTHON_PROVIDE("_bisect.insort_right");
/* Bisection algorithms. Drop in replacement for bisect.py /* Bisection algorithms. Drop in replacement for bisect.py

View file

@ -1,10 +1,26 @@
/* clang-format off */ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
/* _bz2 - Low-level Python interface to libbzip2. */ vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Python 3
https://docs.python.org/3/license.html │
*/
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include "third_party/bzip2/bzlib.h"
#include "third_party/python/Include/Python.h" #include "third_party/python/Include/abstract.h"
#include "third_party/python/Include/bytesobject.h"
#include "third_party/python/Include/ceval.h"
#include "third_party/python/Include/modsupport.h"
#include "third_party/python/Include/object.h"
#include "third_party/python/Include/pyerrors.h"
#include "third_party/python/Include/pymacro.h"
#include "third_party/python/Include/pymem.h"
#include "third_party/python/Include/structmember.h" #include "third_party/python/Include/structmember.h"
#include "third_party/python/Include/yoink.h"
/* clang-format off */
PYTHON_PROVIDE("_bz2");
PYTHON_PROVIDE("_bz2.BZ2Compressor");
PYTHON_PROVIDE("_bz2.BZ2Decompressor");
#ifdef WITH_THREAD #ifdef WITH_THREAD
#include "third_party/python/Include/pythread.h" #include "third_party/python/Include/pythread.h"
@ -17,8 +33,7 @@
#define BZ2_bzDecompress bzDecompress #define BZ2_bzDecompress bzDecompress
#define BZ2_bzDecompressInit bzDecompressInit #define BZ2_bzDecompressInit bzDecompressInit
#define BZ2_bzDecompressEnd bzDecompressEnd #define BZ2_bzDecompressEnd bzDecompressEnd
#endif /* ! BZ_CONFIG_ERROR */ #endif /* !BZ_CONFIG_ERROR */
#ifdef WITH_THREAD #ifdef WITH_THREAD
#define ACQUIRE_LOCK(obj) do { \ #define ACQUIRE_LOCK(obj) do { \
@ -33,7 +48,6 @@
#define RELEASE_LOCK(obj) #define RELEASE_LOCK(obj)
#endif #endif
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
bz_stream bzs; bz_stream bzs;
@ -76,7 +90,6 @@ catch_bz2_error(int bzerror)
case BZ_FINISH_OK: case BZ_FINISH_OK:
case BZ_STREAM_END: case BZ_STREAM_END:
return 0; return 0;
#ifdef BZ_CONFIG_ERROR #ifdef BZ_CONFIG_ERROR
case BZ_CONFIG_ERROR: case BZ_CONFIG_ERROR:
PyErr_SetString(PyExc_SystemError, PyErr_SetString(PyExc_SystemError,

View file

@ -18,6 +18,47 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_codecs"); PYTHON_PROVIDE("_codecs");
PYTHON_PROVIDE("_codecs._forget_codec");
PYTHON_PROVIDE("_codecs.ascii_decode");
PYTHON_PROVIDE("_codecs.ascii_encode");
PYTHON_PROVIDE("_codecs.charmap_build");
PYTHON_PROVIDE("_codecs.charmap_decode");
PYTHON_PROVIDE("_codecs.charmap_encode");
PYTHON_PROVIDE("_codecs.decode");
PYTHON_PROVIDE("_codecs.encode");
PYTHON_PROVIDE("_codecs.escape_decode");
PYTHON_PROVIDE("_codecs.escape_encode");
PYTHON_PROVIDE("_codecs.latin_1_decode");
PYTHON_PROVIDE("_codecs.latin_1_encode");
PYTHON_PROVIDE("_codecs.lookup");
PYTHON_PROVIDE("_codecs.lookup_error");
PYTHON_PROVIDE("_codecs.raw_unicode_escape_decode");
PYTHON_PROVIDE("_codecs.raw_unicode_escape_encode");
PYTHON_PROVIDE("_codecs.readbuffer_encode");
PYTHON_PROVIDE("_codecs.register");
PYTHON_PROVIDE("_codecs.register_error");
PYTHON_PROVIDE("_codecs.unicode_escape_decode");
PYTHON_PROVIDE("_codecs.unicode_escape_encode");
PYTHON_PROVIDE("_codecs.unicode_internal_decode");
PYTHON_PROVIDE("_codecs.unicode_internal_encode");
PYTHON_PROVIDE("_codecs.utf_16_be_decode");
PYTHON_PROVIDE("_codecs.utf_16_be_encode");
PYTHON_PROVIDE("_codecs.utf_16_decode");
PYTHON_PROVIDE("_codecs.utf_16_encode");
PYTHON_PROVIDE("_codecs.utf_16_ex_decode");
PYTHON_PROVIDE("_codecs.utf_16_le_decode");
PYTHON_PROVIDE("_codecs.utf_16_le_encode");
PYTHON_PROVIDE("_codecs.utf_32_be_decode");
PYTHON_PROVIDE("_codecs.utf_32_be_encode");
PYTHON_PROVIDE("_codecs.utf_32_decode");
PYTHON_PROVIDE("_codecs.utf_32_encode");
PYTHON_PROVIDE("_codecs.utf_32_ex_decode");
PYTHON_PROVIDE("_codecs.utf_32_le_decode");
PYTHON_PROVIDE("_codecs.utf_32_le_encode");
PYTHON_PROVIDE("_codecs.utf_7_decode");
PYTHON_PROVIDE("_codecs.utf_7_encode");
PYTHON_PROVIDE("_codecs.utf_8_decode");
PYTHON_PROVIDE("_codecs.utf_8_encode");
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------

View file

@ -17,6 +17,12 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_collections"); PYTHON_PROVIDE("_collections");
PYTHON_PROVIDE("_collections.OrderedDict");
PYTHON_PROVIDE("_collections._count_elements");
PYTHON_PROVIDE("_collections._deque_iterator");
PYTHON_PROVIDE("_collections._deque_reverse_iterator");
PYTHON_PROVIDE("_collections.defaultdict");
PYTHON_PROVIDE("_collections.deque");
/* collections module implementation of a deque() datatype /* collections module implementation of a deque() datatype
Written and maintained by Raymond D. Hettinger <python@rcn.com> Written and maintained by Raymond D. Hettinger <python@rcn.com>

View file

@ -11,6 +11,7 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_crypt"); PYTHON_PROVIDE("_crypt");
PYTHON_PROVIDE("_crypt.crypt");
/* cryptmodule.c - by Steve Majewski /* cryptmodule.c - by Steve Majewski
*/ */

View file

@ -1,3 +1,9 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Python 3
https://docs.python.org/3/license.html │
*/
#include "third_party/python/Include/abstract.h" #include "third_party/python/Include/abstract.h"
#include "third_party/python/Include/descrobject.h" #include "third_party/python/Include/descrobject.h"
#include "third_party/python/Include/dictobject.h" #include "third_party/python/Include/dictobject.h"
@ -14,6 +20,26 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_csv"); PYTHON_PROVIDE("_csv");
PYTHON_PROVIDE("_csv.Dialect");
PYTHON_PROVIDE("_csv.Error");
PYTHON_PROVIDE("_csv.QUOTE_ALL");
PYTHON_PROVIDE("_csv.QUOTE_MINIMAL");
PYTHON_PROVIDE("_csv.QUOTE_NONE");
PYTHON_PROVIDE("_csv.QUOTE_NONNUMERIC");
PYTHON_PROVIDE("_csv.__doc__");
PYTHON_PROVIDE("_csv.__loader__");
PYTHON_PROVIDE("_csv.__name__");
PYTHON_PROVIDE("_csv.__package__");
PYTHON_PROVIDE("_csv.__spec__");
PYTHON_PROVIDE("_csv.__version__");
PYTHON_PROVIDE("_csv._dialects");
PYTHON_PROVIDE("_csv.field_size_limit");
PYTHON_PROVIDE("_csv.get_dialect");
PYTHON_PROVIDE("_csv.list_dialects");
PYTHON_PROVIDE("_csv.reader");
PYTHON_PROVIDE("_csv.register_dialect");
PYTHON_PROVIDE("_csv.unregister_dialect");
PYTHON_PROVIDE("_csv.writer");
/* /*

View file

@ -8,6 +8,12 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_curses_panel"); PYTHON_PROVIDE("_curses_panel");
PYTHON_PROVIDE("_curses_panel.bottom_panel");
PYTHON_PROVIDE("_curses_panel.error");
PYTHON_PROVIDE("_curses_panel.new_panel");
PYTHON_PROVIDE("_curses_panel.top_panel");
PYTHON_PROVIDE("_curses_panel.update_panels");
PYTHON_PROVIDE("_curses_panel.version");
/* /*
* Interface to the ncurses panel library * Interface to the ncurses panel library

View file

@ -29,6 +29,20 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_datetime"); PYTHON_PROVIDE("_datetime");
PYTHON_PROVIDE("_datetime.MAXYEAR");
PYTHON_PROVIDE("_datetime.MINYEAR");
PYTHON_PROVIDE("_datetime.__doc__");
PYTHON_PROVIDE("_datetime.__loader__");
PYTHON_PROVIDE("_datetime.__name__");
PYTHON_PROVIDE("_datetime.__package__");
PYTHON_PROVIDE("_datetime.__spec__");
PYTHON_PROVIDE("_datetime.date");
PYTHON_PROVIDE("_datetime.datetime");
PYTHON_PROVIDE("_datetime.datetime_CAPI");
PYTHON_PROVIDE("_datetime.time");
PYTHON_PROVIDE("_datetime.timedelta");
PYTHON_PROVIDE("_datetime.timezone");
PYTHON_PROVIDE("_datetime.tzinfo");
/* C implementation for the date/time type documented at /* C implementation for the date/time type documented at
* http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage

View file

@ -51,6 +51,49 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_decimal"); PYTHON_PROVIDE("_decimal");
PYTHON_PROVIDE("_decimal.BasicContext");
PYTHON_PROVIDE("_decimal.Clamped");
PYTHON_PROVIDE("_decimal.Context");
PYTHON_PROVIDE("_decimal.ConversionSyntax");
PYTHON_PROVIDE("_decimal.Decimal");
PYTHON_PROVIDE("_decimal.DecimalException");
PYTHON_PROVIDE("_decimal.DecimalTuple");
PYTHON_PROVIDE("_decimal.DefaultContext");
PYTHON_PROVIDE("_decimal.DivisionByZero");
PYTHON_PROVIDE("_decimal.DivisionImpossible");
PYTHON_PROVIDE("_decimal.DivisionUndefined");
PYTHON_PROVIDE("_decimal.ExtendedContext");
PYTHON_PROVIDE("_decimal.FloatOperation");
PYTHON_PROVIDE("_decimal.HAVE_THREADS");
PYTHON_PROVIDE("_decimal.Inexact");
PYTHON_PROVIDE("_decimal.InvalidContext");
PYTHON_PROVIDE("_decimal.InvalidOperation");
PYTHON_PROVIDE("_decimal.MAX_EMAX");
PYTHON_PROVIDE("_decimal.MAX_PREC");
PYTHON_PROVIDE("_decimal.MIN_EMIN");
PYTHON_PROVIDE("_decimal.MIN_ETINY");
PYTHON_PROVIDE("_decimal.Overflow");
PYTHON_PROVIDE("_decimal.ROUND_05UP");
PYTHON_PROVIDE("_decimal.ROUND_CEILING");
PYTHON_PROVIDE("_decimal.ROUND_DOWN");
PYTHON_PROVIDE("_decimal.ROUND_FLOOR");
PYTHON_PROVIDE("_decimal.ROUND_HALF_DOWN");
PYTHON_PROVIDE("_decimal.ROUND_HALF_EVEN");
PYTHON_PROVIDE("_decimal.ROUND_HALF_UP");
PYTHON_PROVIDE("_decimal.ROUND_UP");
PYTHON_PROVIDE("_decimal.Rounded");
PYTHON_PROVIDE("_decimal.Subnormal");
PYTHON_PROVIDE("_decimal.Underflow");
PYTHON_PROVIDE("_decimal.__doc__");
PYTHON_PROVIDE("_decimal.__libmpdec_version__");
PYTHON_PROVIDE("_decimal.__loader__");
PYTHON_PROVIDE("_decimal.__name__");
PYTHON_PROVIDE("_decimal.__package__");
PYTHON_PROVIDE("_decimal.__spec__");
PYTHON_PROVIDE("_decimal.__version__");
PYTHON_PROVIDE("_decimal.getcontext");
PYTHON_PROVIDE("_decimal.localcontext");
PYTHON_PROVIDE("_decimal.setcontext");
asm(".ident\t\"\\n\ asm(".ident\t\"\\n\
libmpdec (BSD-2)\\n\ libmpdec (BSD-2)\\n\
@ -5948,3 +5991,8 @@ error:
return NULL; /* GCOV_NOT_REACHED */ return NULL; /* GCOV_NOT_REACHED */
} }
_Section(".rodata.pytab") struct _inittab _PyImport_Inittab__decimal = {
"_decimal",
PyInit__decimal,
};

View file

@ -26,6 +26,11 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_elementtree"); PYTHON_PROVIDE("_elementtree");
PYTHON_PROVIDE("_elementtree.Element");
PYTHON_PROVIDE("_elementtree.ParseError");
PYTHON_PROVIDE("_elementtree.SubElement");
PYTHON_PROVIDE("_elementtree.TreeBuilder");
PYTHON_PROVIDE("_elementtree.XMLParser");
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Licensed to PSF under a Contributor Agreement. * Licensed to PSF under a Contributor Agreement.

View file

@ -21,6 +21,10 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_functools"); PYTHON_PROVIDE("_functools");
PYTHON_PROVIDE("_functools._lru_cache_wrapper");
PYTHON_PROVIDE("_functools.cmp_to_key");
PYTHON_PROVIDE("_functools.partial");
PYTHON_PROVIDE("_functools.reduce");
/* _functools module written and maintained /* _functools module written and maintained
by Hye-Shik Chang <perky@FreeBSD.org> by Hye-Shik Chang <perky@FreeBSD.org>

View file

@ -1,30 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Python 3
https://docs.python.org/3/license.html │
*/
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include "third_party/mbedtls/md.h"
#include "third_party/python/Include/Python.h" #include "third_party/python/Include/Python.h"
#include "third_party/python/Include/hashlib.h"
#include "third_party/python/Include/pystrhex.h" #include "third_party/python/Include/pystrhex.h"
#include "third_party/python/Include/structmember.h" #include "third_party/python/Include/structmember.h"
#include "third_party/python/Include/yoink.h" #include "third_party/python/Include/yoink.h"
#include "third_party/python/Modules/hashlib.h"
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_hashlib"); PYTHON_PROVIDE("_hashlib");
PYTHON_PROVIDE("_hashlib.HASH");
/* Module that wraps all OpenSSL hash algorithms */ PYTHON_PROVIDE("_hashlib.__doc__");
/* PYTHON_PROVIDE("_hashlib.__loader__");
* Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org) PYTHON_PROVIDE("_hashlib.__name__");
* Licensed to PSF under a Contributor Agreement. PYTHON_PROVIDE("_hashlib.__package__");
* PYTHON_PROVIDE("_hashlib.__spec__");
* Derived from a skeleton of shamodule.c containing work performed by: PYTHON_PROVIDE("_hashlib.new");
* PYTHON_PROVIDE("_hashlib.openssl_md5");
* Andrew Kuchling (amk@amk.ca) PYTHON_PROVIDE("_hashlib.openssl_md_meth_names");
* Greg Stein (gstein@lyra.org) PYTHON_PROVIDE("_hashlib.openssl_sha1");
* PYTHON_PROVIDE("_hashlib.openssl_sha224");
*/ PYTHON_PROVIDE("_hashlib.openssl_sha256");
PYTHON_PROVIDE("_hashlib.openssl_sha384");
/* EVP is the preferred interface to hashing in OpenSSL */ PYTHON_PROVIDE("_hashlib.openssl_sha512");
#include <openssl/evp.h>
/* We use the object interface to discover what hashes OpenSSL supports. */
#include <openssl/objects.h>
#include "openssl/err.h"
#include "third_party/python/Modules/clinic/_hashopenssl.inc" #include "third_party/python/Modules/clinic/_hashopenssl.inc"
/*[clinic input] /*[clinic input]
@ -38,34 +41,26 @@ module _hashlib
#define HASH_OBJ_CONSTRUCTOR 0 #define HASH_OBJ_CONSTRUCTOR 0
#endif #endif
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
/* OpenSSL < 1.1.0 */
#define EVP_MD_CTX_new EVP_MD_CTX_create
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
#define HAS_FAST_PKCS5_PBKDF2_HMAC 0
#include <openssl/hmac.h>
#else
/* OpenSSL >= 1.1.0 */
#define HAS_FAST_PKCS5_PBKDF2_HMAC 1
#endif
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
PyObject *name; /* name of this hash algorithm */ PyObject *name;
EVP_MD_CTX *ctx; /* OpenSSL message digest context */ mbedtls_md_context_t *ctx;
#ifdef WITH_THREAD #ifdef WITH_THREAD
PyThread_type_lock lock; /* OpenSSL context lock */ PyThread_type_lock lock;
#endif #endif
} EVPobject; } EVPobject;
static PyTypeObject EVPtype; static PyTypeObject EVPtype;
static PyObject *CONST_md5_name_obj;
static PyObject *CONST_sha1_name_obj;
static PyObject *CONST_sha224_name_obj;
static PyObject *CONST_sha256_name_obj;
static PyObject *CONST_sha384_name_obj;
static PyObject *CONST_sha512_name_obj;
#define DEFINE_CONSTS_FOR_NEW(Name) \ #define DEFINE_CONSTS_FOR_NEW(Name) \
static PyObject *CONST_ ## Name ## _name_obj = NULL; \ static PyObject *CONST_ ## Name ## _name_obj = NULL; \
static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL; static mbedtls_md_context_t *CONST_new_ ## Name ## _ctx_p = NULL;
DEFINE_CONSTS_FOR_NEW(md5) DEFINE_CONSTS_FOR_NEW(md5)
DEFINE_CONSTS_FOR_NEW(sha1) DEFINE_CONSTS_FOR_NEW(sha1)
@ -74,34 +69,31 @@ DEFINE_CONSTS_FOR_NEW(sha256)
DEFINE_CONSTS_FOR_NEW(sha384) DEFINE_CONSTS_FOR_NEW(sha384)
DEFINE_CONSTS_FOR_NEW(sha512) DEFINE_CONSTS_FOR_NEW(sha512)
/* LCOV_EXCL_START */ /* LCOV_EXCL_START */
static PyObject * static PyObject *
_setException(PyObject *exc) _setException(PyObject *exc)
{ {
unsigned long errcode; /* unsigned long errcode; */
const char *lib, *func, *reason; /* const char *lib, *func, *reason; */
/* errcode = ERR_peek_last_error(); */
errcode = ERR_peek_last_error(); /* if (!errcode) { */
if (!errcode) { /* PyErr_SetString(exc, "unknown reasons"); */
PyErr_SetString(exc, "unknown reasons"); /* return NULL; */
return NULL; /* } */
} /* ERR_clear_error(); */
ERR_clear_error(); /* lib = ERR_lib_error_string(errcode); */
/* func = ERR_func_error_string(errcode); */
lib = ERR_lib_error_string(errcode); /* reason = ERR_reason_error_string(errcode); */
func = ERR_func_error_string(errcode); /* if (lib && func) { */
reason = ERR_reason_error_string(errcode); /* PyErr_Format(exc, "[%s: %s] %s", lib, func, reason); */
/* } */
if (lib && func) { /* else if (lib) { */
PyErr_Format(exc, "[%s: %s] %s", lib, func, reason); /* PyErr_Format(exc, "[%s] %s", lib, reason); */
} /* } */
else if (lib) { /* else { */
PyErr_Format(exc, "[%s] %s", lib, reason); /* PyErr_SetString(exc, reason); */
} /* } */
else { PyErr_SetString(exc, "failhouse");
PyErr_SetString(exc, reason);
}
return NULL; return NULL;
} }
/* LCOV_EXCL_STOP */ /* LCOV_EXCL_STOP */
@ -113,20 +105,17 @@ newEVPobject(PyObject *name)
if (retval == NULL) { if (retval == NULL) {
return NULL; return NULL;
} }
retval->ctx = calloc(1, sizeof(mbedtls_md_context_t));
retval->ctx = EVP_MD_CTX_new();
if (retval->ctx == NULL) { if (retval->ctx == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
} }
/* save the name for .name to return */ /* save the name for .name to return */
Py_INCREF(name); Py_INCREF(name);
retval->name = name; retval->name = name;
#ifdef WITH_THREAD #ifdef WITH_THREAD
retval->lock = NULL; retval->lock = NULL;
#endif #endif
return retval; return retval;
} }
@ -140,7 +129,7 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
process = MUNCH_SIZE; process = MUNCH_SIZE;
else else
process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) { if (!mbedtls_md_update(self->ctx, (const void*)cp, process)) {
_setException(PyExc_ValueError); _setException(PyExc_ValueError);
break; break;
} }
@ -158,17 +147,19 @@ EVP_dealloc(EVPobject *self)
if (self->lock != NULL) if (self->lock != NULL)
PyThread_free_lock(self->lock); PyThread_free_lock(self->lock);
#endif #endif
EVP_MD_CTX_free(self->ctx); mbedtls_md_free(self->ctx);
free(self->ctx);
Py_XDECREF(self->name); Py_XDECREF(self->name);
PyObject_Del(self); PyObject_Del(self);
} }
static int static int
locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) locked_mbedtls_md_clone(mbedtls_md_context_t *new_ctx_p, EVPobject *self)
{ {
int result; int result;
ENTER_HASHLIB(self); ENTER_HASHLIB(self);
result = EVP_MD_CTX_copy(new_ctx_p, self->ctx); result = mbedtls_md_clone(new_ctx_p, self->ctx);
result = 0;
LEAVE_HASHLIB(self); LEAVE_HASHLIB(self);
return result; return result;
} }
@ -177,16 +168,13 @@ locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object."); PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object.");
static PyObject * static PyObject *
EVP_copy(EVPobject *self, PyObject *unused) EVP_copy(EVPobject *self, PyObject *unused)
{ {
EVPobject *newobj; EVPobject *newobj;
if ( (newobj = newEVPobject(self->name))==NULL) if ( (newobj = newEVPobject(self->name))==NULL)
return NULL; return NULL;
if (!locked_mbedtls_md_clone(newobj->ctx, self)) {
if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
return _setException(PyExc_ValueError); return _setException(PyExc_ValueError);
} }
return (PyObject *)newobj; return (PyObject *)newobj;
@ -198,28 +186,25 @@ PyDoc_STRVAR(EVP_digest__doc__,
static PyObject * static PyObject *
EVP_digest(EVPobject *self, PyObject *unused) EVP_digest(EVPobject *self, PyObject *unused)
{ {
unsigned char digest[EVP_MAX_MD_SIZE]; unsigned char digest[MBEDTLS_MD_MAX_SIZE];
EVP_MD_CTX *temp_ctx; mbedtls_md_context_t *temp_ctx;
PyObject *retval; PyObject *retval;
unsigned int digest_size; unsigned int digest_size;
temp_ctx = calloc(1, sizeof(mbedtls_md_context_t));
temp_ctx = EVP_MD_CTX_new();
if (temp_ctx == NULL) { if (temp_ctx == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
} }
if (!locked_mbedtls_md_clone(temp_ctx, self)) {
if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
return _setException(PyExc_ValueError); return _setException(PyExc_ValueError);
} }
digest_size = EVP_MD_CTX_size(temp_ctx); digest_size = mbedtls_md_get_size(temp_ctx->md_info);
if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { if (!mbedtls_md_finish(temp_ctx, digest)) {
_setException(PyExc_ValueError); _setException(PyExc_ValueError);
return NULL; return NULL;
} }
retval = PyBytes_FromStringAndSize((const char *)digest, digest_size); retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
EVP_MD_CTX_free(temp_ctx); mbedtls_md_free(temp_ctx);
return retval; return retval;
} }
@ -229,28 +214,24 @@ PyDoc_STRVAR(EVP_hexdigest__doc__,
static PyObject * static PyObject *
EVP_hexdigest(EVPobject *self, PyObject *unused) EVP_hexdigest(EVPobject *self, PyObject *unused)
{ {
unsigned char digest[EVP_MAX_MD_SIZE]; unsigned char digest[MBEDTLS_MD_MAX_SIZE];
EVP_MD_CTX *temp_ctx; mbedtls_md_context_t *temp_ctx;
unsigned int digest_size; unsigned int digest_size;
temp_ctx = calloc(1, sizeof(mbedtls_md_context_t));
temp_ctx = EVP_MD_CTX_new();
if (temp_ctx == NULL) { if (temp_ctx == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
} }
/* Get the raw (binary) digest value */ /* Get the raw (binary) digest value */
if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { if (!locked_mbedtls_md_clone(temp_ctx, self)) {
return _setException(PyExc_ValueError); return _setException(PyExc_ValueError);
} }
digest_size = EVP_MD_CTX_size(temp_ctx); digest_size = mbedtls_md_get_size(temp_ctx->md_info);
if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { if (!mbedtls_md_finish(temp_ctx, digest)) {
_setException(PyExc_ValueError); _setException(PyExc_ValueError);
return NULL; return NULL;
} }
mbedtls_md_free(temp_ctx);
EVP_MD_CTX_free(temp_ctx);
return _Py_strhex((const char *)digest, digest_size); return _Py_strhex((const char *)digest, digest_size);
} }
@ -262,18 +243,14 @@ EVP_update(EVPobject *self, PyObject *args)
{ {
PyObject *obj; PyObject *obj;
Py_buffer view; Py_buffer view;
if (!PyArg_ParseTuple(args, "O:update", &obj)) if (!PyArg_ParseTuple(args, "O:update", &obj))
return NULL; return NULL;
GET_BUFFER_VIEW_OR_ERROUT(obj, &view); GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
#ifdef WITH_THREAD #ifdef WITH_THREAD
if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) { if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
self->lock = PyThread_allocate_lock(); self->lock = PyThread_allocate_lock();
/* fail? lock = NULL and we fail over to non-threaded code. */ /* fail? lock = NULL and we fail over to non-threaded code. */
} }
if (self->lock != NULL) { if (self->lock != NULL) {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
PyThread_acquire_lock(self->lock, 1); PyThread_acquire_lock(self->lock, 1);
@ -286,7 +263,6 @@ EVP_update(EVPobject *self, PyObject *args)
#else #else
EVP_hash(self, view.buf, view.len); EVP_hash(self, view.buf, view.len);
#endif #endif
PyBuffer_Release(&view); PyBuffer_Release(&view);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -303,7 +279,7 @@ static PyObject *
EVP_get_block_size(EVPobject *self, void *closure) EVP_get_block_size(EVPobject *self, void *closure)
{ {
long block_size; long block_size;
block_size = EVP_MD_CTX_block_size(self->ctx); block_size = mbedtls_md_get_block_size(self->ctx->md_info);
return PyLong_FromLong(block_size); return PyLong_FromLong(block_size);
} }
@ -311,7 +287,7 @@ static PyObject *
EVP_get_digest_size(EVPobject *self, void *closure) EVP_get_digest_size(EVPobject *self, void *closure)
{ {
long size; long size;
size = EVP_MD_CTX_size(self->ctx); size = mbedtls_md_get_size(self->ctx->md_info);
return PyLong_FromLong(size); return PyLong_FromLong(size);
} }
@ -348,24 +324,20 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
PyObject *data_obj = NULL; PyObject *data_obj = NULL;
Py_buffer view; Py_buffer view;
char *nameStr; char *nameStr;
const EVP_MD *digest; const mbedtls_md_info_t *digest;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:HASH", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:HASH", kwlist,
&name_obj, &data_obj)) { &name_obj, &data_obj)) {
return -1; return -1;
} }
if (data_obj) if (data_obj)
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
if (!PyArg_Parse(name_obj, "s", &nameStr)) { if (!PyArg_Parse(name_obj, "s", &nameStr)) {
PyErr_SetString(PyExc_TypeError, "name must be a string"); PyErr_SetString(PyExc_TypeError, "name must be a string");
if (data_obj) if (data_obj)
PyBuffer_Release(&view); PyBuffer_Release(&view);
return -1; return -1;
} }
digest = mbedtls_md_info_from_string(nameStr);
digest = EVP_get_digestbyname(nameStr);
if (!digest) { if (!digest) {
PyErr_SetString(PyExc_ValueError, "unknown hash function"); PyErr_SetString(PyExc_ValueError, "unknown hash function");
if (data_obj) if (data_obj)
@ -378,10 +350,8 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
PyBuffer_Release(&view); PyBuffer_Release(&view);
return -1; return -1;
} }
Py_INCREF(name_obj); Py_INCREF(name_obj);
Py_XSETREF(self->name, name_obj); Py_XSETREF(self->name, name_obj);
if (data_obj) { if (data_obj) {
if (view.len >= HASHLIB_GIL_MINSIZE) { if (view.len >= HASHLIB_GIL_MINSIZE) {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
@ -392,12 +362,10 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
} }
PyBuffer_Release(&view); PyBuffer_Release(&view);
} }
return 0; return 0;
} }
#endif #endif
PyDoc_STRVAR(hashtype_doc, PyDoc_STRVAR(hashtype_doc,
"A hash represents the object used to calculate a checksum of a\n\ "A hash represents the object used to calculate a checksum of a\n\
string of information.\n\ string of information.\n\
@ -460,29 +428,26 @@ static PyTypeObject EVPtype = {
static PyObject * static PyObject *
EVPnew(PyObject *name_obj, EVPnew(PyObject *name_obj,
const EVP_MD *digest, const EVP_MD_CTX *initial_ctx, const mbedtls_md_info_t *digest,
const mbedtls_md_context_t *initial_ctx,
const unsigned char *cp, Py_ssize_t len) const unsigned char *cp, Py_ssize_t len)
{ {
EVPobject *self; EVPobject *self;
if (!digest && !initial_ctx) { if (!digest && !initial_ctx) {
PyErr_SetString(PyExc_ValueError, "unsupported hash type"); PyErr_SetString(PyExc_ValueError, "unsupported hash type");
return NULL; return NULL;
} }
if ((self = newEVPobject(name_obj)) == NULL) if ((self = newEVPobject(name_obj)) == NULL)
return NULL; return NULL;
if (initial_ctx) { if (initial_ctx) {
EVP_MD_CTX_copy(self->ctx, initial_ctx); mbedtls_md_clone(self->ctx, initial_ctx);
} else { } else {
if (!EVP_DigestInit(self->ctx, digest)) { if (!mbedtls_md_setup(self->ctx, digest, 0)) {
_setException(PyExc_ValueError); _setException(PyExc_ValueError);
Py_DECREF(self); Py_DECREF(self);
return NULL; return NULL;
} }
} }
if (cp && len) { if (cp && len) {
if (len >= HASHLIB_GIL_MINSIZE) { if (len >= HASHLIB_GIL_MINSIZE) {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
@ -492,7 +457,6 @@ EVPnew(PyObject *name_obj,
EVP_hash(self, cp, len); EVP_hash(self, cp, len);
} }
} }
return (PyObject *)self; return (PyObject *)self;
} }
@ -515,32 +479,24 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
Py_buffer view = { 0 }; Py_buffer view = { 0 };
PyObject *ret_obj; PyObject *ret_obj;
char *name; char *name;
const EVP_MD *digest; const mbedtls_md_info_t *digest;
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|O:new", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|O:new", kwlist,
&name_obj, &data_obj)) { &name_obj, &data_obj)) {
return NULL; return NULL;
} }
if (!PyArg_Parse(name_obj, "s", &name)) { if (!PyArg_Parse(name_obj, "s", &name)) {
PyErr_SetString(PyExc_TypeError, "name must be a string"); PyErr_SetString(PyExc_TypeError, "name must be a string");
return NULL; return NULL;
} }
if (data_obj) if (data_obj)
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
digest = mbedtls_md_info_from_string(name);
digest = EVP_get_digestbyname(name);
ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len); ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len);
if (data_obj) if (data_obj)
PyBuffer_Release(&view); PyBuffer_Release(&view);
return ret_obj; return ret_obj;
} }
#if (OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) \ #if (OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) \
&& !defined(OPENSSL_NO_SHA)) && !defined(OPENSSL_NO_SHA))
@ -560,15 +516,15 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
static int static int
PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen, PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen,
const unsigned char *salt, int saltlen, const unsigned char *salt, int saltlen,
int iter, const EVP_MD *digest, int iter, const mbedtls_md_info_t *digest,
int keylen, unsigned char *out) int keylen, unsigned char *out)
{ {
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; unsigned char digtmp[MBEDTLS_MD_MAX_SIZE], *p, itmp[4];
int cplen, j, k, tkeylen, mdlen; int cplen, j, k, tkeylen, mdlen;
unsigned long i = 1; unsigned long i = 1;
HMAC_CTX hctx_tpl, hctx; HMAC_CTX hctx_tpl, hctx;
mdlen = EVP_MD_size(digest); mdlen = mbedtls_md_get_size(digest);
if (mdlen < 0) if (mdlen < 0)
return 0; return 0;
@ -647,7 +603,7 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
Py_buffer password, salt; Py_buffer password, salt;
long iterations, dklen; long iterations, dklen;
int retval; int retval;
const EVP_MD *digest; const mbedtls_md_info_t *digest;
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "sy*y*l|O:pbkdf2_hmac", if (!PyArg_ParseTupleAndKeywords(args, kwdict, "sy*y*l|O:pbkdf2_hmac",
kwlist, &name, &password, &salt, kwlist, &name, &password, &salt,
@ -655,7 +611,7 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
return NULL; return NULL;
} }
digest = EVP_get_digestbyname(name); digest = mbedtls_md_info_from_string(name);
if (digest == NULL) { if (digest == NULL) {
PyErr_SetString(PyExc_ValueError, "unsupported hash type"); PyErr_SetString(PyExc_ValueError, "unsupported hash type");
goto end; goto end;
@ -685,7 +641,7 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
} }
if (dklen_obj == Py_None) { if (dklen_obj == Py_None) {
dklen = EVP_MD_size(digest); dklen = mbedtls_md_get_size(digest);
} else { } else {
dklen = PyLong_AsLong(dklen_obj); dklen = PyLong_AsLong(dklen_obj);
if ((dklen == -1) && PyErr_Occurred()) { if ((dklen == -1) && PyErr_Occurred()) {
@ -740,7 +696,6 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
#if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER) #if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)
#define PY_SCRYPT 1 #define PY_SCRYPT 1
/* XXX: Parameters salt, n, r and p should be required keyword-only parameters. /* XXX: Parameters salt, n, r and p should be required keyword-only parameters.
They are optional in the Argument Clinic declaration only due to a They are optional in the Argument Clinic declaration only due to a
limitation of PyArg_ParseTupleAndKeywords. */ limitation of PyArg_ParseTupleAndKeywords. */
@ -760,7 +715,6 @@ _hashlib.scrypt
scrypt password-based key derivation function. scrypt password-based key derivation function.
[clinic start generated code]*/ [clinic start generated code]*/
static PyObject * static PyObject *
_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
PyObject *n_obj, PyObject *r_obj, PyObject *p_obj, PyObject *n_obj, PyObject *r_obj, PyObject *p_obj,
@ -771,13 +725,11 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
char *key; char *key;
int retval; int retval;
unsigned long n, r, p; unsigned long n, r, p;
if (password->len > INT_MAX) { if (password->len > INT_MAX) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"password is too long."); "password is too long.");
return NULL; return NULL;
} }
if (salt->buf == NULL) { if (salt->buf == NULL) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"salt is required"); "salt is required");
@ -788,7 +740,6 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
"salt is too long."); "salt is too long.");
return NULL; return NULL;
} }
n = PyLong_AsUnsignedLong(n_obj); n = PyLong_AsUnsignedLong(n_obj);
if (n == (unsigned long) -1 && PyErr_Occurred()) { if (n == (unsigned long) -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
@ -800,21 +751,18 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
"n must be a power of 2."); "n must be a power of 2.");
return NULL; return NULL;
} }
r = PyLong_AsUnsignedLong(r_obj); r = PyLong_AsUnsignedLong(r_obj);
if (r == (unsigned long) -1 && PyErr_Occurred()) { if (r == (unsigned long) -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"r is required and must be an unsigned int"); "r is required and must be an unsigned int");
return NULL; return NULL;
} }
p = PyLong_AsUnsignedLong(p_obj); p = PyLong_AsUnsignedLong(p_obj);
if (p == (unsigned long) -1 && PyErr_Occurred()) { if (p == (unsigned long) -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"p is required and must be an unsigned int"); "p is required and must be an unsigned int");
return NULL; return NULL;
} }
if (maxmem < 0 || maxmem > INT_MAX) { if (maxmem < 0 || maxmem > INT_MAX) {
/* OpenSSL 1.1.0 restricts maxmem to 32MB. It may change in the /* OpenSSL 1.1.0 restricts maxmem to 32MB. It may change in the
future. The maxmem constant is private to OpenSSL. */ future. The maxmem constant is private to OpenSSL. */
@ -823,14 +771,12 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
INT_MAX); INT_MAX);
return NULL; return NULL;
} }
if (dklen < 1 || dklen > INT_MAX) { if (dklen < 1 || dklen > INT_MAX) {
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"dklen must be greater than 0 and smaller than %d", "dklen must be greater than 0 and smaller than %d",
INT_MAX); INT_MAX);
return NULL; return NULL;
} }
/* let OpenSSL validate the rest */ /* let OpenSSL validate the rest */
retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0); retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0);
if (!retval) { if (!retval) {
@ -839,13 +785,11 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
"Invalid paramemter combination for n, r, p, maxmem."); "Invalid paramemter combination for n, r, p, maxmem.");
return NULL; return NULL;
} }
key_obj = PyBytes_FromStringAndSize(NULL, dklen); key_obj = PyBytes_FromStringAndSize(NULL, dklen);
if (key_obj == NULL) { if (key_obj == NULL) {
return NULL; return NULL;
} }
key = PyBytes_AS_STRING(key_obj); key = PyBytes_AS_STRING(key_obj);
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
retval = EVP_PBE_scrypt( retval = EVP_PBE_scrypt(
(const char*)password->buf, (size_t)password->len, (const char*)password->buf, (size_t)password->len,
@ -854,7 +798,6 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
(unsigned char *)key, (size_t)dklen (unsigned char *)key, (size_t)dklen
); );
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (!retval) { if (!retval) {
Py_CLEAR(key_obj); Py_CLEAR(key_obj);
_setException(PyExc_ValueError); _setException(PyExc_ValueError);
@ -864,61 +807,21 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
} }
#endif #endif
/* State for our callback function so that it can accumulate a result. */ static PyObject *
typedef struct _internal_name_mapper_state {
PyObject *set;
int error;
} _InternalNameMapperState;
/* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */
static void
_openssl_hash_name_mapper(const OBJ_NAME *openssl_obj_name, void *arg)
{
_InternalNameMapperState *state = (_InternalNameMapperState *)arg;
PyObject *py_name;
assert(state != NULL);
if (openssl_obj_name == NULL)
return;
/* Ignore aliased names, they pollute the list and OpenSSL appears to
* have its own definition of alias as the resulting list still
* contains duplicate and alternate names for several algorithms. */
if (openssl_obj_name->alias)
return;
py_name = PyUnicode_FromString(openssl_obj_name->name);
if (py_name == NULL) {
state->error = 1;
} else {
if (PySet_Add(state->set, py_name) != 0) {
state->error = 1;
}
Py_DECREF(py_name);
}
}
/* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */
static PyObject*
generate_hash_name_list(void) generate_hash_name_list(void)
{ {
_InternalNameMapperState state; uint8_t *p;
state.set = PyFrozenSet_New(NULL); PyObject *set, *name;
if (state.set == NULL) if ((set = PyFrozenSet_New(0))) {
return NULL; for (p = mbedtls_md_list(); *p != MBEDTLS_MD_NONE; ++p) {
state.error = 0; name = PyUnicode_FromString(mbedtls_md_info_from_type(*p)->name);
PySet_Add(set, name);
OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, &_openssl_hash_name_mapper, &state); Py_DECREF(name);
}
if (state.error) {
Py_DECREF(state.set);
return NULL;
} }
return state.set; return set;
} }
/* /*
* This macro generates constructor function definitions for specific * This macro generates constructor function definitions for specific
* hash algorithms. These constructors are much faster than calling * hash algorithms. These constructors are much faster than calling
@ -941,11 +844,11 @@ generate_hash_name_list(void)
} \ } \
\ \
if (CONST_new_ ## NAME ## _ctx_p == NULL) { \ if (CONST_new_ ## NAME ## _ctx_p == NULL) { \
EVP_MD_CTX *ctx_p = EVP_MD_CTX_new(); \ mbedtls_md_context_t *ctx_p = calloc(1, sizeof(mbedtls_md_context_t)); \
if (!EVP_get_digestbyname(#NAME) || \ if (!mbedtls_md_info_from_string(#NAME) || \
!EVP_DigestInit(ctx_p, EVP_get_digestbyname(#NAME))) { \ !mbedtls_md_setup(ctx_p, mbedtls_md_info_from_string(#NAME), 0)) { \
_setException(PyExc_ValueError); \ _setException(PyExc_ValueError); \
EVP_MD_CTX_free(ctx_p); \ mbedtls_md_free(ctx_p); \
return NULL; \ return NULL; \
} \ } \
CONST_new_ ## NAME ## _ctx_p = ctx_p; \ CONST_new_ ## NAME ## _ctx_p = ctx_p; \
@ -975,11 +878,10 @@ generate_hash_name_list(void)
/* used in the init function to setup a constructor: initialize OpenSSL /* used in the init function to setup a constructor: initialize OpenSSL
constructor constants if they haven't been initialized already. */ constructor constants if they haven't been initialized already. */
#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \ #define INIT_CONSTRUCTOR_CONSTANTS(NAME) \
if (CONST_ ## NAME ## _name_obj == NULL) { \ if (CONST_ ## NAME ## _name_obj == NULL) { \
CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \ CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME);\
} \ }
} while (0);
GEN_CONSTRUCTOR(md5) GEN_CONSTRUCTOR(md5)
GEN_CONSTRUCTOR(sha1) GEN_CONSTRUCTOR(sha1)
@ -1006,10 +908,6 @@ static struct PyMethodDef EVP_functions[] = {
{NULL, NULL} /* Sentinel */ {NULL, NULL} /* Sentinel */
}; };
/* Initialize this module. */
static struct PyModuleDef _hashlibmodule = { static struct PyModuleDef _hashlibmodule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"_hashlib", "_hashlib",
@ -1026,26 +924,16 @@ PyMODINIT_FUNC
PyInit__hashlib(void) PyInit__hashlib(void)
{ {
PyObject *m, *openssl_md_meth_names; PyObject *m, *openssl_md_meth_names;
#ifndef OPENSSL_VERSION_1_1
/* Load all digest algorithms and initialize cpuid */
OPENSSL_add_all_algorithms_noconf();
ERR_load_crypto_strings();
#endif
/* TODO build EVP_functions openssl_* entries dynamically based /* TODO build EVP_functions openssl_* entries dynamically based
* on what hashes are supported rather than listing many * on what hashes are supported rather than listing many
* but having some be unsupported. Only init appropriate * but having some be unsupported. Only init appropriate
* constants. */ * constants. */
Py_TYPE(&EVPtype) = &PyType_Type; Py_TYPE(&EVPtype) = &PyType_Type;
if (PyType_Ready(&EVPtype) < 0) if (PyType_Ready(&EVPtype) < 0)
return NULL; return NULL;
m = PyModule_Create(&_hashlibmodule); m = PyModule_Create(&_hashlibmodule);
if (m == NULL) if (m == NULL)
return NULL; return NULL;
openssl_md_meth_names = generate_hash_name_list(); openssl_md_meth_names = generate_hash_name_list();
if (openssl_md_meth_names == NULL) { if (openssl_md_meth_names == NULL) {
Py_DECREF(m); Py_DECREF(m);
@ -1055,16 +943,14 @@ PyInit__hashlib(void)
Py_DECREF(m); Py_DECREF(m);
return NULL; return NULL;
} }
Py_INCREF((PyObject *)&EVPtype); Py_INCREF((PyObject *)&EVPtype);
PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype); PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
/* these constants are used by the convenience constructors */ /* these constants are used by the convenience constructors */
INIT_CONSTRUCTOR_CONSTANTS(md5); INIT_CONSTRUCTOR_CONSTANTS(md5)
INIT_CONSTRUCTOR_CONSTANTS(sha1); INIT_CONSTRUCTOR_CONSTANTS(sha1)
INIT_CONSTRUCTOR_CONSTANTS(sha224); INIT_CONSTRUCTOR_CONSTANTS(sha224)
INIT_CONSTRUCTOR_CONSTANTS(sha256); INIT_CONSTRUCTOR_CONSTANTS(sha256)
INIT_CONSTRUCTOR_CONSTANTS(sha384); INIT_CONSTRUCTOR_CONSTANTS(sha384)
INIT_CONSTRUCTOR_CONSTANTS(sha512); INIT_CONSTRUCTOR_CONSTANTS(sha512)
return m; return m;
} }

View file

@ -13,6 +13,14 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_heapq"); PYTHON_PROVIDE("_heapq");
PYTHON_PROVIDE("_heapq._heapify_max");
PYTHON_PROVIDE("_heapq._heappop_max");
PYTHON_PROVIDE("_heapq._heapreplace_max");
PYTHON_PROVIDE("_heapq.heapify");
PYTHON_PROVIDE("_heapq.heappop");
PYTHON_PROVIDE("_heapq.heappush");
PYTHON_PROVIDE("_heapq.heappushpop");
PYTHON_PROVIDE("_heapq.heapreplace");
/* Drop in replacement for heapq.py /* Drop in replacement for heapq.py

View file

@ -24,6 +24,23 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_io"); PYTHON_PROVIDE("_io");
PYTHON_PROVIDE("_io.BlockingIOError");
PYTHON_PROVIDE("_io.BufferedRWPair");
PYTHON_PROVIDE("_io.BufferedRandom");
PYTHON_PROVIDE("_io.BufferedReader");
PYTHON_PROVIDE("_io.BufferedWriter");
PYTHON_PROVIDE("_io.BytesIO");
PYTHON_PROVIDE("_io.DEFAULT_BUFFER_SIZE");
PYTHON_PROVIDE("_io.FileIO");
PYTHON_PROVIDE("_io.IncrementalNewlineDecoder");
PYTHON_PROVIDE("_io.StringIO");
PYTHON_PROVIDE("_io.TextIOWrapper");
PYTHON_PROVIDE("_io.UnsupportedOperation");
PYTHON_PROVIDE("_io._BufferedIOBase");
PYTHON_PROVIDE("_io._IOBase");
PYTHON_PROVIDE("_io._RawIOBase");
PYTHON_PROVIDE("_io._TextIOBase");
PYTHON_PROVIDE("_io.open");
/* /*
An implementation of the new I/O lib as defined by PEP 3116 - "New I/O" An implementation of the new I/O lib as defined by PEP 3116 - "New I/O"

View file

@ -21,6 +21,11 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_json"); PYTHON_PROVIDE("_json");
PYTHON_PROVIDE("_json.encode_basestring");
PYTHON_PROVIDE("_json.encode_basestring_ascii");
PYTHON_PROVIDE("_json.make_encoder");
PYTHON_PROVIDE("_json.make_scanner");
PYTHON_PROVIDE("_json.scanstring");
#ifdef __GNUC__ #ifdef __GNUC__
#define UNUSED __attribute__((__unused__)) #define UNUSED __attribute__((__unused__))

View file

@ -20,6 +20,17 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_locale"); PYTHON_PROVIDE("_locale");
PYTHON_PROVIDE("_locale.CHAR_MAX");
PYTHON_PROVIDE("_locale.Error");
PYTHON_PROVIDE("_locale.LC_ALL");
PYTHON_PROVIDE("_locale.LC_COLLATE");
PYTHON_PROVIDE("_locale.LC_CTYPE");
PYTHON_PROVIDE("_locale.LC_MESSAGES");
PYTHON_PROVIDE("_locale.LC_MONETARY");
PYTHON_PROVIDE("_locale.LC_NUMERIC");
PYTHON_PROVIDE("_locale.LC_TIME");
PYTHON_PROVIDE("_locale.localeconv");
PYTHON_PROVIDE("_locale.setlocale");
/*********************************************************** /***********************************************************
Copyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis Copyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis

View file

@ -18,6 +18,9 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_lsprof"); PYTHON_PROVIDE("_lsprof");
PYTHON_PROVIDE("_lsprof.Profiler");
PYTHON_PROVIDE("_lsprof.profiler_entry");
PYTHON_PROVIDE("_lsprof.profiler_subentry");
/*** Selection of a high-precision timer ***/ /*** Selection of a high-precision timer ***/

View file

@ -10,6 +10,40 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_lzma"); PYTHON_PROVIDE("_lzma");
PYTHON_PROVIDE("_lzma.CHECK_CRC32");
PYTHON_PROVIDE("_lzma.CHECK_CRC64");
PYTHON_PROVIDE("_lzma.CHECK_ID_MAX");
PYTHON_PROVIDE("_lzma.CHECK_NONE");
PYTHON_PROVIDE("_lzma.CHECK_SHA256");
PYTHON_PROVIDE("_lzma.CHECK_UNKNOWN");
PYTHON_PROVIDE("_lzma.FILTER_ARM");
PYTHON_PROVIDE("_lzma.FILTER_ARMTHUMB");
PYTHON_PROVIDE("_lzma.FILTER_DELTA");
PYTHON_PROVIDE("_lzma.FILTER_IA64");
PYTHON_PROVIDE("_lzma.FILTER_LZMA1");
PYTHON_PROVIDE("_lzma.FILTER_LZMA2");
PYTHON_PROVIDE("_lzma.FILTER_POWERPC");
PYTHON_PROVIDE("_lzma.FILTER_SPARC");
PYTHON_PROVIDE("_lzma.FILTER_X86");
PYTHON_PROVIDE("_lzma.FORMAT_ALONE");
PYTHON_PROVIDE("_lzma.FORMAT_AUTO");
PYTHON_PROVIDE("_lzma.FORMAT_RAW");
PYTHON_PROVIDE("_lzma.FORMAT_XZ");
PYTHON_PROVIDE("_lzma.LZMACompressor");
PYTHON_PROVIDE("_lzma.LZMADecompressor");
PYTHON_PROVIDE("_lzma.LZMAError");
PYTHON_PROVIDE("_lzma.MF_BT2");
PYTHON_PROVIDE("_lzma.MF_BT3");
PYTHON_PROVIDE("_lzma.MF_BT4");
PYTHON_PROVIDE("_lzma.MF_HC3");
PYTHON_PROVIDE("_lzma.MF_HC4");
PYTHON_PROVIDE("_lzma.MODE_FAST");
PYTHON_PROVIDE("_lzma.MODE_NORMAL");
PYTHON_PROVIDE("_lzma.PRESET_DEFAULT");
PYTHON_PROVIDE("_lzma.PRESET_EXTREME");
PYTHON_PROVIDE("_lzma._decode_filter_properties");
PYTHON_PROVIDE("_lzma._encode_filter_properties");
PYTHON_PROVIDE("_lzma.is_check_supported");
/* _lzma - Low-level Python interface to liblzma. /* _lzma - Low-level Python interface to liblzma.

View file

@ -1,3 +1,9 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Python 3
https://docs.python.org/3/license.html │
*/
#include "libc/errno.h" #include "libc/errno.h"
#include "third_party/python/Include/pymath.h" #include "third_party/python/Include/pymath.h"
#include "third_party/python/Modules/_math.h" #include "third_party/python/Modules/_math.h"

View file

@ -9,6 +9,7 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_multiprocessing"); PYTHON_PROVIDE("_multiprocessing");
PYTHON_PROVIDE("_multiprocessing.flags");
/* /*
* Extension module used by multiprocessing package * Extension module used by multiprocessing package

View file

@ -15,6 +15,7 @@
/* clang-format off */ /* clang-format off */
PYTHON_PROVIDE("_opcode"); PYTHON_PROVIDE("_opcode");
PYTHON_PROVIDE("_opcode.stack_effect");
/*[clinic input] /*[clinic input]
module _opcode module _opcode

Some files were not shown because too many files have changed in this diff Show more