Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 623ae29

Browse files
committed
#10510: Fix bug in forward port of 2.7 distutils patch.
Pointed out by Arfrever.
1 parent 9c1dba2 commit 623ae29

3 files changed

Lines changed: 77 additions & 3 deletions

File tree

Doc/faq/programming.rst

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ requested again. This is called "memoizing", and can be implemented like this::
401401

402402
# Calculate the value
403403
result = ... expensive computation ...
404-
_cache[(arg1, arg2)] = result # Store result in the cache
404+
_cache[(arg1, arg2)] = result # Store result in the cache
405405
return result
406406

407407
You could use a global variable containing a dictionary instead of the default
@@ -448,6 +448,81 @@ arguments a function can accept. For example, given the function definition::
448448
the values ``42``, ``314``, and ``somevar`` are arguments.
449449

450450

451+
Why did changing list 'y' also change list 'x'?
452+
------------------------------------------------
453+
454+
If you wrote code like::
455+
456+
>>> x = []
457+
>>> y = x
458+
>>> y.append(10)
459+
>>> y
460+
[10]
461+
>>> x
462+
[10]
463+
464+
you might be wondering why appending an element to ``y`` changed ``x`` too.
465+
466+
There are two factors that produce this result:
467+
468+
1) Variables are simply names that refer to objects. Doing ``y = x`` doesn't
469+
create a copy of the list -- it creates a new variable ``y`` that refers to
470+
the same object ``x`` refers to. This means that there is only one object
471+
(the list), and both ``x`` and ``y`` refer to it.
472+
2) Lists are :term:`mutable`, which means that you can change their content.
473+
474+
After the call to :meth:`~list.append`, the content of the mutable object has
475+
changed from ``[]`` to ``[10]``. Since both the variables refer to the same
476+
object, accessing either one of them accesses the modified value ``[10]``.
477+
478+
If we instead assign an immutable object to ``x``::
479+
480+
>>> x = 5 # ints are immutable
481+
>>> y = x
482+
>>> x = x + 1 # 5 can't be mutated, we are creating a new object here
483+
>>> x
484+
6
485+
>>> y
486+
5
487+
488+
we can see that in this case ``x`` and ``y`` are not equal anymore. This is
489+
because integers are :term:`immutable`, and when we do ``x = x + 1`` we are not
490+
mutating the int ``5`` by incrementing its value; instead, we are creating a
491+
new object (the int ``6``) and assigning it to ``x`` (that is, changing which
492+
object ``x`` refers to). After this assignment we have two objects (the ints
493+
``6`` and ``5``) and two variables that refer to them (``x`` now refers to
494+
``6`` but ``y`` still refers to ``5``).
495+
496+
Some operations (for example ``y.append(10)`` and ``y.sort()``) mutate the
497+
object, whereas superficially similar operations (for example ``y = y + [10]``
498+
and ``sorted(y)``) create a new object. In general in Python (and in all cases
499+
in the standard library) a method that mutates an object will return ``None``
500+
to help avoid getting the two types of operations confused. So if you
501+
mistakenly write ``y.sort()`` thinking it will give you a sorted copy of ``y``,
502+
you'll instead end up with ``None``, which will likely cause your program to
503+
generate an easily diagnosed error.
504+
505+
However, there is one class of operations where the same operation sometimes
506+
has different behaviors with different types: the augmented assignment
507+
operators. For example, ``+=`` mutates lists but not tuples or ints (``a_list
508+
+= [1, 2, 3]`` is equivalent to ``a_list.extend([1, 2, 3])`` and mutates
509+
``a_list``, whereas ``some_tuple += (1, 2, 3)`` and ``some_int += 1`` create
510+
new objects).
511+
512+
In other words:
513+
514+
* If we have a mutable object (:class:`list`, :class:`dict`, :class:`set`,
515+
etc.), we can use some specific operations to mutate it and all the variables
516+
that refer to it will see the change.
517+
* If we have an immutable object (:class:`str`, :class:`int`, :class:`tuple`,
518+
etc.), all the variables that refer to it will always see the same value,
519+
but operations that transform that value into a new value always return a new
520+
object.
521+
522+
If you want to know if two variables refer to the same object or not, you can
523+
use the :keyword:`is` operator, or the built-in function :func:`id`.
524+
525+
451526
How do I write a function with output parameters (call by reference)?
452527
---------------------------------------------------------------------
453528

Lib/distutils/command/upload.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ def upload_file(self, command, pyversion, filename):
164164
if value and value[-1:] == b'\r':
165165
body.write(b'\n') # write an extra newline (lurve Macs)
166166
body.write(end_boundary)
167-
body.write(b"\r\n")
168167
body = body.getvalue()
169168

170169
self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)

Lib/distutils/tests/test_upload.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def test_upload(self):
127127

128128
# what did we send ?
129129
headers = dict(self.last_open.req.headers)
130-
self.assertEqual(headers['Content-length'], '2163')
130+
self.assertEqual(headers['Content-length'], '2161')
131131
content_type = headers['Content-type']
132132
self.assertTrue(content_type.startswith('multipart/form-data'))
133133
self.assertEqual(self.last_open.req.get_method(), 'POST')

0 commit comments

Comments
 (0)