Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Doc/library/__future__.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ language using this mechanism:
| annotations | 3.7.0b1 | 4.0 | :pep:`563`: |
| | | | *Postponed evaluation of annotations* |
+------------------+-------------+--------------+---------------------------------------------+
+------------------+-------------+--------------+---------------------------------------------+
| absolute_codepath| 3.8.0b1 | 4.0 | :pep:`9999`: |
| | | | *Absolute codepaths* |
+------------------+-------------+--------------+---------------------------------------------+

.. XXX Adding a new entry? Remember to update simple_stmts.rst, too.

Expand Down
1 change: 1 addition & 0 deletions Include/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ typedef struct {
#define CO_FUTURE_BARRY_AS_BDFL 0x40000
#define CO_FUTURE_GENERATOR_STOP 0x80000
#define CO_FUTURE_ANNOTATIONS 0x100000
#define CO_FUTURE_ABSOLUTE_CODEPATH 0x200000

/* This value is found in the co_cell2arg array when the associated cell
variable does not correspond to an argument. */
Expand Down
5 changes: 4 additions & 1 deletion Include/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *);
#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \
CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS)
CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS | \
CO_FUTURE_ABSOLUTE_CODEPATH)

#define PyCF_MASK_OBSOLETE (CO_NESTED)
#define PyCF_SOURCE_IS_UTF8 0x0100
#define PyCF_DONT_IMPLY_DEDENT 0x0200
Expand Down Expand Up @@ -49,6 +51,7 @@ typedef struct {
#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL"
#define FUTURE_GENERATOR_STOP "generator_stop"
#define FUTURE_ANNOTATIONS "annotations"
#define FUTURE_ABSOLUTE_CODEPATH "absolute_codepath"

struct _mod; /* Declare the existence of this type */
#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar)
Expand Down
6 changes: 6 additions & 0 deletions Lib/__future__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"barry_as_FLUFL",
"generator_stop",
"annotations",
"absolute_codepath",
]

__all__ = ["all_feature_names"] + all_feature_names
Expand All @@ -76,6 +77,7 @@
CO_FUTURE_BARRY_AS_BDFL = 0x40000
CO_FUTURE_GENERATOR_STOP = 0x80000 # StopIteration becomes RuntimeError in generators
CO_FUTURE_ANNOTATIONS = 0x100000 # annotations become strings at runtime
CO_FUTURE_ABSOLUTE_CODEPATH = 0x200000

class _Feature:
def __init__(self, optionalRelease, mandatoryRelease, compiler_flag):
Expand Down Expand Up @@ -144,3 +146,7 @@ def __repr__(self):
annotations = _Feature((3, 7, 0, "beta", 1),
(4, 0, 0, "alpha", 0),
CO_FUTURE_ANNOTATIONS)

absolute_codepath = _Feature((3, 8, 0, "beta", 1),
(4, 0, 0, "alpha", 0),
CO_FUTURE_ABSOLUTE_CODEPATH)
4 changes: 4 additions & 0 deletions Lib/test/test_future.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ def test_unicode_literals_exec(self):
exec("from __future__ import unicode_literals; x = ''", {}, scope)
self.assertIsInstance(scope["x"], str)

def test_future5(self):
with support.CleanImport('test_future6'):
from test import test_future6

class AnnotationsFutureTestCase(unittest.TestCase):
template = dedent(
"""
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_future6.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from __future__ import absolute_codepath
import os
import unittest

class Tests(unittest.TestCase):
def test_absolute_codepath(self):
def fn():
pass
filename = fn.__code__.co_filename
self.assertEqual(filename, os.path.abspath(filename))


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Now code objects ``co_filename`` attribute is always an absolute path if a ``absolute_codepath`` future flag specified -- by
Batuhan Taskaya
23 changes: 20 additions & 3 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@
*/

#include "Python.h"

#include "osdefs.h"
#include "Python-ast.h"
#include "pycore_pystate.h" /* _PyInterpreterState_GET_UNSAFE() */
#include "ast.h"
#include "code.h"
#include "symtable.h"
#include "opcode.h"
#include "wordcode_helpers.h"
#include <wchar.h>

#define DEFAULT_BLOCK_SIZE 16
#define DEFAULT_BLOCKS 8
Expand Down Expand Up @@ -325,8 +326,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
}
if (!compiler_init(&c))
return NULL;
Py_INCREF(filename);
c.c_filename = filename;

c.c_arena = arena;
c.c_future = PyFuture_FromASTObject(mod, filename);
if (c.c_future == NULL)
Expand Down Expand Up @@ -354,6 +354,23 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
goto finally;
}

if (c.c_future->ff_features & CO_FUTURE_ABSOLUTE_CODEPATH) {
wchar_t *path = PyUnicode_AsWideCharString(filename, NULL);
#if defined(HAVE_REALPATH)
wchar_t fullpath[MAXPATHLEN];
path = _Py_wrealpath(path, fullpath, Py_ARRAY_LENGTH(fullpath));
#elif defined(MS_WINDOWS)
wchar_t fullpath[MAX_PATH];
wchar_t *ptemp;
if (GetFullPathNameW(path, Py_ARRAY_LENGTH(fullpath), fullpath, &ptemp))
path = fullpath;
#endif
if (path != NULL)
filename = PyUnicode_FromWideChar(path, -1);
}
Py_INCREF(filename);
c.c_filename = filename;

co = compiler_mod(&c, mod);

finally:
Expand Down
2 changes: 2 additions & 0 deletions Python/future.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename)
continue;
} else if (strcmp(feature, FUTURE_ANNOTATIONS) == 0) {
ff->ff_features |= CO_FUTURE_ANNOTATIONS;
} else if (strcmp(feature, FUTURE_ABSOLUTE_CODEPATH) == 0) {
ff->ff_features |= CO_FUTURE_ABSOLUTE_CODEPATH;
} else if (strcmp(feature, "braces") == 0) {
PyErr_SetString(PyExc_SyntaxError,
"not a chance");
Expand Down