Skip to content
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

Unexpected behaviour of dir() after implementation of __dir__ #75997

Closed
nlsdfnbch mannequin opened this issue Oct 19, 2017 · 4 comments
Closed

Unexpected behaviour of dir() after implementation of __dir__ #75997

nlsdfnbch mannequin opened this issue Oct 19, 2017 · 4 comments
Labels
type-bug An unexpected behavior, bug, or error

Comments

@nlsdfnbch
Copy link
Mannequin

nlsdfnbch mannequin commented Oct 19, 2017

BPO 31816
Nosy @tiran, @nlsdfnbch

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2017-10-19.08:35:11.781>
created_at = <Date 2017-10-19.07:48:26.042>
labels = ['type-bug', 'invalid']
title = 'Unexpected behaviour of `dir()` after implementation of __dir__'
updated_at = <Date 2017-10-19.08:35:11.780>
user = 'https://github.com/nlsdfnbch'

bugs.python.org fields:

activity = <Date 2017-10-19.08:35:11.780>
actor = 'christian.heimes'
assignee = 'none'
closed = True
closed_date = <Date 2017-10-19.08:35:11.781>
closer = 'christian.heimes'
components = []
creation = <Date 2017-10-19.07:48:26.042>
creator = 'nlsdfnbch'
dependencies = []
files = []
hgrepos = []
issue_num = 31816
keywords = []
message_count = 4.0
messages = ['304606', '304608', '304609', '304610']
nosy_count = 2.0
nosy_names = ['christian.heimes', 'nlsdfnbch']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue31816'
versions = ['Python 3.5']

@nlsdfnbch
Copy link
Mannequin Author

nlsdfnbch mannequin commented Oct 19, 2017

When defining a custom __dir__ method in a class, calling dir() on
said class still sorts the output. This is, imo, unexpected behaviour, especially if the order of output was specified in __dir__ and is somehow relevant.

Example and more detail here
https://stackoverflow.com/questions/46824459/custom-dir-returns-list-of-attributes-sorted-alphabetically

@nlsdfnbch nlsdfnbch mannequin added the type-bug An unexpected behavior, bug, or error label Oct 19, 2017
@tiran
Copy link
Member

tiran commented Oct 19, 2017

dir() and __dir__ work as designed and documented:

https://docs.python.org/3/reference/datamodel.html?highlight=__dir__#object.\_\_dir__

Called when dir() is called on the object. A sequence must be returned. dir() converts the returned sequence to a list and sorts it

@tiran tiran added the invalid label Oct 19, 2017
@nlsdfnbch
Copy link
Mannequin Author

nlsdfnbch mannequin commented Oct 19, 2017

Alright. Are there any other magic methods that do some post-processing on a custom implementation of them ?

I couldn't think of one, which is why this behaviour appeared odd to me.

@tiran
Copy link
Member

tiran commented Oct 19, 2017

https://docs.python.org/3/library/functions.html#dir also states that "The resulting list is sorted alphabetically." The section has an example where __dir__ returns an unsorted list but dir() returns a sorted list:

>>> class Shape:
...     def __dir__(self):
...         return ['area', 'perimeter', 'location']
>>> s = Shape()
>>> dir(s)
['area', 'location', 'perimeter']

Since the primary purpose of dir() is convenient use for humans, sorting makes perfectly sense. If you need tight control over order of values, you should make your object iterable instead or provide another method.

Several dunder methods perform some sort of post-processing or post-check:

>>> class Example:
...     def __bool__(self): return 2
... 
>>> bool(Example())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __bool__ should return bool, returned int

>>> class MyInt(int):
...     pass
... 
>>> type(MyInt(1))
<class '__main__.MyInt'>
>>> class Example:
...     def __int__(self):
...         return MyInt(1)
... 
>>> int(Example())
1
>>> type(int(Example()))
<class 'int'>

@tiran tiran closed this as completed Oct 19, 2017
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant