1

I had a problem with the Django tutorial so I asked a question here. No-one knew the answer, but I eventually figured it out with help from Robert. Python seems to be treating import datetime the same as from datetime import *.

Working code:

import datetime
from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __unicode__(self):
        return self.question

    def was_published_today(self):
        return self.pub_date.date() == date.today()

Not working code: (The only differences are the import statements and the last line.)

from django.db import models
import datetime

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __unicode__(self):
        return self.question

    def was_published_today(self):
        return (self.pub_date() == datetime.date.today())

EDIT: I guess I wasn't clear enough. The code produces the exact same traceback with the last line being return (self.pub_date.date() == datetime.date.today()) Me originally forgetting to add .date() is NOT the error I'm asking about.

The traceback produced by the not working code:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/myDir/mySite/polls/models.py", line 11, in was_published_today
    return (self.pub_date() == datetime.date.today())
TypeError: 'datetime.datetime' object is not callable

Why on earth is it doing this?

My question is NOT about forgetting .date(). My question is: Why is datetime in my namespace without me using from datetime import *.

Note: The first question asked what it was doing. This question asks why.

UPDATE: Suddenly it works. With datetime.date.today() AND date.today(). My question remains though, why does date.today() work? It seems datetime is in my local namespace without me putting there. Why?

Community
  • 1
  • 1
John
  • 15,418
  • 12
  • 44
  • 65
  • 2
    Your Python installation must be seriously messed up. – Chris Morgan Dec 17 '10 at 06:30
  • Shouldn't `self.pub_date()` in the second case be `self.pub_date.date()`, just like in the first case? – Alok Singhal Dec 17 '10 at 06:31
  • 1
    That's really odd. Works normally when I just do `import datetime; datetime.date.today()` with none of the Django stuff. – Rafe Kettler Dec 17 '10 at 06:31
  • I guess self.pub_date is not callable. – Kabie Dec 17 '10 at 06:31
  • @Alok: That's one reason that's the code that **doesn't** work. – John Dec 17 '10 at 06:32
  • @Rafe: Yes, me too. In a different file in the same folder it works fine, just not it this file. – John Dec 17 '10 at 06:33
  • @John but does the second script run if you use `self.pub_date.date()`? – Rafe Kettler Dec 17 '10 at 06:33
  • @Rafe: No it does **NOT**. It produces the exact same traceback. – John Dec 17 '10 at 06:36
  • By __exact__ you mean even the "return (self.pub_date() == datetime.date.today())" part? – Kabie Dec 17 '10 at 06:39
  • @Kabie: After I add `.date()` it still produces the same traceback. – John Dec 17 '10 at 06:40
  • what's the output of `print datetime` from within the file. – dan_waterworth Dec 17 '10 at 06:42
  • Maybe the view file import this model happened contains `from datetime import *`? And if you use `self.pub_date.date()`, the traceback should show `self.pub_date.date()` instead of `self.pub_date()`. – Kabie Dec 17 '10 at 06:44
  • @dan: I added it right before the return and nothing different happened. – John Dec 17 '10 at 06:45
  • @John, it didn't print anything? try putting it at the beginning of the file after the import. – dan_waterworth Dec 17 '10 at 06:46
  • @Kabie: I see your point now. The *error* is the same. The *traceback* differs in that `.date()` is added. – John Dec 17 '10 at 06:48
  • @Dan: Still nothing....I'm so confused. – John Dec 17 '10 at 06:49
  • @John, try changing it to `assert 0, repr(datetime)` – dan_waterworth Dec 17 '10 at 06:54
  • @John: Then it shouldn't raise `TypeError: 'datetime.datetime' object is not callable` after using `self.pub_date.date()`. – Kabie Dec 17 '10 at 07:07
  • I've had some weird issues like this too with Django + datetime. Hopefully this gets resolved. – mpen Dec 17 '10 at 07:08
  • @Kabie: I know it *shouldn't* but it *is*. – John Dec 17 '10 at 18:14
  • @Dan: If I put it right after the imports it should execute when that file itself is imported right? It doesn't seem to be. Changing `print datetime` to `assert0, repr(datetime)` do not change anything that I saw. Importing my polls file still didn't print anything. – John Dec 17 '10 at 18:18
  • I was able to get the code running. It's not your full environment, obviously, but the code imports and runs. I do not get the same effect you did. – Lennart Regebro Dec 17 '10 at 19:16
  • @Lennart: -bangs head on desk- Yes, Robert said he did the exactly same tutorial last month without problem. – John Dec 17 '10 at 19:21
  • @John: Well, start with understandning what pdb is and how to use it. Then learn how to interpret a traceback. Then I'm sure you'll find the problem. – Lennart Regebro Dec 17 '10 at 20:00
  • @Lennart: I know how to interpret a traceback(I think anyway). It makes no mention of my file *at all*! What I don't get is why polls is not defined when `import polls.models` works fine. – John Dec 17 '10 at 20:05
  • Oh, you are talking about the traceback when you tried to use pdb. Sigh. – Lennart Regebro Dec 17 '10 at 20:12
  • @John, If nothing is happening I don't think it is being run. Are you sure you are making changes to the right file? if you put `print models` or whatever you've imported it as in your view file then does it show the correct file name? – dan_waterworth Dec 18 '10 at 06:10
  • Yes, it's supposed to print that. I don't think it's updating properly before you are re-running the code. Try removing the assert and print statement and retrying ayaz's answer. – dan_waterworth Dec 19 '10 at 22:22
  • @dan: Just retried that. I've no idea why but suddenly I'm getting the debug prompt that Lennart said I should but I never did. Also, `date.today()` correctly, no longer works. What do you think isn't updating? Put it as an answer and I'll accept it. – John Dec 19 '10 at 22:34
  • Are you using Django's auto-reloading server? – dan_waterworth Dec 19 '10 at 22:36
  • @dan: I was only aware of one Django server:the development one. It's not running now. I'm not sure if it was running the first time I tried these suggestions, but I'm trying to find out. – John Dec 19 '10 at 22:44
  • @john, I mean, are you checking the answers using Django's server or the shell or what? – dan_waterworth Dec 19 '10 at 22:48
  • @dan:I have been and am checking the answers in the shell. – John Dec 19 '10 at 22:56
  • do you reload the shell for each change? – dan_waterworth Dec 19 '10 at 22:57
  • @Dan: No. I'm starting the get the feeling that was a *big* mistake.... – John Dec 19 '10 at 23:02
  • @Dan: -facepalm- Well now I feel stupid. Thanks for your help. – John Dec 19 '10 at 23:05
  • @john, you learnt something, it wasn't a complete loss. – dan_waterworth Dec 19 '10 at 23:07
  • @Dan: Yes, I'm also very glad that there are people like you who stick with me until it's fixed. – John Dec 19 '10 at 23:09

3 Answers3

4

The problem in the latter snippet is with this part of your code:

return (self.pub_date() == datetime.date.today())

self.pub_date contains a datetime.datetime instance. It's not callable like that. For example:

>>> import datetime
>>> d = datetime.datetime.now()
>>> d()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'datetime.datetime' object is not callable
>>>

If you want to compare only the date, you should call it thus:

return (self.pub_date.date() == datetime.date.today())
ayaz
  • 10,406
  • 6
  • 33
  • 48
  • 1
    Take a look at the other question. He got an error on that, but if you remove `datetime` from the second half of the `==` he's OK. The question isn't the `pub_date.date()` (although he has a typo in the question) but why `datetime` seems to be poisoning his namespace without using a `from`. – Robert Dec 17 '10 at 06:37
  • I already tried that. I covered that in the answer to the other question. `return (self.pub_date.date() == datetime.date.today())` **does not work!** – John Dec 17 '10 at 06:38
2

As we discussed in the comments, the problem is not with the code, but the way you are updating the source. python caches modules in sys.modules. You can reload individual modules using the reload function, but for many changes it's best to reload the entire shell. In many cases it looked as though the changes had propagated because the error messages seemed to have changed, this is because python doesn't cache the source code of the file, so when it references code, it shows you the newest version. Hopefully now, you can apply the other answers with more success.

dan_waterworth
  • 6,261
  • 1
  • 30
  • 41
2

"My question is: Why is datetime in my namespace without me using from datetime import *."

Because you did import datetime. Then you have datetime in your namespace. Not the CLASS datetime, but the MODULE.

Python does not treat import datetime the same way as from datetime import *. Stop asking why it does that, when it does not.

>>> import datetime
>>> date.today()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'date' is not defined
>>> 

There is something else happening. If it's Django magic or not, I don't know. I don't have a Django installation where I can try this at the moment. (If there is a super-quick way of making that happen, tell me. easy_installing Django wasn't enough. :) )

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
  • I know Python *shouldn't* treat them the same but I looks to me like it *is*. I also think something else is happening, but what? – John Dec 17 '10 at 18:13
  • @John: That's probably trivially easy to figure out by sticking a pdb in the code. But I can't do that, as I don't know how to make the code example actually runnable, since I haven't used Django for two years. :-) I'm **guessing** Django magically craps all over your locals() but that's just a wild guess. – Lennart Regebro Dec 17 '10 at 18:26
  • @Lennart: The output of that is here: http://pastebin.com/2eRuxajV Unfortunately, I don't understand what that output means. I'm not sure I did that right, that was my first time ever using pdb. – John Dec 17 '10 at 18:34
  • I should probably add that `import polls.models` works fine in the interpreter. – John Dec 17 '10 at 18:47
  • @John: Just before the line where the error happens, stick `import pdb;pdb.set_trace()`. Then you'll be able to inspect local variables and step into the methods, etc. – Lennart Regebro Dec 17 '10 at 19:04
  • @Lennart: I don't think my file is causing that error. The traceback has no mention of my files. Nevertheless, I added that at the very beginning of the file. There was no difference. It produced the same traceback as I put in pastebin. – John Dec 17 '10 at 19:11
  • OK, once again: **Just before the line where the error happens, stick import pdb;pdb.set_trace()**. Not at the beginning of the module, but **ON THE LINE BEFORE THE ERROR HAPPENS**. You will get a prompt. There you can debug. – Lennart Regebro Dec 17 '10 at 20:15
  • @Lennart: The pdb traceback. The one I put in pastebin and linked to a few comments ago. *That* traceback makes no mention of my file. – John Dec 17 '10 at 20:16
  • @Lennart: The presence of `import pdb;pdb.set_trace()` did not appear to change anything. From the interpreter I again tried `pdb.run('polls.models')` and received the `polls is not defined` traceback. – John Dec 17 '10 at 20:20
  • I never said the presence would change anything. I said: **You will get a prompt. There you can debug.** Please read what I say, this is turning out to be a big waste of time otherwise. Did you not get a debug prompt? I have no clue why you are trying to do `pdb.run('polls.models')` from the interpreter. – Lennart Regebro Dec 17 '10 at 20:30
  • @Lennart: It's presence not changing anything means that when I run the file I get no prompt. – John Dec 17 '10 at 20:41
  • Well, that's also impossible. Things are clearly not as you say they are. That line *will* start a debug prompt, so you can not get an error on the line after without getting a prompt. I suggest you delete everything and restart. – Lennart Regebro Dec 17 '10 at 22:12
  • @Lennart: Yes you are probably right. At least, I hope it's something that simple! Thanks for your help. – John Dec 17 '10 at 22:47