Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c23baa2

Browse filesBrowse files
authored
Merge branch 'main' into fetch-restore-objects
2 parents 9b68505 + 4e7c0cb commit c23baa2
Copy full SHA for c23baa2

File tree

Expand file treeCollapse file tree

7 files changed

+176
-80
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+176
-80
lines changed

‎Doc/library/os.rst

Copy file name to clipboardExpand all lines: Doc/library/os.rst
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ process and user.
201201
``'surrogateescape'`` error handler. Use :data:`environb` if you would like
202202
to use a different encoding.
203203

204+
On Windows, the keys are converted to uppercase. This also applies when
205+
getting, setting, or deleting an item. For example,
206+
``environ['monty'] = 'python'`` maps the key ``'MONTY'`` to the value
207+
``'python'``.
208+
204209
.. note::
205210

206211
Calling :func:`putenv` directly does not change :data:`os.environ`, so it's better

‎Include/internal/pycore_compile.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_compile.h
-6Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
1919
int optimize,
2020
struct _arena *arena);
2121

22-
int _PyFuture_FromAST(
23-
struct _mod * mod,
24-
PyObject *filename,
25-
PyFutureFeatures* futures);
26-
27-
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
2822

2923
typedef struct {
3024
int optimize;

‎Include/internal/pycore_symtable.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_symtable.h
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *);
9090

9191
extern void _PySymtable_Free(struct symtable *);
9292

93+
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
94+
9395
/* Flags for def-use information */
9496

9597
#define DEF_GLOBAL 1 /* global stmt */
@@ -128,6 +130,11 @@ extern struct symtable* _Py_SymtableStringObjectFlags(
128130
int start,
129131
PyCompilerFlags *flags);
130132

133+
int _PyFuture_FromAST(
134+
struct _mod * mod,
135+
PyObject *filename,
136+
PyFutureFeatures* futures);
137+
131138
#ifdef __cplusplus
132139
}
133140
#endif

‎Lib/test/test_typing.py

Copy file name to clipboardExpand all lines: Lib/test/test_typing.py
+95-4Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4171,38 +4171,129 @@ class OverrideDecoratorTests(BaseTestCase):
41714171
def test_override(self):
41724172
class Base:
41734173
def normal_method(self): ...
4174+
@classmethod
4175+
def class_method_good_order(cls): ...
4176+
@classmethod
4177+
def class_method_bad_order(cls): ...
41744178
@staticmethod
41754179
def static_method_good_order(): ...
41764180
@staticmethod
41774181
def static_method_bad_order(): ...
4178-
@staticmethod
4179-
def decorator_with_slots(): ...
41804182

41814183
class Derived(Base):
41824184
@override
41834185
def normal_method(self):
41844186
return 42
41854187

4188+
@classmethod
4189+
@override
4190+
def class_method_good_order(cls):
4191+
return 42
4192+
@override
4193+
@classmethod
4194+
def class_method_bad_order(cls):
4195+
return 42
4196+
41864197
@staticmethod
41874198
@override
41884199
def static_method_good_order():
41894200
return 42
4190-
41914201
@override
41924202
@staticmethod
41934203
def static_method_bad_order():
41944204
return 42
41954205

4196-
41974206
self.assertIsSubclass(Derived, Base)
41984207
instance = Derived()
41994208
self.assertEqual(instance.normal_method(), 42)
4209+
self.assertIs(True, Derived.normal_method.__override__)
42004210
self.assertIs(True, instance.normal_method.__override__)
4211+
4212+
self.assertEqual(Derived.class_method_good_order(), 42)
4213+
self.assertIs(True, Derived.class_method_good_order.__override__)
4214+
self.assertEqual(Derived.class_method_bad_order(), 42)
4215+
self.assertIs(False, hasattr(Derived.class_method_bad_order, "__override__"))
4216+
42014217
self.assertEqual(Derived.static_method_good_order(), 42)
42024218
self.assertIs(True, Derived.static_method_good_order.__override__)
42034219
self.assertEqual(Derived.static_method_bad_order(), 42)
42044220
self.assertIs(False, hasattr(Derived.static_method_bad_order, "__override__"))
42054221

4222+
# Base object is not changed:
4223+
self.assertIs(False, hasattr(Base.normal_method, "__override__"))
4224+
self.assertIs(False, hasattr(Base.class_method_good_order, "__override__"))
4225+
self.assertIs(False, hasattr(Base.class_method_bad_order, "__override__"))
4226+
self.assertIs(False, hasattr(Base.static_method_good_order, "__override__"))
4227+
self.assertIs(False, hasattr(Base.static_method_bad_order, "__override__"))
4228+
4229+
def test_property(self):
4230+
class Base:
4231+
@property
4232+
def correct(self) -> int:
4233+
return 1
4234+
@property
4235+
def wrong(self) -> int:
4236+
return 1
4237+
4238+
class Child(Base):
4239+
@property
4240+
@override
4241+
def correct(self) -> int:
4242+
return 2
4243+
@override
4244+
@property
4245+
def wrong(self) -> int:
4246+
return 2
4247+
4248+
instance = Child()
4249+
self.assertEqual(instance.correct, 2)
4250+
self.assertTrue(Child.correct.fget.__override__)
4251+
self.assertEqual(instance.wrong, 2)
4252+
self.assertFalse(hasattr(Child.wrong, "__override__"))
4253+
self.assertFalse(hasattr(Child.wrong.fset, "__override__"))
4254+
4255+
def test_silent_failure(self):
4256+
class CustomProp:
4257+
__slots__ = ('fget',)
4258+
def __init__(self, fget):
4259+
self.fget = fget
4260+
def __get__(self, obj, objtype=None):
4261+
return self.fget(obj)
4262+
4263+
class WithOverride:
4264+
@override # must not fail on object with `__slots__`
4265+
@CustomProp
4266+
def some(self):
4267+
return 1
4268+
4269+
self.assertEqual(WithOverride.some, 1)
4270+
self.assertFalse(hasattr(WithOverride.some, "__override__"))
4271+
4272+
def test_multiple_decorators(self):
4273+
import functools
4274+
4275+
def with_wraps(f): # similar to `lru_cache` definition
4276+
@functools.wraps(f)
4277+
def wrapper(*args, **kwargs):
4278+
return f(*args, **kwargs)
4279+
return wrapper
4280+
4281+
class WithOverride:
4282+
@override
4283+
@with_wraps
4284+
def on_top(self, a: int) -> int:
4285+
return a + 1
4286+
@with_wraps
4287+
@override
4288+
def on_bottom(self, a: int) -> int:
4289+
return a + 2
4290+
4291+
instance = WithOverride()
4292+
self.assertEqual(instance.on_top(1), 2)
4293+
self.assertTrue(instance.on_top.__override__)
4294+
self.assertEqual(instance.on_bottom(1), 3)
4295+
self.assertTrue(instance.on_bottom.__override__)
4296+
42064297

42074298
class CastTests(BaseTestCase):
42084299

‎Objects/typeobject.c

Copy file name to clipboardExpand all lines: Objects/typeobject.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "Python.h"
44
#include "pycore_call.h"
55
#include "pycore_code.h" // CO_FAST_FREE
6-
#include "pycore_compile.h" // _Py_Mangle()
6+
#include "pycore_symtable.h" // _Py_Mangle()
77
#include "pycore_dict.h" // _PyDict_KeysSize()
88
#include "pycore_initconfig.h" // _PyStatus_OK()
99
#include "pycore_moduleobject.h" // _PyModule_GetDef()

‎Python/compile.c

Copy file name to clipboardExpand all lines: Python/compile.c
+2-68Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
2929
#include "Python.h"
3030
#include "pycore_ast.h" // _PyAST_GetDocString()
3131
#include "pycore_code.h" // _PyCode_New()
32-
#include "pycore_compile.h" // _PyFuture_FromAST()
32+
#include "pycore_compile.h"
3333
#include "pycore_intrinsics.h"
3434
#include "pycore_long.h" // _PyLong_GetZero()
3535
#include "pycore_opcode.h" // _PyOpcode_Caches
3636
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
37-
#include "pycore_symtable.h" // PySTEntryObject
37+
#include "pycore_symtable.h" // PySTEntryObject, _PyFuture_FromAST()
3838

3939
#include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
4040

@@ -569,72 +569,6 @@ static PyCodeObject *assemble(struct compiler *, int addNone);
569569

570570
#define CAPSULE_NAME "compile.c compiler unit"
571571

572-
PyObject *
573-
_Py_Mangle(PyObject *privateobj, PyObject *ident)
574-
{
575-
/* Name mangling: __private becomes _classname__private.
576-
This is independent from how the name is used. */
577-
PyObject *result;
578-
size_t nlen, plen, ipriv;
579-
Py_UCS4 maxchar;
580-
if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
581-
PyUnicode_READ_CHAR(ident, 0) != '_' ||
582-
PyUnicode_READ_CHAR(ident, 1) != '_') {
583-
return Py_NewRef(ident);
584-
}
585-
nlen = PyUnicode_GET_LENGTH(ident);
586-
plen = PyUnicode_GET_LENGTH(privateobj);
587-
/* Don't mangle __id__ or names with dots.
588-
589-
The only time a name with a dot can occur is when
590-
we are compiling an import statement that has a
591-
package name.
592-
593-
TODO(jhylton): Decide whether we want to support
594-
mangling of the module name, e.g. __M.X.
595-
*/
596-
if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' &&
597-
PyUnicode_READ_CHAR(ident, nlen-2) == '_') ||
598-
PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) {
599-
return Py_NewRef(ident); /* Don't mangle __whatever__ */
600-
}
601-
/* Strip leading underscores from class name */
602-
ipriv = 0;
603-
while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_')
604-
ipriv++;
605-
if (ipriv == plen) {
606-
return Py_NewRef(ident); /* Don't mangle if class is just underscores */
607-
}
608-
plen -= ipriv;
609-
610-
if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
611-
PyErr_SetString(PyExc_OverflowError,
612-
"private identifier too large to be mangled");
613-
return NULL;
614-
}
615-
616-
maxchar = PyUnicode_MAX_CHAR_VALUE(ident);
617-
if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar)
618-
maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
619-
620-
result = PyUnicode_New(1 + nlen + plen, maxchar);
621-
if (!result) {
622-
return NULL;
623-
}
624-
/* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
625-
PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
626-
if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
627-
Py_DECREF(result);
628-
return NULL;
629-
}
630-
if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) {
631-
Py_DECREF(result);
632-
return NULL;
633-
}
634-
assert(_PyUnicode_CheckConsistency(result, 1));
635-
return result;
636-
}
637-
638572

639573
static int
640574
compiler_setup(struct compiler *c, mod_ty mod, PyObject *filename,

‎Python/symtable.c

Copy file name to clipboardExpand all lines: Python/symtable.c
+66-1Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "Python.h"
22
#include "pycore_ast.h" // identifier, stmt_ty
3-
#include "pycore_compile.h" // _Py_Mangle(), _PyFuture_FromAST()
43
#include "pycore_parser.h" // _PyParser_ASTFromString()
54
#include "pycore_pystate.h" // _PyThreadState_GET()
65
#include "pycore_symtable.h" // PySTEntryObject
@@ -2152,3 +2151,69 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
21522151
_PyArena_Free(arena);
21532152
return st;
21542153
}
2154+
2155+
PyObject *
2156+
_Py_Mangle(PyObject *privateobj, PyObject *ident)
2157+
{
2158+
/* Name mangling: __private becomes _classname__private.
2159+
This is independent from how the name is used. */
2160+
if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
2161+
PyUnicode_READ_CHAR(ident, 0) != '_' ||
2162+
PyUnicode_READ_CHAR(ident, 1) != '_') {
2163+
return Py_NewRef(ident);
2164+
}
2165+
size_t nlen = PyUnicode_GET_LENGTH(ident);
2166+
size_t plen = PyUnicode_GET_LENGTH(privateobj);
2167+
/* Don't mangle __id__ or names with dots.
2168+
2169+
The only time a name with a dot can occur is when
2170+
we are compiling an import statement that has a
2171+
package name.
2172+
2173+
TODO(jhylton): Decide whether we want to support
2174+
mangling of the module name, e.g. __M.X.
2175+
*/
2176+
if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' &&
2177+
PyUnicode_READ_CHAR(ident, nlen-2) == '_') ||
2178+
PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) {
2179+
return Py_NewRef(ident); /* Don't mangle __whatever__ */
2180+
}
2181+
/* Strip leading underscores from class name */
2182+
size_t ipriv = 0;
2183+
while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') {
2184+
ipriv++;
2185+
}
2186+
if (ipriv == plen) {
2187+
return Py_NewRef(ident); /* Don't mangle if class is just underscores */
2188+
}
2189+
plen -= ipriv;
2190+
2191+
if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
2192+
PyErr_SetString(PyExc_OverflowError,
2193+
"private identifier too large to be mangled");
2194+
return NULL;
2195+
}
2196+
2197+
Py_UCS4 maxchar = PyUnicode_MAX_CHAR_VALUE(ident);
2198+
if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar) {
2199+
maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
2200+
}
2201+
2202+
PyObject *result = PyUnicode_New(1 + nlen + plen, maxchar);
2203+
if (!result) {
2204+
return NULL;
2205+
}
2206+
/* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
2207+
PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
2208+
if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
2209+
Py_DECREF(result);
2210+
return NULL;
2211+
}
2212+
if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) {
2213+
Py_DECREF(result);
2214+
return NULL;
2215+
}
2216+
assert(_PyUnicode_CheckConsistency(result, 1));
2217+
return result;
2218+
}
2219+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.