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
da0a2117
Commit
da0a2117
authored
Sep 05, 2010
by
Georg Brandl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrap and consistency fixes.
parent
d881f316
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
175 additions
and
175 deletions
+175
-175
Doc/whatsnew/3.2.rst
Doc/whatsnew/3.2.rst
+175
-175
No files found.
Doc/whatsnew/3.2.rst
View file @
da0a2117
...
@@ -36,14 +36,12 @@
...
@@ -36,14 +36,12 @@
necessary (especially when a final release is some months away).
necessary (especially when a final release is some months away).
* Credit the author of a patch or bugfix. Just the name is
* Credit the author of a patch or bugfix. Just the name is
sufficient; the e-mail address isn't necessary.
sufficient; the e-mail address isn't necessary. It's helpful to
add the issue number:
* It's helpful to add the bug/patch number as a comment:
% Patch 12345
XXX Describe the transmogrify() function added to the socket
XXX Describe the transmogrify() function added to the socket
module.
module.
(Contributed by P.Y. Developer.)
(Contributed by P.Y. Developer
; :issue:`12345`
.)
This saves the maintainer the effort of going through the SVN log
This saves the maintainer the effort of going through the SVN log
when researching a change.
when researching a change.
...
@@ -54,20 +52,19 @@ This article explains the new features in Python 3.2, compared to 3.1.
...
@@ -54,20 +52,19 @@ This article explains the new features in Python 3.2, compared to 3.1.
PEP 391: Dictionary Based Configuration for Logging
PEP 391: Dictionary Based Configuration for Logging
===================================================
===================================================
The :mod:`logging` module had two ways of configuring the module, either
The :mod:`logging` module had two ways of configuring the module, either calling
calling functions for each option or by reading an external file saved
functions for each option or by reading an external file saved in a ConfigParser
in a ConfigParser format. Those options did not provide the flexibility
format. Those options did not provide the flexibility to create configurations
to create configurations from JSON or YAML files and they did not support
from JSON or YAML files and they did not support incremental configuration which
incremental configuration which is needed for specifying logger options
is needed for specifying logger options from a command line.
from a command line.
To support a more flexible style, the module now offers
To support a more flexible style, the module now offers
:func:`logging.config.dictConfig` to use dictionaries to specify logger
:func:`logging.config.dictConfig` to use dictionaries to specify logger
configurations (including formatters, handlers, filters, and loggers).
configurations (including formatters, handlers, filters, and loggers).
For
For example:
:
example
:
>>> import logging.config
>>> import logging.config
>>> logging.config.dictConfig(json.load(open('log.cfg', 'rb')))
>>> logging.config.dictConfig(json.load(open('log.cfg', 'rb')))
The above fragment configures logging from a JSON encoded dictionary stored in
The above fragment configures logging from a JSON encoded dictionary stored in
file called "log.cfg". Here's a working example of a configuration dictionary::
file called "log.cfg". Here's a working example of a configuration dictionary::
...
@@ -94,6 +91,7 @@ file called "log.cfg". Here's a working example of a configuration dictionary::
...
@@ -94,6 +91,7 @@ file called "log.cfg". Here's a working example of a configuration dictionary::
:pep:`391` - Dictionary Based Configuration for Logging
:pep:`391` - Dictionary Based Configuration for Logging
PEP written by Vinay Sajip.
PEP written by Vinay Sajip.
PEP 3147: PYC Repository Directories
PEP 3147: PYC Repository Directories
=====================================
=====================================
...
@@ -117,15 +115,15 @@ cluttering source directories, the *pyc* files are now collected in a
...
@@ -117,15 +115,15 @@ cluttering source directories, the *pyc* files are now collected in a
Aside from the filenames and target directories, the new scheme has a few
Aside from the filenames and target directories, the new scheme has a few
aspects that are visible to the programmer:
aspects that are visible to the programmer:
* Imported modules now have a :attr:`__cached__` attribute which stores the
* Imported modules now have a :attr:`__cached__` attribute which stores the
name
name of the actual file that was imported:
:
of the actual file that was imported
:
>>> import collections
>>> import collections
>>> collections.__cached__
>>> collections.__cached__
'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
* The tag that is unique to each interpreter is accessible from the :mod:`imp`
* The tag that is unique to each interpreter is accessible from the :mod:`imp`
module:
:
module:
>>> import imp
>>> import imp
>>> imp.get_tag()
>>> imp.get_tag()
...
@@ -148,6 +146,7 @@ aspects that are visible to the programmer:
...
@@ -148,6 +146,7 @@ aspects that are visible to the programmer:
:pep:`3147` - PYC Repository Directories
:pep:`3147` - PYC Repository Directories
PEP written by Barry Warsaw.
PEP written by Barry Warsaw.
PEP 3149 ABI Version Tagged .so Files
PEP 3149 ABI Version Tagged .so Files
=====================================
=====================================
...
@@ -184,27 +183,27 @@ Other Language Changes
...
@@ -184,27 +183,27 @@ Other Language Changes
Some smaller changes made to the core Python language are:
Some smaller changes made to the core Python language are:
* The :func:`hasattr` function used to catch and suppress any Exception.
* The :func:`hasattr` function used to catch and suppress any Exception.
Now,
Now, it only catches :exc:`AttributeError`. Under the hood, :func:`hasattr`
it only catches :exc:`AttributeError`. Under the hood, :func:`hasattr` works
works by calling :func:`getattr` and throwing away the results. This is
by calling :func:`getattr` and throwing away the results. This is necessary
necessary because dynamic attribute creation is possible using
because dynamic attribute creation is possible using :meth:`__getattribute__`
:meth:`__getattribute__` or :meth:`__getattr`. If :func:`hasattr` were to
or :meth:`__getattr`. If :func:`hasattr` were to just scan instance and class
just scan instance and class dictionaries it would miss the dynmaic methods
dictionaries it would miss the dynmaic methods and make it difficult to
and make it difficult to
implement proxy objects.
implement proxy objects.
(Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.)
(Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.)
* The :func:`str` of a float or complex number is now the same as it
* The :func:`str` of a float or complex number is now the same as it
:func:`repr`. Previously, the :func:`str` form was shorter but that just
:func:`repr`. Previously, the :func:`str` form was shorter but that just
caused confusion and is no longer needed now that we the shortest possible
caused confusion and is no longer needed now that we the shortest possible
:func:`repr` is displayed by default:
:
:func:`repr` is displayed by default:
>>> repr(math.pi)
>>> repr(math.pi)
'3.141592653589793'
'3.141592653589793'
>>> str(math.pi)
>>> str(math.pi)
'3.141592653589793'
'3.141592653589793'
(Proposed and implemented by Mark Dickinson; :issue:`9337`
).
(Proposed and implemented by Mark Dickinson; :issue:`9337`
.)
* The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
* The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
pointing to the original callable function. This allows wrapped functions to
pointing to the original callable function. This allows wrapped functions to
...
@@ -218,14 +217,15 @@ Some smaller changes made to the core Python language are:
...
@@ -218,14 +217,15 @@ Some smaller changes made to the core Python language are:
* The :mod:`abc` module now supports :func:`abstractclassmethod` and
* The :mod:`abc` module now supports :func:`abstractclassmethod` and
:func:`abstractstaticmethod`.
:func:`abstractstaticmethod`.
(:issue:`5867`)
(:issue:`5867`.)
New, Improved, and Deprecated Modules
New, Improved, and Deprecated Modules
=====================================
=====================================
* The :mod:`functools` module now includes a new decorator for caching
* The :mod:`functools` module now includes a new decorator for caching
function
function calls. :func:`functools.lru_cache` can save repeated queries to an
calls. :func:`functools.lru_cache` can save repeated queries to an external
external
resource whenever the results are expected to be the same.
resource whenever the results are expected to be the same.
For example, adding a caching decorator to a database query function can save
For example, adding a caching decorator to a database query function can save
database accesses for popular searches::
database accesses for popular searches::
...
@@ -237,7 +237,7 @@ New, Improved, and Deprecated Modules
...
@@ -237,7 +237,7 @@ New, Improved, and Deprecated Modules
return c.fetchone()[0]
return c.fetchone()[0]
To help with choosing an effective cache size, the wrapped function is
To help with choosing an effective cache size, the wrapped function is
instrumented with two attributes *cache_hits* and *cache_misses*:
:
instrumented with two attributes *cache_hits* and *cache_misses*:
>>> for name in user_requests:
>>> for name in user_requests:
... get_phone_number(name)
... get_phone_number(name)
...
@@ -245,24 +245,24 @@ New, Improved, and Deprecated Modules
...
@@ -245,24 +245,24 @@ New, Improved, and Deprecated Modules
4805 980
4805 980
If the phonelist table gets updated, the outdated contents of the cache can be
If the phonelist table gets updated, the outdated contents of the cache can be
cleared with:
:
cleared with:
>>> get_phone_number.cache_clear()
>>> get_phone_number.cache_clear()
(Contributed by Raymond Hettinger)
(Contributed by Raymond Hettinger
.
)
* The previously deprecated :func:`contextlib.nested` function has been
* The previously deprecated :func:`contextlib.nested` function has been
removed
removed in favor of a plain :keyword:`with` statement which can
in favor of a plain :keyword:`with` statement which can accept multiple
accept multiple context managers. The latter technique is faster
context managers. The latter technique is faster (because it is built-in),
(because it is built-in), and it does a better job finalizing multiple
and it does a better job finalizing multiple context managers when one of them
context managers when one of them
raises an exception.
raises an exception.
(Contributed by Georg Brandl and Mattias Brändström;
(Contributed by Georg Brandl and Mattias Brändström;
`appspot issue 53094 <http://codereview.appspot.com/53094>`_.)
`appspot issue 53094 <http://codereview.appspot.com/53094>`_.)
* The :class:`ftplib.FTP` class now supports the context manager protocol
* The :class:`ftplib.FTP` class now supports the context manager protocol
to
to unconditionally consume :exc:`socket.error` exceptions and to close
unconditionally consume :exc:`socket.error` exceptions and to close the ftp
the ftp connection when done:
:
connection when done
:
>>> from ftplib import FTP
>>> from ftplib import FTP
>>> with FTP("ftp1.at.proftpd.org") as ftp:
>>> with FTP("ftp1.at.proftpd.org") as ftp:
...
@@ -277,9 +277,10 @@ New, Improved, and Deprecated Modules
...
@@ -277,9 +277,10 @@ New, Improved, and Deprecated Modules
(Contributed by Tarek Ziadé and Giampaolo Rodolà; :issue:`4972`.)
(Contributed by Tarek Ziadé and Giampaolo Rodolà; :issue:`4972`.)
* A warning message will now get printed at interpreter shutdown if
* A warning message will now get printed at interpreter shutdown if the
the :data:`gc.garbage` list isn't empty. This is meant to make the
:data:`gc.garbage` list isn't empty. This is meant to make the programmer
programmer aware that his code contains object finalization issues.
aware that his code contains object finalization issues.
(Added by Antoine Pitrou; :issue:`477863`.)
(Added by Antoine Pitrou; :issue:`477863`.)
* The :mod:`os` module now has the :const:`ST_RDONLY` and :const:`ST_NOSUID`
* The :mod:`os` module now has the :const:`ST_RDONLY` and :const:`ST_NOSUID`
...
@@ -289,72 +290,66 @@ New, Improved, and Deprecated Modules
...
@@ -289,72 +290,66 @@ New, Improved, and Deprecated Modules
* The :func:`shutil.copytree` function has two new options:
* The :func:`shutil.copytree` function has two new options:
* *ignore_dangling_symlinks*: when ``symlinks=False`` dp that the
* *ignore_dangling_symlinks*: when ``symlinks=False`` dp that the function
function copies the file pointed to by the symlink, not the symlink
copies the file pointed to by the symlink, not the symlink itself. This
itself. This option will silence the error raised if the file doesn't
option will silence the error raised if the file doesn't exist.
exist.
* *copy_function*: is a callable that will be used to copy files.
* *copy_function*: is a callable that will be used to copy files.
:func:`shutil.copy2` is used by default.
:func:`shutil.copy2` is used by default.
(Contributed by Tarek Ziadé.)
(Contributed by Tarek Ziadé.)
* Socket objects now have a :meth:`~socket.socket.detach()` method which
* Socket objects now have a :meth:`~socket.socket.detach()` method which
puts
puts the socket into closed state without actually closing the underlying
the socket into closed state without actually closing the underlying file
file
descriptor. The latter can then be reused for other purposes.
descriptor. The latter can then be reused for other purposes.
(Added by Antoine Pitrou; :issue:`8524`.)
(Added by Antoine Pitrou; :issue:`8524`.)
* The :mod:`sqlite3` module has two new capabilities.
* The :mod:`sqlite3` module has two new capabilities.
The :attr:`Connection.in_transit` attribute is true if there is an
The :attr:`Connection.in_transit` attribute is true if there is an
active
active
transaction for uncommitted changes.
transaction for uncommitted changes.
The :meth:`Connection.enable_load_extension` and
The :meth:`Connection.enable_load_extension` and
:meth:`Connection.load_extension` methods allows you to load SQLite extensions
:meth:`Connection.load_extension` methods allows you to load SQLite extensions
from ".so" files. One well-known extension is the fulltext-search extension
from ".so" files. One well-known extension is the fulltext-search extension
distributed with SQLite.
distributed with SQLite.
(Contributed by R. David Murray and Shashwat Anand
,
:issue:`8845`.)
(Contributed by R. David Murray and Shashwat Anand
;
:issue:`8845`.)
* The :mod:`ssl` module has a new class, :class:`~ssl.SSLContext` which
* The :mod:`ssl` module has a new class, :class:`~ssl.SSLContext` which serves
serves as a container for various persistent SSL data, such as protocol
as a container for various persistent SSL data, such as protocol settings,
settings, certificates, private keys, and various other options.
certificates, private keys, and various other options. The
The :meth:`~ssl.SSLContext.wrap_socket` method allows to create an
:meth:`~ssl.SSLContext.wrap_socket` method allows to create an SSL socket from
SSL socket from such an SSL context.
such an SSL context. (Added by Antoine Pitrou; :issue:`8550`.)
(Added by Antoine Pitrou; :issue:`8550`.)
The :func:`ssl.wrap_socket` constructor function now takes a
The :func:`ssl.wrap_socket` constructor function now takes a *ciphers*
*ciphers* argument that's a string listing the encryption algorithms
argument that's a string listing the encryption algorithms to be allowed; the
to be allowed; the format of the string is described
format of the string is described `in the OpenSSL documentation
`in the OpenSSL documentation
<http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`__. (Added
<http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`__.
by Antoine Pitrou; :issue:`8322`.)
(Added by Antoine Pitrou; :issue:`8322`.)
Various options have been added to the :mod:`ssl` module, such as
Various options have been added to the :mod:`ssl` module, such as
:data:`~ssl.OP_NO_SSLv2` which allows to force disabling of the insecure
:data:`~ssl.OP_NO_SSLv2` which allows to force disabling of the insecure and
and obsolete SSLv2 protocol.
obsolete SSLv2 protocol. (Added by Antoine Pitrou; :issue:`4870`.)
(Added by Antoine Pitrou; :issue:`4870`.)
Another change makes the extension load all of OpenSSL's ciphers and digest
Another change makes the extension load all of OpenSSL's ciphers and
algorithms so that they're all available. Some SSL certificates couldn't be
digest algorithms so that they're all available. Some SSL
verified, reporting an "unknown algorithm" error. (Reported by Beda Kosata,
certificates couldn't be verified, reporting an "unknown algorithm"
and fixed by Antoine Pitrou; :issue:`8484`.)
error. (Reported by Beda Kosata, and fixed by Antoine Pitrou;
:issue:`8484`.)
The version of OpenSSL being used is now available as the module attributes
:data:`ssl.OPENSSL_VERSION` (a string), :data:`ssl.OPENSSL_VERSION_INFO` (a
The version of OpenSSL being used is now available as the module
5-tuple), and :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by
attributes :data:`ssl.OPENSSL_VERSION` (a string),
Antoine Pitrou; :issue:`8321`.)
:data:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and
:data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by Antoine
* The previously deprecated :func:`string.maketrans` function has been removed
Pitrou; :issue:`8321`.)
in favor of the static methods, :meth:`bytes.maketrans` and
* The previously deprecated :func:`string.maketrans` function has been
removed in favor of the static methods, :meth:`bytes.maketrans` and
:meth:`bytearray.maketrans`. This change solves the confusion around which
:meth:`bytearray.maketrans`. This change solves the confusion around which
types were supported by the :mod:`string` module. Now, :class:`str`,
types were supported by the :mod:`string` module. Now, :class:`str`,
:class:`bytes`, and :class:`bytearray` each have their own **maketrans** and
:class:`bytes`, and :class:`bytearray` each have their own **maketrans** and
**translate** methods with intermediate translation tables of the
**translate** methods with intermediate translation tables of the
appropriate
appropriate
type.
type.
(Contributed by Georg Brandl; :issue:`5675`.)
(Contributed by Georg Brandl; :issue:`5675`.)
...
@@ -365,44 +360,46 @@ New, Improved, and Deprecated Modules
...
@@ -365,44 +360,46 @@ New, Improved, and Deprecated Modules
(Contributed by Giampaolo Rodolà; :issue:`8807`.)
(Contributed by Giampaolo Rodolà; :issue:`8807`.)
Multi-threading
Multi-threading
===============
===============
* The mechanism for serializing execution of concurrently running Python
* The mechanism for serializing execution of concurrently running Python
threads
threads (generally known as the GIL or Global Interpreter Lock) has been
(generally known as the GIL or Global Interpreter Lock) has been rewritten.
rewritten. Among the objectives were more predictable switching intervals
Among the objectives were more predictable switching intervals and reduced
and reduced overhead due to lock contention and the number of ensuing
overhead due to lock contention and the number of ensuing system calls. The
system calls. The notion of a "check interval" to allow thread switches
notion of a "check interval" to allow thread switches has been abandoned and
has been abandoned and replaced by an absolute duration expressed in
replaced by an absolute duration expressed in seconds. This parameter is
seconds. This parameter is tunable through :func:`sys.setswitchinterval()`.
tunable through :func:`sys.setswitchinterval()`. It currently defaults to 5
It currently defaults to 5
milliseconds.
milliseconds.
Additional details about the implementation can be read from a `python-dev
Additional details about the implementation can be read from a `python-dev
mailing-list message
mailing-list message
<http://mail.python.org/pipermail/python-dev/2009-October/093321.html>`_
<http://mail.python.org/pipermail/python-dev/2009-October/093321.html>`_
(however, "priority requests" as exposed in this message have not been
(however, "priority requests" as exposed in this message have not been
kept
kept
for inclusion).
for inclusion).
(Contributed by Antoine Pitrou.)
(Contributed by Antoine Pitrou.)
* Recursive locks (created with the :func:`threading.RLock` API) now benefit
* Recursive locks (created with the :func:`threading.RLock` API) now benefit
from a C implementation which makes them as fast as regular locks, and
from a C implementation which makes them as fast as regular locks, and
between
between
10x and 15x faster than their previous pure Python implementation.
10x and 15x faster than their previous pure Python implementation.
(Contributed by Antoine Pitrou; :issue:`3001`.)
(Contributed by Antoine Pitrou; :issue:`3001`.)
* Regular and recursive locks now accept an optional *timeout* argument
* Regular and recursive locks now accept an optional *timeout* argument to their
to their ``acquire`` method. (Contributed by Antoine Pitrou; :issue:`7316`)
``acquire`` method. (Contributed by Antoine Pitrou; :issue:`7316`.)
Similarly, :meth:`threading.Semaphore.acquire` also gains a *timeout*
Similarly, :meth:`threading.Semaphore.acquire` also gains a *timeout*
argument. (Contributed by Torsten Landschoff; :issue:`850728`.)
argument. (Contributed by Torsten Landschoff; :issue:`850728`.)
Optimizations
..
Optimizations
=============
=============
Major performance enhancements have been added:
Major performance enhancements have been added:
* Stub
* Stub
Filenames and unicode
Filenames and unicode
...
@@ -418,10 +415,10 @@ The :mod:`os` module has two new functions: :func:`os.fsencode` and
...
@@ -418,10 +415,10 @@ The :mod:`os` module has two new functions: :func:`os.fsencode` and
:func:`os.fsdecode`.
:func:`os.fsdecode`.
IDLE
..
IDLE
====
====
* Stub
* Stub
Build and C API Changes
Build and C API Changes
...
@@ -429,27 +426,30 @@ Build and C API Changes
...
@@ -429,27 +426,30 @@ Build and C API Changes
Changes to Python's build process and to the C API include:
Changes to Python's build process and to the C API include:
* The C functions that access the Unicode Database now accept and
* The C functions that access the Unicode Database now accept and
return
return
characters from the full Unicode range, even on narrow unicode builds
characters from the full Unicode range, even on narrow unicode builds
(Py_UNICODE_TOLOWER, Py_UNICODE_ISDECIMAL, and others). A visible difference
(Py_UNICODE_TOLOWER, Py_UNICODE_ISDECIMAL, and others). A visible difference
in Python is that :cfunc:`unicodedata.numeric` now returns the correct value for
in Python is that :func:`unicodedata.numeric` now returns the correct value
large code points, and :func:`repr` may consider more characters as printable.
for large code points, and :func:`repr` may consider more characters as
printable.
(Reported by Bupjoe Lee and fixed by Amaury Forgeot D'Arc; :issue:`5127`.)
(Reported by Bupjoe Lee and fixed by Amaury Forgeot D'Arc; :issue:`5127`.)
* Computed gotos are now enabled by default on supported
* Computed gotos are now enabled by default on supported compilers (which are
compilers (which are detected by the configure script). They can still
detected by the configure script). They can still be disable selectively by
be disable selectively by specifying ``--without-computed-gotos``.
specifying ``--without-computed-gotos``.
(Contributed by Antoine Pitrou; :issue:`9203`.)
(:issue:`9203`)
Porting to Python 3.2
Porting to Python 3.2
=====================
=====================
This section lists previously described changes and other bugfixes
This section lists previously described changes and other bugfixes
that may
that may
require changes to your code:
require changes to your code:
* bytearray objects cannot be used anymore as filenames: convert them to bytes
* :class:`bytearray` objects cannot be used anymore as filenames: convert them
to :class:`bytes`.
* PyArg_Parse*() functions:
* PyArg_Parse*() functions:
...
@@ -457,6 +457,6 @@ that may require changes to your code:
...
@@ -457,6 +457,6 @@ that may require changes to your code:
* "w" and "w#" formats has been removed: use "w*" instead
* "w" and "w#" formats has been removed: use "w*" instead
* The :ctype:`PyCObject` type, deprecated in 3.1, has been removed. To wrap
* The :ctype:`PyCObject` type, deprecated in 3.1, has been removed. To wrap
opaque C pointers in Python objects, the :ctype:`PyCapsule` API should be
opaque C pointers in Python objects, the :ctype:`PyCapsule` API should be
used
used instead; the new type has a well defined interface for passing typing
instead; the new type has a well defined interface for passing typing safety
safety
information and a less complicated signature for calling a destructor.
information and a less complicated signature for calling a destructor.
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