Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
cbcd221d
Commit
cbcd221d
authored
Aug 21, 2016
by
Nick Coghlan
Browse files
Options
Browse Files
Download
Plain Diff
Merge #27782 fix from 3.5
parents
f9ed528f
8682f578
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
83 additions
and
32 deletions
+83
-32
Doc/c-api/module.rst
Doc/c-api/module.rst
+1
-1
Include/moduleobject.h
Include/moduleobject.h
+1
-1
Lib/test/test_importlib/extension/test_loader.py
Lib/test/test_importlib/extension/test_loader.py
+9
-0
Misc/ACKS
Misc/ACKS
+1
-0
Misc/NEWS
Misc/NEWS
+4
-0
Modules/_testmultiphase.c
Modules/_testmultiphase.c
+32
-1
Objects/moduleobject.c
Objects/moduleobject.c
+35
-29
No files found.
Doc/c-api/module.rst
View file @
cbcd221d
...
@@ -324,7 +324,7 @@ The available slot types are:
...
@@ -324,7 +324,7 @@ The available slot types are:
:c:type:`PyModule_Type`. Any type can be used, as long as it supports
:c:type:`PyModule_Type`. Any type can be used, as long as it supports
setting and getting import-related attributes.
setting and getting import-related attributes.
However, only ``PyModule_Type`` instances may be returned if the
However, only ``PyModule_Type`` instances may be returned if the
``PyModuleDef`` has non-*NULL* ``m_
methods``, ``m_
traverse``, ``m_clear``,
``PyModuleDef`` has non-*NULL* ``m_traverse``, ``m_clear``,
``m_free``; non-zero ``m_size``; or slots other than ``Py_mod_create``.
``m_free``; non-zero ``m_size``; or slots other than ``Py_mod_create``.
.. c:var:: Py_mod_exec
.. c:var:: Py_mod_exec
...
...
Include/moduleobject.h
View file @
cbcd221d
...
@@ -77,7 +77,7 @@ typedef struct PyModuleDef{
...
@@ -77,7 +77,7 @@ typedef struct PyModuleDef{
traverseproc
m_traverse
;
traverseproc
m_traverse
;
inquiry
m_clear
;
inquiry
m_clear
;
freefunc
m_free
;
freefunc
m_free
;
}
PyModuleDef
;
}
PyModuleDef
;
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
...
Lib/test/test_importlib/extension/test_loader.py
View file @
cbcd221d
...
@@ -212,6 +212,15 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
...
@@ -212,6 +212,15 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
self
.
assertNotEqual
(
type
(
mod
),
type
(
unittest
))
self
.
assertNotEqual
(
type
(
mod
),
type
(
unittest
))
self
.
assertEqual
(
mod
.
three
,
3
)
self
.
assertEqual
(
mod
.
three
,
3
)
# issue 27782
def
test_nonmodule_with_methods
(
self
):
'''Test creating a non-module object with methods defined'''
name
=
self
.
name
+
'_nonmodule_with_methods'
mod
=
self
.
load_module_by_name
(
name
)
self
.
assertNotEqual
(
type
(
mod
),
type
(
unittest
))
self
.
assertEqual
(
mod
.
three
,
3
)
self
.
assertEqual
(
mod
.
bar
(
10
,
1
),
9
)
def
test_null_slots
(
self
):
def
test_null_slots
(
self
):
'''Test that NULL slots aren't a problem'''
'''Test that NULL slots aren't a problem'''
name
=
self
.
name
+
'_null_slots'
name
=
self
.
name
+
'_null_slots'
...
...
Misc/ACKS
View file @
cbcd221d
...
@@ -1679,6 +1679,7 @@ Nickolai Zeldovich
...
@@ -1679,6 +1679,7 @@ Nickolai Zeldovich
Yuxiao Zeng
Yuxiao Zeng
Uwe Zessin
Uwe Zessin
Cheng Zhang
Cheng Zhang
Xiang Zhang
Kai Zhu
Kai Zhu
Tarek Ziadé
Tarek Ziadé
Jelle Zijlstra
Jelle Zijlstra
...
...
Misc/NEWS
View file @
cbcd221d
...
@@ -10,6 +10,10 @@ What's New in Python 3.6.0 beta 1
...
@@ -10,6 +10,10 @@ What's New in Python 3.6.0 beta 1
Core and Builtins
Core and Builtins
-----------------
-----------------
- Issue #27782: Multi-phase extension module import now correctly allows the
``m_methods`` field to be used to add module level functions to instances
of non-module types returned from ``Py_create_mod``. Patch by Xiang Zhang.
- Issue #27487: Warn if a submodule argument to "python -m" or
- Issue #27487: Warn if a submodule argument to "python -m" or
runpy.run_module() is found in sys.modules after parent packages are
runpy.run_module() is found in sys.modules after parent packages are
imported, but before the submodule is executed.
imported, but before the submodule is executed.
...
...
Modules/_testmultiphase.c
View file @
cbcd221d
...
@@ -248,6 +248,7 @@ PyInit__testmultiphase(PyObject *spec)
...
@@ -248,6 +248,7 @@ PyInit__testmultiphase(PyObject *spec)
/**** Importing a non-module object ****/
/**** Importing a non-module object ****/
static
PyModuleDef
def_nonmodule
;
static
PyModuleDef
def_nonmodule
;
static
PyModuleDef
def_nonmodule_with_methods
;
/* Create a SimpleNamespace(three=3) */
/* Create a SimpleNamespace(three=3) */
static
PyObject
*
static
PyObject
*
...
@@ -255,7 +256,7 @@ createfunc_nonmodule(PyObject *spec, PyModuleDef *def)
...
@@ -255,7 +256,7 @@ createfunc_nonmodule(PyObject *spec, PyModuleDef *def)
{
{
PyObject
*
dct
,
*
ns
,
*
three
;
PyObject
*
dct
,
*
ns
,
*
three
;
if
(
def
!=
&
def_nonmodule
)
{
if
(
def
!=
&
def_nonmodule
&&
def
!=
&
def_nonmodule_with_methods
)
{
PyErr_SetString
(
PyExc_SystemError
,
"def does not match"
);
PyErr_SetString
(
PyExc_SystemError
,
"def does not match"
);
return
NULL
;
return
NULL
;
}
}
...
@@ -291,6 +292,36 @@ PyInit__testmultiphase_nonmodule(PyObject *spec)
...
@@ -291,6 +292,36 @@ PyInit__testmultiphase_nonmodule(PyObject *spec)
return
PyModuleDef_Init
(
&
def_nonmodule
);
return
PyModuleDef_Init
(
&
def_nonmodule
);
}
}
PyDoc_STRVAR
(
nonmodule_bar_doc
,
"bar(i,j)
\n
\
\n
\
Return the difference of i - j."
);
static
PyObject
*
nonmodule_bar
(
PyObject
*
self
,
PyObject
*
args
)
{
long
i
,
j
;
long
res
;
if
(
!
PyArg_ParseTuple
(
args
,
"ll:bar"
,
&
i
,
&
j
))
return
NULL
;
res
=
i
-
j
;
return
PyLong_FromLong
(
res
);
}
static
PyMethodDef
nonmodule_methods
[]
=
{
{
"bar"
,
nonmodule_bar
,
METH_VARARGS
,
nonmodule_bar_doc
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyModuleDef
def_nonmodule_with_methods
=
TEST_MODULE_DEF
(
"_testmultiphase_nonmodule_with_methods"
,
slots_create_nonmodule
,
nonmodule_methods
);
PyMODINIT_FUNC
PyInit__testmultiphase_nonmodule_with_methods
(
PyObject
*
spec
)
{
return
PyModuleDef_Init
(
&
def_nonmodule_with_methods
);
}
/**** Non-ASCII-named modules ****/
/**** Non-ASCII-named modules ****/
static
PyModuleDef
def_nonascii_latin
=
{
\
static
PyModuleDef
def_nonascii_latin
=
{
\
...
...
Objects/moduleobject.c
View file @
cbcd221d
...
@@ -130,6 +130,34 @@ check_api_version(const char *name, int module_api_version)
...
@@ -130,6 +130,34 @@ check_api_version(const char *name, int module_api_version)
return
1
;
return
1
;
}
}
static
int
_add_methods_to_object
(
PyObject
*
module
,
PyObject
*
name
,
PyMethodDef
*
functions
)
{
PyObject
*
func
;
PyMethodDef
*
fdef
;
for
(
fdef
=
functions
;
fdef
->
ml_name
!=
NULL
;
fdef
++
)
{
if
((
fdef
->
ml_flags
&
METH_CLASS
)
||
(
fdef
->
ml_flags
&
METH_STATIC
))
{
PyErr_SetString
(
PyExc_ValueError
,
"module functions cannot set"
" METH_CLASS or METH_STATIC"
);
return
-
1
;
}
func
=
PyCFunction_NewEx
(
fdef
,
(
PyObject
*
)
module
,
name
);
if
(
func
==
NULL
)
{
return
-
1
;
}
if
(
PyObject_SetAttrString
(
module
,
fdef
->
ml_name
,
func
)
!=
0
)
{
Py_DECREF
(
func
);
return
-
1
;
}
Py_DECREF
(
func
);
}
return
0
;
}
PyObject
*
PyObject
*
PyModule_Create2
(
struct
PyModuleDef
*
module
,
int
module_api_version
)
PyModule_Create2
(
struct
PyModuleDef
*
module
,
int
module_api_version
)
{
{
...
@@ -269,7 +297,7 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api
...
@@ -269,7 +297,7 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api
}
}
}
}
}
else
{
}
else
{
m
=
PyModule_New
(
name
);
m
=
PyModule_New
Object
(
nameobj
);
if
(
m
==
NULL
)
{
if
(
m
==
NULL
)
{
goto
error
;
goto
error
;
}
}
...
@@ -297,7 +325,7 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api
...
@@ -297,7 +325,7 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api
}
}
if
(
def
->
m_methods
!=
NULL
)
{
if
(
def
->
m_methods
!=
NULL
)
{
ret
=
PyModule_AddFunctions
(
m
,
def
->
m_methods
);
ret
=
_add_methods_to_object
(
m
,
nameobj
,
def
->
m_methods
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
{
goto
error
;
goto
error
;
}
}
...
@@ -331,7 +359,7 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def)
...
@@ -331,7 +359,7 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def)
return
-
1
;
return
-
1
;
}
}
if
(
PyModule_Check
(
module
)
&&
def
->
m_size
>=
0
)
{
if
(
def
->
m_size
>=
0
)
{
PyModuleObject
*
md
=
(
PyModuleObject
*
)
module
;
PyModuleObject
*
md
=
(
PyModuleObject
*
)
module
;
if
(
md
->
md_state
==
NULL
)
{
if
(
md
->
md_state
==
NULL
)
{
/* Always set a state pointer; this serves as a marker to skip
/* Always set a state pointer; this serves as a marker to skip
...
@@ -387,37 +415,15 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def)
...
@@ -387,37 +415,15 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def)
int
int
PyModule_AddFunctions
(
PyObject
*
m
,
PyMethodDef
*
functions
)
PyModule_AddFunctions
(
PyObject
*
m
,
PyMethodDef
*
functions
)
{
{
PyObject
*
name
,
*
func
;
int
res
;
PyMethodDef
*
fdef
;
PyObject
*
name
=
PyModule_GetNameObject
(
m
);
name
=
PyModule_GetNameObject
(
m
);
if
(
name
==
NULL
)
{
if
(
name
==
NULL
)
{
return
-
1
;
return
-
1
;
}
}
for
(
fdef
=
functions
;
fdef
->
ml_name
!=
NULL
;
fdef
++
)
{
res
=
_add_methods_to_object
(
m
,
name
,
functions
);
if
((
fdef
->
ml_flags
&
METH_CLASS
)
||
(
fdef
->
ml_flags
&
METH_STATIC
))
{
PyErr_SetString
(
PyExc_ValueError
,
"module functions cannot set"
" METH_CLASS or METH_STATIC"
);
Py_DECREF
(
name
);
return
-
1
;
}
func
=
PyCFunction_NewEx
(
fdef
,
(
PyObject
*
)
m
,
name
);
if
(
func
==
NULL
)
{
Py_DECREF
(
name
);
return
-
1
;
}
if
(
PyObject_SetAttrString
(
m
,
fdef
->
ml_name
,
func
)
!=
0
)
{
Py_DECREF
(
func
);
Py_DECREF
(
name
);
return
-
1
;
}
Py_DECREF
(
func
);
}
Py_DECREF
(
name
);
Py_DECREF
(
name
);
return
0
;
return
res
;
}
}
int
int
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment