Skip to content

bpo-29196: Removed old-deprecated classes Plist, Dict and _InternalDict #488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

32 changes: 8 additions & 24 deletions Doc/library/plistlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,12 @@ The following functions are deprecated:
This function calls :func:`load` to do the actual work, see the documentation
of :func:`that function <load>` for an explanation of the keyword arguments.

.. note::

Dict values in the result have a ``__getattr__`` method that defers
to ``__getitem_``. This means that you can use attribute access to
access items of these dictionaries.

.. deprecated:: 3.4 Use :func:`load` instead.

.. versionchanged:: 3.7
Dict values in the result are now normal dicts. You no longer can use
attribute access to access items of these dictionaries.


.. function:: writePlist(rootObject, pathOrFile)

Expand All @@ -156,14 +154,12 @@ The following functions are deprecated:

See :func:`load` for a description of the keyword arguments.

.. note::

Dict values in the result have a ``__getattr__`` method that defers
to ``__getitem_``. This means that you can use attribute access to
access items of these dictionaries.

.. deprecated:: 3.4 Use :func:`loads` instead.

.. versionchanged:: 3.7
Dict values in the result are now normal dicts. You no longer can use
attribute access to access items of these dictionaries.


.. function:: writePlistToBytes(rootObject)

Expand All @@ -174,18 +170,6 @@ The following functions are deprecated:

The following classes are available:

.. class:: Dict([dict]):

Return an extended mapping object with the same value as dictionary
*dict*.

This class is a subclass of :class:`dict` where attribute access can
be used to access items. That is, ``aDict.key`` is the same as
``aDict['key']`` for getting, setting and deleting items in the mapping.

.. deprecated:: 3.0


.. class:: Data(data)

Return a "data" wrapper object around the bytes object *data*. This is used
Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,12 @@ API and Feature Removals
longer take keyword arguments. The first argument of :func:`int` can now
be passes only as positional argument.

* Removed previously deprecated in Python 2.4 classes ``Plist``, ``Dict`` and
``_InternalDict`` in the :mod:`plistlib` module. Dict values in the result
of functions :func:`~plistlib.readPlist` and
:func:`~plistlib.readPlistFromBytes` are now normal dicts. You no longer
can use attribute access to access items of these dictionaries.


Porting to Python 3.7
=====================
Expand Down
71 changes: 3 additions & 68 deletions Lib/plistlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"""
__all__ = [
"readPlist", "writePlist", "readPlistFromBytes", "writePlistToBytes",
"Plist", "Data", "Dict", "InvalidFileException", "FMT_XML", "FMT_BINARY",
"Data", "InvalidFileException", "FMT_XML", "FMT_BINARY",
"load", "dump", "loads", "dumps"
]

Expand Down Expand Up @@ -76,44 +76,6 @@
#


class _InternalDict(dict):

# This class is needed while Dict is scheduled for deprecation:
# we only need to warn when a *user* instantiates Dict or when
# the "attribute notation for dict keys" is used.
__slots__ = ()

def __getattr__(self, attr):
try:
value = self[attr]
except KeyError:
raise AttributeError(attr)
warn("Attribute access from plist dicts is deprecated, use d[key] "
"notation instead", DeprecationWarning, 2)
return value

def __setattr__(self, attr, value):
warn("Attribute access from plist dicts is deprecated, use d[key] "
"notation instead", DeprecationWarning, 2)
self[attr] = value

def __delattr__(self, attr):
try:
del self[attr]
except KeyError:
raise AttributeError(attr)
warn("Attribute access from plist dicts is deprecated, use d[key] "
"notation instead", DeprecationWarning, 2)


class Dict(_InternalDict):

def __init__(self, **kwargs):
warn("The plistlib.Dict class is deprecated, use builtin dict instead",
DeprecationWarning, 2)
super().__init__(**kwargs)


@contextlib.contextmanager
def _maybe_open(pathOrFile, mode):
if isinstance(pathOrFile, str):
Expand All @@ -124,31 +86,6 @@ def _maybe_open(pathOrFile, mode):
yield pathOrFile


class Plist(_InternalDict):
"""This class has been deprecated. Use dump() and load()
functions instead, together with regular dict objects.
"""

def __init__(self, **kwargs):
warn("The Plist class is deprecated, use the load() and "
"dump() functions instead", DeprecationWarning, 2)
super().__init__(**kwargs)

@classmethod
def fromFile(cls, pathOrFile):
"""Deprecated. Use the load() function instead."""
with _maybe_open(pathOrFile, 'rb') as fp:
value = load(fp)
plist = cls()
plist.update(value)
return plist

def write(self, pathOrFile):
"""Deprecated. Use the dump() function instead."""
with _maybe_open(pathOrFile, 'wb') as fp:
dump(self, fp)


def readPlist(pathOrFile):
"""
Read a .plist from a path or file. pathOrFile should either
Expand All @@ -160,8 +97,7 @@ def readPlist(pathOrFile):
DeprecationWarning, 2)

with _maybe_open(pathOrFile, 'rb') as fp:
return load(fp, fmt=None, use_builtin_types=False,
dict_type=_InternalDict)
return load(fp, fmt=None, use_builtin_types=False)

def writePlist(value, pathOrFile):
"""
Expand All @@ -184,8 +120,7 @@ def readPlistFromBytes(data):
"""
warn("The readPlistFromBytes function is deprecated, use loads() instead",
DeprecationWarning, 2)
return load(BytesIO(data), fmt=None, use_builtin_types=False,
dict_type=_InternalDict)
return load(BytesIO(data), fmt=None, use_builtin_types=False)


def writePlistToBytes(value):
Expand Down
15 changes: 7 additions & 8 deletions Lib/test/test_plistlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ def test_bytes(self):
pl = self._create()
data = plistlib.dumps(pl)
pl2 = plistlib.loads(data)
self.assertNotIsInstance(pl, plistlib._InternalDict)
self.assertEqual(dict(pl), dict(pl2))
data2 = plistlib.dumps(pl2)
self.assertEqual(data, data2)
Expand Down Expand Up @@ -454,14 +453,14 @@ def test_io_deprecated(self):
'data': b'buffer',
}
}
pl_out = plistlib._InternalDict({
pl_out = {
'key': 42,
'sub': plistlib._InternalDict({
'sub': {
'key': 9,
'alt': 'value',
'data': plistlib.Data(b'buffer'),
})
})
}
}

self.addCleanup(support.unlink, support.TESTFN)
with self.assertWarns(DeprecationWarning):
Expand Down Expand Up @@ -499,10 +498,10 @@ def test_bytes_deprecated(self):
with self.assertWarns(DeprecationWarning):
pl2 = plistlib.readPlistFromBytes(data)

self.assertIsInstance(pl2, plistlib._InternalDict)
self.assertEqual(pl2, plistlib._InternalDict(
self.assertIsInstance(pl2, dict)
self.assertEqual(pl2, dict(
key=42,
sub=plistlib._InternalDict(
sub=dict(
key=9,
alt='value',
data=plistlib.Data(b'buffer'),
Expand Down
5 changes: 5 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,11 @@ Extension Modules
Library
-------

- bpo-29196: Removed previously deprecated in Python 2.4 classes Plist, Dict
and _InternalDict in the plistlib module. Dict values in the result of
functions readPlist() and readPlistFromBytes() are now normal dicts. You
no longer can use attribute access to access items of these dictionaries.

- bpo-9850: The :mod:`macpath` is now deprecated and will be removed
in Python 3.8.

Expand Down