Skip to content
Commits on Source (10)
Metadata-Version: 1.1
Name: typed-ast
Version: 1.1.0
Version: 1.1.1
Summary: a fork of Python 2 and 3 ast modules with type comment support
Home-page: https://github.com/python/typed_ast
Author: David Fisher
......
# Typed AST
[![Build Status](https://travis-ci.org/python/typed_ast.svg?branch=master)](https://travis-ci.org/python/typed_ast)
[![Chat at https://gitter.im/python/typed_ast](https://badges.gitter.im/python/typed_ast.svg)](https://gitter.im/python/typed_ast)
`typed_ast` is a Python 3 package that provides a Python 2.7 and Python 3
parser similar to the standard `ast` library. Unlike `ast`, the parsers in
`typed_ast` include [PEP 484](https://www.python.org/dev/peps/pep-0484/) type
comments and are independent of the version of Python under which they are run.
The `typed_ast` parsers produce the standard Python AST (plus type comments),
and are both fast and correct, as they are based on the CPython 2.7 and 3.6
parsers. `typed_ast` runs on Python 3.3-3.6 on Linux, OS X and Windows.
## Development Philosophy
This project is a drop-in replacement for the builtin `ast` module. It is
intended to be bug-for-bug compatible and behave identically, except for the
presence of a few additional fields on the returned classes and a few
additional optional arguments to the `parse` call. Therefore, `typed_ast` will
not accept any bugfixes for bugs in `ast` -- they should be fixed upstream
instead. To avoid feature bloat, any new features for `typed_ast` should have
the potential to be broadly useful and not be built just for one niche usecase
or in a manner such that only one project can use them.
## Submodules
### ast3
The `ast3` parser produces the AST from the latest version of Python 3
(currently Python 3.6). When new versions of Python 3 are released, it will be
updated to match any changes in their AST. (For rationale and technical
details, see [here](update_process.md).) The AST it currently produces is described in
[ast3/Parser/Python.asdl](ast3/Parser/Python.asdl). If you wish to limit
parsing to older versions of Python 3, `ast3` can be configured to to give a
SyntaxError for new syntax features introduced beyond a given Python version.
For more information, see the module docstring in
[typed\_ast/ast3.py](typed_ast/ast3.py).
### ast27
The `ast27` parser tracks the standard Python 2.7 AST, which is expected to
never receive further updates. The AST it produces is described in
[ast27/Parser/Python.asdl](ast27/Parser/Python.asdl). For more information,
see the module docstring in [typed\_ast/ast27.py](typed_ast/ast27.py).
### conversions
`typed_ast` also provides a `conversions` module which converts `ast27` ASTs
into `ast3` ASTs. This functionality is somewhat experimental, however. For
more information, see the `py2to3` docstring in
[typed\_ast/conversions](typed_ast/conversions.py).
Note: as these parsers consider type comments part of the grammar, incorrectly
placed type comments are considered syntax errors.
## Updates and Releases
To update `typed_ast` for new major Python releases, see [`update_process.md`](update_process.md).
To make a new `typed_ast` release, see [`release_process.md`](release_process.md).
......@@ -286,7 +286,7 @@ struct _expr {
struct {
string s;
int has_b;
string kind;
} Str;
struct {
......@@ -505,7 +505,7 @@ expr_ty _Ta27_Repr(expr_ty value, int lineno, int col_offset, PyArena *arena);
#define Num(a0, a1, a2, a3) _Ta27_Num(a0, a1, a2, a3)
expr_ty _Ta27_Num(object n, int lineno, int col_offset, PyArena *arena);
#define Str(a0, a1, a2, a3, a4) _Ta27_Str(a0, a1, a2, a3, a4)
expr_ty _Ta27_Str(string s, int has_b, int lineno, int col_offset, PyArena *arena);
expr_ty _Ta27_Str(string s, string kind, int lineno, int col_offset, PyArena *arena);
#define Attribute(a0, a1, a2, a3, a4, a5) _Ta27_Attribute(a0, a1, a2, a3, a4, a5)
expr_ty _Ta27_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
col_offset, PyArena *arena);
......
......@@ -252,7 +252,7 @@ static char *Num_fields[]={
static PyTypeObject *Str_type;
static char *Str_fields[]={
"s",
"has_b",
"kind",
};
static PyTypeObject *Attribute_type;
static char *Attribute_fields[]={
......@@ -1850,7 +1850,7 @@ Num(object n, int lineno, int col_offset, PyArena *arena)
}
expr_ty
Str(string s, int has_b, int lineno, int col_offset, PyArena *arena)
Str(string s, string kind, int lineno, int col_offset, PyArena *arena)
{
expr_ty p;
if (!s) {
......@@ -1858,12 +1858,17 @@ Str(string s, int has_b, int lineno, int col_offset, PyArena *arena)
"field s is required for Str");
return NULL;
}
if (!kind) {
PyErr_SetString(PyExc_ValueError,
"field kind is required for Str");
return NULL;
}
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
p->kind = Str_kind;
p->v.Str.s = s;
p->v.Str.has_b = has_b;
p->v.Str.kind = kind;
p->lineno = lineno;
p->col_offset = col_offset;
return p;
......@@ -2889,9 +2894,9 @@ ast2obj_expr(void* _o)
if (PyObject_SetAttrString(result, "s", value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_int(o->v.Str.has_b);
value = ast2obj_string(o->v.Str.kind);
if (!value) goto failed;
if (PyObject_SetAttrString(result, "has_b", value) == -1)
if (PyObject_SetAttrString(result, "kind", value) == -1)
goto failed;
Py_DECREF(value);
break;
......@@ -5714,7 +5719,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
}
if (isinstance) {
string s;
int has_b;
string kind;
if (PyObject_HasAttrString(obj, "s")) {
int res;
......@@ -5728,18 +5733,19 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
PyErr_SetString(PyExc_TypeError, "required field \"s\" missing from Str");
return 1;
}
if (PyObject_HasAttrString(obj, "has_b")) {
if (PyObject_HasAttrString(obj, "kind")) {
int res;
tmp = PyObject_GetAttrString(obj, "has_b");
tmp = PyObject_GetAttrString(obj, "kind");
if (tmp == NULL) goto failed;
res = obj2ast_int(tmp, &has_b, arena);
res = obj2ast_string(tmp, &kind, arena);
if (res != 0) goto failed;
Py_XDECREF(tmp);
tmp = NULL;
} else {
has_b = 0;
PyErr_SetString(PyExc_TypeError, "required field \"kind\" missing from Str");
return 1;
}
*out = Str(s, has_b, lineno, col_offset, arena);
*out = Str(s, kind, lineno, col_offset, arena);
if (*out == NULL) goto failed;
return 0;
}
......
......@@ -1498,10 +1498,20 @@ ast_for_atom(struct compiling *c, const node *n)
return Name(name, Load, LINENO(n), n->n_col_offset, c->c_arena);
}
case STRING: {
PyObject *str = parsestrplus(c, n);
const char *s = STR(CHILD(n, 0));
PyObject *kind, *str = parsestrplus(c, n);
const char *raw, *s = STR(CHILD(n, 0));
int quote = Py_CHARMASK(*s);
int has_b = 0;
/* currently Python allows up to 2 string modifiers */
char *ch, s_kind[3] = {0, 0, 0};
ch = s_kind;
raw = s;
while (*raw && *raw != '\'' && *raw != '"') {
*ch++ = *raw++;
}
kind = PyUnicode_FromString(s_kind);
if (!kind) {
return NULL;
}
if (!str) {
#ifdef Py_USING_UNICODE
if (PyErr_ExceptionMatches(PyExc_UnicodeError)){
......@@ -1526,10 +1536,7 @@ ast_for_atom(struct compiling *c, const node *n)
return NULL;
}
PyArena_AddPyObject(c->c_arena, str);
if (quote == 'b' || quote == 'B') {
has_b = 1;
}
return Str(str, has_b, LINENO(n), n->n_col_offset, c->c_arena);
return Str(str, kind, LINENO(n), n->n_col_offset, c->c_arena);
}
case NUMBER: {
PyObject *pynum = parsenumber(c, STR(ch));
......
......@@ -318,6 +318,7 @@ struct _expr {
struct {
string s;
string kind;
} Str;
struct {
......@@ -601,8 +602,9 @@ expr_ty _Ta3_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int
lineno, int col_offset, PyArena *arena);
#define Num(a0, a1, a2, a3) _Ta3_Num(a0, a1, a2, a3)
expr_ty _Ta3_Num(object n, int lineno, int col_offset, PyArena *arena);
#define Str(a0, a1, a2, a3) _Ta3_Str(a0, a1, a2, a3)
expr_ty _Ta3_Str(string s, int lineno, int col_offset, PyArena *arena);
#define Str(a0, a1, a2, a3, a4) _Ta3_Str(a0, a1, a2, a3, a4)
expr_ty _Ta3_Str(string s, string kind, int lineno, int col_offset, PyArena
*arena);
#define FormattedValue(a0, a1, a2, a3, a4, a5) _Ta3_FormattedValue(a0, a1, a2, a3, a4, a5)
expr_ty _Ta3_FormattedValue(expr_ty value, int conversion, expr_ty format_spec,
int lineno, int col_offset, PyArena *arena);
......
......@@ -307,8 +307,10 @@ static char *Num_fields[]={
};
static PyTypeObject *Str_type;
_Py_IDENTIFIER(s);
_Py_IDENTIFIER(kind);
static char *Str_fields[]={
"s",
"kind",
};
static PyTypeObject *FormattedValue_type;
_Py_IDENTIFIER(conversion);
......@@ -983,7 +985,7 @@ static int init_types(void)
if (!Call_type) return 0;
Num_type = make_type("Num", expr_type, Num_fields, 1);
if (!Num_type) return 0;
Str_type = make_type("Str", expr_type, Str_fields, 1);
Str_type = make_type("Str", expr_type, Str_fields, 2);
if (!Str_type) return 0;
FormattedValue_type = make_type("FormattedValue", expr_type,
FormattedValue_fields, 3);
......@@ -2181,7 +2183,7 @@ Num(object n, int lineno, int col_offset, PyArena *arena)
}
expr_ty
Str(string s, int lineno, int col_offset, PyArena *arena)
Str(string s, string kind, int lineno, int col_offset, PyArena *arena)
{
expr_ty p;
if (!s) {
......@@ -2189,11 +2191,17 @@ Str(string s, int lineno, int col_offset, PyArena *arena)
"field s is required for Str");
return NULL;
}
if (!kind) {
PyErr_SetString(PyExc_ValueError,
"field kind is required for Str");
return NULL;
}
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
p->kind = Str_kind;
p->v.Str.s = s;
p->v.Str.kind = kind;
p->lineno = lineno;
p->col_offset = col_offset;
return p;
......@@ -3448,6 +3456,11 @@ ast2obj_expr(void* _o)
if (_PyObject_SetAttrId(result, &PyId_s, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_string(o->v.Str.kind);
if (!value) goto failed;
if (_PyObject_SetAttrId(result, &PyId_kind, value) == -1)
goto failed;
Py_DECREF(value);
break;
case FormattedValue_kind:
result = PyType_GenericNew(FormattedValue_type, NULL, NULL);
......@@ -6766,6 +6779,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
}
if (isinstance) {
string s;
string kind;
if (_PyObject_HasAttrId(obj, &PyId_s)) {
int res;
......@@ -6778,7 +6792,18 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
PyErr_SetString(PyExc_TypeError, "required field \"s\" missing from Str");
return 1;
}
*out = Str(s, lineno, col_offset, arena);
if (_PyObject_HasAttrId(obj, &PyId_kind)) {
int res;
tmp = _PyObject_GetAttrId(obj, &PyId_kind);
if (tmp == NULL) goto failed;
res = obj2ast_string(tmp, &kind, arena);
if (res != 0) goto failed;
Py_CLEAR(tmp);
} else {
PyErr_SetString(PyExc_TypeError, "required field \"kind\" missing from Str");
return 1;
}
*out = Str(s, kind, lineno, col_offset, arena);
if (*out == NULL) goto failed;
return 0;
}
......
......@@ -4971,14 +4971,25 @@ FstringParser_Dealloc(FstringParser *state)
static expr_ty
make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
{
PyObject *s = *str;
PyObject *kind, *s = *str;
const char *raw = STR(CHILD(n, 0));
/* currently Python allows up to 2 string modifiers */
char *ch, s_kind[3] = {0, 0, 0};
ch = s_kind;
while (*raw && *raw != '\'' && *raw != '"') {
*ch++ = *raw++;
}
kind = PyUnicode_FromString(s_kind);
if (!kind) {
return NULL;
}
*str = NULL;
assert(PyUnicode_CheckExact(s));
if (PyArena_AddPyObject(c->c_arena, s) < 0) {
Py_DECREF(s);
return NULL;
}
return Str(s, LINENO(n), n->n_col_offset, c->c_arena);
return Str(s, kind, LINENO(n), n->n_col_offset, c->c_arena);
}
/* Add a non-f-string (that is, a regular literal string). str is
......
python3-typed-ast (1.1.1-1) unstable; urgency=medium
* New upstream version
* debhelper 11
* Point Vcs fields to salsa.debian.org
* Standards-Version: 4.2.1
* Testsuite: autopkgtest-pkg-python
* Remove trailing whitespace in debian/control
* Drop ancient X-Python-Version field
-- Michael R. Crusoe <michael.crusoe@gmail.com> Sun, 23 Dec 2018 05:57:31 -0800
python3-typed-ast (1.1.0-1) unstable; urgency=medium
* New upstream version.
......
......@@ -2,21 +2,25 @@ Source: python3-typed-ast
Maintainer: Debian Med Packaging Team <debian-med-packaging@lists.alioth.debian.org>
Uploaders: Michael R. Crusoe <michael.crusoe@gmail.com>
Section: python
Testsuite: autopkgtest-pkg-python
Priority: optional
Build-Depends: debhelper (>= 9),
Build-Depends: debhelper (>= 11~),
dh-python,
python3-all,
python3-setuptools,
python3-all-dev
Standards-Version: 4.1.1
Vcs-Browser: https://anonscm.debian.org/cgit/debian-med/python3-typed-ast.git
Vcs-Git: https://anonscm.debian.org/git/debian-med/python3-typed-ast.git
Standards-Version: 4.2.1
Vcs-Browser: https://salsa.debian.org/med-team/python3-typed-ast
Vcs-Git: https://salsa.debian.org/med-team/python3-typed-ast.git
Homepage: http://www.mypy-lang.org/
X-Python3-Version: >= 3.3
Package: python3-typed-ast
Architecture: any
Depends: ${python3:Depends}, ${misc:Depends}, ${shlibs:Depends}
X-Python3-Version: ${python3:Versions}
Provides: ${python3:Provides}
Depends: ${python3:Depends},
${misc:Depends},
${shlibs:Depends}
Description: AST with PEP 484 type comments support
A fork of the CPython 2.7 and 3.5 ast modules with the ability to parse
PEP 484 type comments. The primary goals of this package are correctness and
......
import ast
import re
import sys
if sys.version_info[0] < 3 or sys.version_info[1] < 3:
sys.exit('Error: typed_ast only runs on Python 3.3 and above.')
......@@ -86,8 +88,14 @@ Python AST (plus type comments), and are both fast and correct, as they are
based on the CPython 2.7 and 3.6 parsers.
""".strip()
_version_re = re.compile(r'__version__\s+=\s+(?P<version>.*)')
with open('typed_ast/__init__.py', 'r', encoding='utf8') as f:
version = _version_re.search(f.read()).group('version')
version = str(ast.literal_eval(version))
setup (name = 'typed-ast',
version = '1.1.0',
version = version,
description = 'a fork of Python 2 and 3 ast modules with type comment support',
long_description = long_description,
author = 'David Fisher',
......
Metadata-Version: 1.1
Name: typed-ast
Version: 1.1.0
Version: 1.1.1
Summary: a fork of Python 2 and 3 ast modules with type comment support
Home-page: https://github.com/python/typed_ast
Author: David Fisher
......
LICENSE
MANIFEST.in
README.md
setup.py
ast27/Custom/typed_ast.c
ast27/Include/Python-ast.h
......
......@@ -19,9 +19,8 @@
called with `mode=func_type`.
- `Module` has a `type_ignores` field which contains a list of
lines which have been `# type: ignore`d.
- `Str` has a `has_b` boolean field which indicates if the string is
explicitly prefixed with a `b`. (This is deprecated and may be removed in
future versions.)
- `Str` has a `kind` string field which preserves the original string
prefix, so that `ast27.parse('br"test"').body[0].value.kind == 'br'`.
An abstract syntax tree can be generated by using the `parse()`
function from this module. The result will be a tree of objects whose
......
......@@ -21,6 +21,8 @@
newer Python syntax features.
- `Module` has a `type_ignores` field which contains a list of
lines which have been `# type: ignore`d.
- `Str` has a `kind` string field which preserves the original string
prefix, so that `ast3.parse('u"test"').body[0].value.kind == 'u'`.
An abstract syntax tree can be generated by using the `parse()`
function from this module. The result will be a tree of objects whose
......