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
59953087
Commit
59953087
authored
Jun 14, 2013
by
Brett Cannon
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
dcf22693
25fefc47
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
52 additions
and
1 deletion
+52
-1
Doc/library/py_compile.rst
Doc/library/py_compile.rst
+10
-1
Doc/whatsnew/3.4.rst
Doc/whatsnew/3.4.rst
+5
-0
Lib/py_compile.py
Lib/py_compile.py
+14
-0
Lib/test/test_py_compile.py
Lib/test/test_py_compile.py
+20
-0
Misc/NEWS
Misc/NEWS
+3
-0
No files found.
Doc/library/py_compile.rst
View file @
59953087
...
@@ -41,6 +41,13 @@ byte-code cache files in the directory containing the source code.
...
@@ -41,6 +41,13 @@ byte-code cache files in the directory containing the source code.
is raised. This function returns the path to byte-compiled file, i.e.
is raised. This function returns the path to byte-compiled file, i.e.
whatever *cfile* value was used.
whatever *cfile* value was used.
If the path that *cfile* becomes (either explicitly specified or computed)
is a symlink or non-regular file, :exc:`FileExistsError` will be raised.
This is to act as a warning that import will turn those paths into regular
files if it is allowed to write byte-compiled files to those paths. This is
a side-effect of import using file renaming to place the final byte-compiled
file into place to prevent concurrent file writing issues.
*optimize* controls the optimization level and is passed to the built-in
*optimize* controls the optimization level and is passed to the built-in
:func:`compile` function. The default of ``-1`` selects the optimization
:func:`compile` function. The default of ``-1`` selects the optimization
level of the current interpreter.
level of the current interpreter.
...
@@ -53,7 +60,9 @@ byte-code cache files in the directory containing the source code.
...
@@ -53,7 +60,9 @@ byte-code cache files in the directory containing the source code.
.. versionchanged:: 3.4
.. versionchanged:: 3.4
Changed code to use :mod:`importlib` for the byte-code cache file writing.
Changed code to use :mod:`importlib` for the byte-code cache file writing.
This means file creation/writing semantics now match what :mod:`importlib`
This means file creation/writing semantics now match what :mod:`importlib`
does, e.g. permissions, write-and-move semantics, etc.
does, e.g. permissions, write-and-move semantics, etc. Also added the
caveat that :exc:`FileExistsError` is raised if *cfile* is a symlink or
non-regular file.
.. function:: main(args=None)
.. function:: main(args=None)
...
...
Doc/whatsnew/3.4.rst
View file @
59953087
...
@@ -272,3 +272,8 @@ that may require changes to your code.
...
@@ -272,3 +272,8 @@ that may require changes to your code.
* :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg**
* :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg**
argument is not set. Previously only ``NULL`` was returned.
argument is not set. Previously only ``NULL`` was returned.
* :func:`py_compile.compile` now raises :exc:`FileExistsError` if the file path
it would write to is a symlink or a non-regular file. This is to act as a
warning that import will overwrite those files with a regular file regardless
of what type of file path they were originally.
Lib/py_compile.py
View file @
59953087
...
@@ -7,6 +7,7 @@ import imp
...
@@ -7,6 +7,7 @@ import imp
import
importlib._bootstrap
import
importlib._bootstrap
import
importlib.machinery
import
importlib.machinery
import
os
import
os
import
os.path
import
sys
import
sys
import
traceback
import
traceback
...
@@ -96,12 +97,25 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1):
...
@@ -96,12 +97,25 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1):
See compileall.py for a script/module that uses this module to
See compileall.py for a script/module that uses this module to
byte-compile all installed files (or all files in selected
byte-compile all installed files (or all files in selected
directories).
directories).
Do note that FileExistsError is raised if cfile ends up pointing at a
non-regular file or symlink. Because the compilation uses a file renaming,
the resulting file would be regular and thus not the same type of file as
it was previously.
"""
"""
if
cfile
is
None
:
if
cfile
is
None
:
if
optimize
>=
0
:
if
optimize
>=
0
:
cfile
=
imp
.
cache_from_source
(
file
,
debug_override
=
not
optimize
)
cfile
=
imp
.
cache_from_source
(
file
,
debug_override
=
not
optimize
)
else
:
else
:
cfile
=
imp
.
cache_from_source
(
file
)
cfile
=
imp
.
cache_from_source
(
file
)
if
os
.
path
.
islink
(
cfile
):
msg
=
(
'{} is a symlink and will be changed into a regular file if '
'import writes a byte-compiled file to it'
)
raise
FileExistsError
(
msg
.
format
(
file
,
cfile
))
elif
os
.
path
.
exists
(
cfile
)
and
not
os
.
path
.
isfile
(
cfile
):
msg
=
(
'{} is a non-regular file and will be changed into a regular '
'one if import writes a byte-compiled file to it'
)
raise
FileExistsError
(
msg
.
format
(
file
,
cfile
))
loader
=
importlib
.
machinery
.
SourceFileLoader
(
'<py_compile>'
,
file
)
loader
=
importlib
.
machinery
.
SourceFileLoader
(
'<py_compile>'
,
file
)
source_bytes
=
loader
.
get_data
(
file
)
source_bytes
=
loader
.
get_data
(
file
)
try
:
try
:
...
...
Lib/test/test_py_compile.py
View file @
59953087
...
@@ -36,6 +36,26 @@ class PyCompileTests(unittest.TestCase):
...
@@ -36,6 +36,26 @@ class PyCompileTests(unittest.TestCase):
self
.
assertTrue
(
os
.
path
.
exists
(
self
.
pyc_path
))
self
.
assertTrue
(
os
.
path
.
exists
(
self
.
pyc_path
))
self
.
assertFalse
(
os
.
path
.
exists
(
self
.
cache_path
))
self
.
assertFalse
(
os
.
path
.
exists
(
self
.
cache_path
))
def
test_do_not_overwrite_symlinks
(
self
):
# In the face of a cfile argument being a symlink, bail out.
# Issue #17222
try
:
os
.
symlink
(
self
.
pyc_path
+
'.actual'
,
self
.
pyc_path
)
except
OSError
:
self
.
skipTest
(
'need to be able to create a symlink for a file'
)
else
:
assert
os
.
path
.
islink
(
self
.
pyc_path
)
with
self
.
assertRaises
(
FileExistsError
):
py_compile
.
compile
(
self
.
source_path
,
self
.
pyc_path
)
@
unittest
.
skipIf
(
not
os
.
path
.
exists
(
os
.
devnull
)
or
os
.
path
.
isfile
(
os
.
devnull
),
'requires os.devnull and for it to be a non-regular file'
)
def
test_do_not_overwrite_nonregular_files
(
self
):
# In the face of a cfile argument being a non-regular file, bail out.
# Issue #17222
with
self
.
assertRaises
(
FileExistsError
):
py_compile
.
compile
(
self
.
source_path
,
os
.
devnull
)
def
test_cache_path
(
self
):
def
test_cache_path
(
self
):
py_compile
.
compile
(
self
.
source_path
)
py_compile
.
compile
(
self
.
source_path
)
self
.
assertTrue
(
os
.
path
.
exists
(
self
.
cache_path
))
self
.
assertTrue
(
os
.
path
.
exists
(
self
.
cache_path
))
...
...
Misc/NEWS
View file @
59953087
...
@@ -1008,6 +1008,9 @@ Library
...
@@ -1008,6 +1008,9 @@ Library
Python
file
.
Patch
by
Ben
Morgan
.
Python
file
.
Patch
by
Ben
Morgan
.
-
Have
py_compile
use
importlib
as
much
as
possible
to
avoid
code
duplication
.
-
Have
py_compile
use
importlib
as
much
as
possible
to
avoid
code
duplication
.
Code
now
raises
FileExistsError
if
the
file
path
to
be
used
for
the
byte
-
compiled
file
is
a
symlink
or
non
-
regular
file
as
a
warning
that
import
will
not
keep
the
file
path
type
if
it
writes
to
that
path
.
-
Issue
#
180022
:
Have
site
.
addpackage
()
consider
already
known
paths
even
when
-
Issue
#
180022
:
Have
site
.
addpackage
()
consider
already
known
paths
even
when
none
are
explicitly
passed
in
.
Bug
report
and
fix
by
Kirill
.
none
are
explicitly
passed
in
.
Bug
report
and
fix
by
Kirill
.
...
...
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