Skip to content

Instantly share code, notes, and snippets.

@amcgregor
Created August 10, 2011 02:03
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save amcgregor/1135902 to your computer and use it in GitHub Desktop.
Save amcgregor/1135902 to your computer and use it in GitHub Desktop.
Where asking a simple question, and not accepting useless and insulting answers, gets you banned from an IRC channel.

Cleaned IRC log of #python starting Monday, 25 July, 2011 at 17:13:55 EDT.

Gems are highlighted in bold.

GothAlice How do I determine if a given object is a @classmethod, and, additionally, how do I determine if it is a @staticmethod? 1
KirkMcDonald GothAlice: Why would you care?
GothAlice KirkMcDonald: Enforcing interfaces, not that it matters.
dash GothAlice: you’re right, it doesn’t matter
_habnabit GothAlice, if you wanted an answer to the question as asked, why don’t you try ##python-friendly? #python is about writing better code.
nedbat GothAlice: what KirkMcDonald should have said was, “The Python culture is to not check ahead of time, do you have an unusual requirement that means you really have to know?”
GothAlice _habnabit: Cute, thank you for living up to expectations.
nedbat _habnabit: you don’t have to treat people that way.
GothAlice nedbat: Assume yes, I do have a requirement that needs this.
message144 heh today i learned that ##python-friendly is a real thing
GothAlice nedbat: No worries, I expect that kind of behaviour from him and a few select others.
nedbat GothAlice: the inspect module has lots of tools, not sure if it covers what you’re looking for.
GothAlice nedbat: I’ve already looked, it doesn’t.
GothAlice Also, _habnabit, it’s against channel rules to advertise other channels; or it was, last time I checked.
KirkMcDonald GothAlice: The answer is obvious if you know how classmethod and staticmethod work. 2
nedbat KirkMcDonald: that’s not that helpful an answer either.
GothAlice KirkMcDonald: Again, thank you for meeting expectations. Is it any wonder I created ##python-friendly?
KirkMcDonald GothAlice: Just yank the objects out of the thing and see what they are. 2
GothAlice KirkMcDonald: Still not helpful. You do realize you’re wasting not just my time, but yours as well?
dash GothAlice: You already know what to expect when you come here.
nedbat dash: why is it ok for her to expect curt rude unhelpful answers?
dash GothAlice: So please don’t expect us to be moved by your complaints about it.
Yhg1s nedbat: there’s quite a bit of history involved.
dash nedbat: A long history of disagreement.
nedbat Yhg1s: I’m getting that sense, but in my experience, GothAlice is not unusual in this regard. Lots of people have come to expect those answers.
KirkMcDonald nedbat: We’re not here to just answer asked questions.
Yhg1s nedbat: if the questions are about bad ideas, then yes, many people won’t give direct answers. With good reason. All too often, if they are given something that does what they seem to want, it’ll just ruin their design and they’ll come back crying later.
Yhg1s nedbat: #python is about helping people write Python, not get something working.
nedbat i’ve heard all this before. Some people disagree. I won’t take more of your time.
GothAlice I think that’s the primary conflict, here. I feel no need to justify myself when asking a question about a real problem I’m encountering. I’ve been programming commercially since I was 9, and generally my OSS code speaks for itself. I’m not an idiot, don’t treat me as one.
Yhg1s nedbat: this is why there’s other channels :)
Yhg1s GothAlice: And yet you insist on treating us as idiots. Thanks. 3
GothAlice However, my particular use case involves writing an interface declaration and enforcement system, similar to zope.interface, but a fair bit simpler.
KirkMcDonald GothAlice: If you find that you actually need to do this sort of metaprogramming nonsense, I am surprised you don’t know how to do it. 4
nedbat KirkMcDonald: we’ve established that you are surprised. Now, do you know the answer?
KirkMcDonald That you have sufficient skill for this kind of metaprogramming to be a need but insufficient skill to just do it is strange to me. 4
dash GothAlice: I would note that not even zope.interface checks if things are staticmethods or classmethods. :)
KirkMcDonald I gave the answer: Get the objects. See what they are instances of. 2
dash GothAlice: So your approach already sounds less simple
GothAlice sighs.
nedbat KirkMcDonald: when i get a classmethod from an object, its type is “instancemethod”.
NelleV GothAlice: maybe you’ll have more answers on the python-list mailing list
Yhg1s nedbat: you have to get it from the class, of course.
KirkMcDonald To get the actual classmethod object, you don’t even get it from the class. You need to sidestep the descriptor protocol.
Yhg1s some knowledge of how these things work is necessary, if you want to do these kinds of things. There’s several decent documents on the interwebs that explain how classes, metaclasses and descriptors like staticmethod and classmethod work. [17:29:43]
GothAlice Yhg1s: A ha, descriptor protocol. Thank you for finally being useful. type(obj).mro() + dict here I come. 5
Yhg1s GothAlice: ‘finally being useful’. Thanks again.
Yhg1s GothAlice: your hostile attitude is as old as your passive-agressiveness. Please go away, learn to act like a civil person or ask better questions (preferably all three.) 6
GothAlice Yhg1s: Just giving credit where credit is due. Those two words took 15 minutes and solved my problem. Additionally, the question was perfectly sound. Your insistence on correcting the purpose of others’ code is the problem.
Kaedenn GothAlice: Welcome to #python
Kaedenn GothAlice: I see you’re new here
17:33:40 mode (+o Yhg1s) by ChanServ
17:33:51 mode (+b !amcgregor@74.198.165.*) by Yhg1s
17:33:52 You have been kicked by Yhg1s: (Don’t come back.)

1 If you can argue that this isn’t a clear and concise question, please comment.

2 Snide and/or unhelpful answers that are such in any context. Pretend you’re a tourist, and from everyone you ask “How do I get to X?” you get “Well, if you lived here, you’d know!”

3 Not sure how dismissing useless answers is treating someone as an idiot… sure, repeatedly pointing out someone is living up to low expectations (held not just by me) might be insulting, but when it’s demonstrated again and again—within the same conversation no less—it’s not unjustified.

4 These aren’t even subtle.

5 Should have been directed at KirkMcDonald and Yhg1s.

6 Prior to the actual answer there was one attempted good-faith answer (inspect module, alas, not viable), two dismissals, three purposefully vague and unhelpful answers, at least two thinly veiled insults, and three suggestions to ask elsewhere (though one was more along the lines of “You know we won’t help you, so why do you bother?”).

This is not a good sign for what one might usually refer to as a “Python support community”. Operative word being support. Thank you, nedbat, for helping. The inspect module, after further inspection, does contain code that can be helpful by way of the undocumented classify_class_attrs function, which works in much the same way as my own code.

For future reference, the solution is attached.

def isclassmethod(cls, name):
for cls in cls.mro():
if name in cls.__dict__:
if type(cls.__dict__[name]) is classmethod:
return True
return False
return False
def isstaticmethod(cls, name):
for cls in cls.mro():
if name in cls.__dict__:
if type(cls.__dict__[name]) is staticmethod:
return True
return False
return False
class Foo(object):
def foo(self):
pass
@classmethod
def bar(cls):
pass
@staticmethod
def baz():
pass
assert not isclassmethod(Foo, 'foo'), "Method is classmethod?"
assert isclassmethod(Foo, 'bar'), "Classmethod isn't?"
assert isstaticmethod(Foo, 'baz'), "Staticmethod isn't?"
@pjenvey
Copy link

pjenvey commented Aug 10, 2011

needs moar any()

@amcgregor
Copy link
Author

@pjenvy Actually, any would be bad since if a method is overridden by a subclass the fact that a superclass's method is a class method or staticmethod is irrelevant, it's not what's going to be used in the end. What is really needed here is for/else. :)

@DaftVadeR
Copy link

That has definitely put a damper on any motivation I may have had to try out Python...

@amcgregor
Copy link
Author

@DaftVadeR That's the wrong response to this; in any sufficiently large community there are shit users, and sometimes these shit users are vocal in spreading their stench. This isn't a statement against the language itself, just about staying away from the "official" support channel. ##python-friendly exists and is, after this incident, even more populated than before, and mailing lists, project specific channels, Stack Overflow and kin remain good resources.

@voidspace
Copy link

I've had several poor experiences along the same lines in #python - they seem to be far more interested in proving their own superiority than actually helping anyone. I'm surprised at Yhg1s though.

@amcgregor
Copy link
Author

@apoirier — thirty minutes. :/

@manuco
Copy link

manuco commented Aug 11, 2011

I'm perhaps writing a mistake, but why didn't you use getattr(cls, name) instead of cls.dict[name] in a mro loop ?

@Singletoned
Copy link

I'm not sure you come out of this any better than them. You're asking for help, yet you are antagonistic. If your initial question is valid then so is KirkMcDonald's question in reply. You want help from people yet you're not giving them anything back.

Regarding footnote 2: Imagine you're a tourist and everytime you ask someone "How do I get to [dangerous part of town]?". They all answer "you shouldn't go there" or "if you really needed to go there, you would already know". That's not surprising. However if someone replied "why do you want to go there?", and you said "[short answer], not that it matters", how would you react? What if then someone said "what he should have said was: we try to avoid that place, do you have a particular reason to go there?" and you replied "assume yes, I have a reason for going there". I wouldn't expect much good to come of that.

As far as I can tell, everyone except "_habnabit" gives reasonable responses until you become antagonistic. And there is always extra responsibility on the person requesting help to not be antagonistic.

@amcgregor
Copy link
Author

@manuco Using getattr would trigger the descriptor protocol and return a mutated copy of the original function (e.g. an instance method in the case of the @classmethod). You have to access dict directly to avoid this behaviour.

@Singletoned You're ignoring the fact that I actually answered his question. "Not that it matters", while blunt, is also true. It was a short way of writing "I know what I'm doing is discouraged, but I have a use case that I do not want to waste time explaining". (And it would have been a waste of time as evinced by the comments on the use case despite the popularity and valid uses for packages like zope.interface.)

@manuco
Copy link

manuco commented Aug 11, 2011

@GothAlice thanks for your answer !

@Singletoned
Copy link

I'm not ignoring it. The fact that something is true doesn't make it a good answer. It's understandable that you valued your time and wanted to save as much time as possible, but I doubt the other people considered themselves to be there to save you time. They wanted information from you, but your time was too important, so you asked for help without giving any good reason for it. Strangely, they didn't give you the help.

There's a really good (and quite old) article all about this by ESR: http://catb.org/~esr/faqs/smart-questions.html

@pjenvey
Copy link

pjenvey commented Aug 11, 2011

@GothAlice not sure what you mean, all I meant was a refactoring, e.g.:

def isclassmethod(cls, name):
    return any(type(base.__dict__[name]) is classmethod
               for base in cls.mro()
               if name in base.__dict__)

@amcgregor
Copy link
Author

@pjenvey With the above, the following would erroneously return True:

class A(object):
    @classmethod
    def foo(cls):
        pass

class B(A):
    def foo(self):
        pass

print isclassmethod(B, 'foo')

It must explicitly determine the answer from the first match from the MRO to ensure that B.foo() is actually a class method. (Which in this case it isn't. MRO is short for method resolution order, FYI.) Additionally, it's more efficient to not iterate the whole set. (Thus not using ([type(base.__dict__[name]) is classmethod for base in cls.mro() if name in base.__dict__]+[False])[0])

@pjenvey
Copy link

pjenvey commented Aug 11, 2011

Ah yes, my bad

@katanacrimson
Copy link

@Singletoned Linking to something written by ESR when discussing something like public relations and community development is like playing Russian Roulette with a revolver that's got all but one barrel loaded.
The lit you linked to reads to many normal users (I've discussed that article with numerous users before) as arrogant, snide, terse, and belittling; it makes those who direct others to it look like egotistical jackasses. Open Source is, while free, still a product, and it has to be sold to all that are interested in buying (into) it. Acting hostile, demonstrating a superiority complex, and insulting the customer does absolutely _nothing_ to sell Open Source; instead, it detracts from the movement itself.
Please, shelve that link and don't use it again. It makes every FOSS developer look like an asshat.

@GothAlice it's a shame you encountered that, but thanks for putting up the log.
I guess if I start working with python anytime soon, I know what channel to avoid like the plague.

Shame that the chanops there don't know how to nurture and grow a community.

@amcgregor
Copy link
Author

@damianb With my primary account out-of-the-loop until October (when the ban expires), I missed out on some of the other fallout from this. Apparently _habnabit has "called it quits" (according to Yhg1s) and in the same conversation, after I made it clear I wanted to help #python improve (and not plead my case for the ban to be lifted), Yhg1s cut off the conversation.

Nurturing and growing a community seems to be the opposite of what #python's chief members want. Which is weird and not unlike a private fraternity, which is sad. I think I'll pose a question to our BDFL, Guido, tonight. :(

@reuf
Copy link

reuf commented Jun 5, 2012

Got banned from from Python few minutes ago. Same person.

T 1338855153 amoxibos: uml - diagrams - yes or no?
T 1338855166 x0rs_w: SegFaultAX|work2, I've tried assigning the recursive function calls back to a variable as well with different, but still failed results
T 1338855167 bob2: no
T 1338855176 amoxibos: pros and cons?
T 1338855177 Yhg1s: amoxibos: yes, they are both words.
T 1338855221 amoxibos: Yhg1s, dont denigrate the conversation
T 1338855223 Runeg: Yhg1s, I tweaked it slightly: for k in d1.keys(): if d1[k] != d2[key]...
T 1338855243 Yhg1s: amoxibos: there isn't any conversation. You're tossing random words. Perhaps you should try asking an actual question.
T 1338855249 Yhg1s: Runeg: no, don't do that.
T 1338855249 Runeg: Yhg1s, and it works exactly as needed.
T 1338855268 Runeg: Yhg1s, I'll revert it, but can you explain why I'd prefer 'for k in d1' vs 'for k in d1.keys()' ?
T 1338855269 Yhg1s: Runeg: 'for k in d1' already iterates over keys, without creating a new list of them.
T 1338855278 Runeg: Yhg1s, Ah ha. Thanks.
T 1338855288 amoxibos: Yhg1s, data mining concetps - just give out the info - dont bull ppl with crap talk
T 1338855297 amoxibos: too much data, too little info
T 1338855309 amoxibos: my qs are more info, less data
T 1338855309 Yhg1s: amoxibos: please take your attitude elsewhere.
T 1338855329 amoxibos: Yhg1s, mirror, mirror, on the wall, whos the brightest of them all?
T 1338855335 26ChanServ gives channel operator status to26 Yhg1s
T 1338855339 Yhg1s sets ban on !amoxibos@**.**.**.
T 1338855339 You have been kicked from #python by Yhg1s (how much data is this23)

@amcgregor
Copy link
Author

@reuf :/

While I'm certain Yhg1s can be an obtuse jackass ("yes, they are both words") I can also see his point here. Doesn't excuse his statements which, as far as I'm concerned, should preclude him from maintaining moderator status.

Your text from this snippet does read like a list of arbitrary keywords. Boolean questions that consist of two technical keywords can't rightfully be answered by anyone. In the same snippet he gave both good advice (don't use .keys()) and explained why. Your mirror mirror jab, like my "finally being useful" one, obviously didn't help the situation.

Here's hoping your ban is temporary. Me? I basically just don't go there any more even though my ban has been lifted. Not worth the frustration.

@reuf
Copy link

reuf commented Jun 5, 2012

Yea I know i messed up, but don't understand why do I have to get banned?

@amcgregor
Copy link
Author

@reuf No doubt, Yhg1s loves his banhammer.

@katanacrimson
Copy link

@reuf The reason is commonly known as "power trip", or alternatively "ego".

@reuf
Copy link

reuf commented Jun 5, 2012

Yea, it seems that other people have had similar problems with the guy...
https://gist.github.com/2204516#comments

Did a bit of research on the him...
http://nl.linkedin.com/pub/thomas-wouters/a/250/546
http://stackoverflow.com/users/17624/thomas-wouters
http://www.flickr.com/photos/mfoord/5543048811/
https://twitter.com/#!/Yhg1s

Giving Google tech talks on Python
http://video.google.com/videoplay?docid=7760178035196894549
http://www.youtube.com/watch?v=Jpjo0JX797Q

So, he does deserve a lot of respect...Had I known his background, would not approach him in that way.

@amcgregor
Copy link
Author

@reuf To me respect is a personal thing that has to be earned; renown is a separate issue. I have seen very few examples of Yhg1s attempting to garner respect in his interpersonal communications on #python, and many examples of him being what I referred to earlier as "an obtuse jackass". If he expects respect, but continues to abuse his powers while showing no respect to others…

Looking at some of that research I noticed an interesting detail: he's Dutch! :D (J/K… my mother's Dutch… ¬_¬)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment