BTW:

In [7]: issubclass(set, frozenset)
Out[7]: False

In [8]: issubclass(frozenset, set)
Out[8]: False

no reason to do anything different here.

and:

In [13]: issubclass(MappingProxyType, abc.Hashable)
Out[13]: False

so yes, there is a need for something different

-CHB




On Thu, Oct 11, 2018 at 12:34 PM, Chris Barker <chris.barker@noaa.gov> wrote:
On Thu, Oct 11, 2018 at 9:54 AM, Jonathan Fine <jfine2358@gmail.com> wrote:
Summary: Long post. Because of LSP, neither dict nor frozendict are a
subclass of the other.

given Python's dynamic typing, these issues are kinda academic :-)

> Intuition tells me that a frozen dictionary is a form of dictionary
> that adds restrictions, not that a dictionary is a frozen dictionary
> that you left out to thaw.

well, IIUC the Liskov principle correctly then a subclass is never a version of a class that does less, but rather always one that does more.

Think you intuition may be driven by the choice of names and history: yes, a frozen dict sounds like a regular dict that has been altered (specifically frozen) -- but if we called them "hash_table" and "mutable_has_table", then your intuition may be different :-)

As for subclassing or not, for most Python code is makes no difference -- polymorphism is not achieved through subclassing. and the "Pythonic" way to test for type is through ABCs, and we already have Mapping and MutableMapping, which kind of surprised me, as there is no builtin Mapping that isn't also a MutableMapping.

Notice that I said USEFUL property P. The negation Q of property P is
also a property.

well, yeah, but I think the concept of "useful" is pretty vague.

in this case, is "imutablilty" the "useful" property -- or is "hashability"?, which would want us to use abc.Hashable.

So:

I don't care what is or isn't a subclass of what -- I don't think that's a Pythonic question. But I do think :

issubclass(frozendict, abc.Mapping) and issubclass(frozendict, abc.Hashable)

would be useful.

BTW, I just noticed that:

A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B) or ...`` etc.

which seems less useful than "and" -- at least for ABCs

I suppose that API pre-dates ABCs....

One way to fix this in Python 4 would be to create a common ancestor,
which has only the shared methods of dict and frozendict.

which would be an immutable, but not hashable, mapping ?!? 

Or do
something similar with abstract base classes.

already done -- see above.

-CHB


--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker@noaa.gov



--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker@noaa.gov