These are chat archives for praw-dev/praw

21st
Mar 2018
Joe RH
@jarhill0
Mar 21 02:02
@bakonydraco I believe you need to add doc pages for the Emoji, SubredditEmoji, and EmojiModeration classes. To do this, create three files in praw/docs/code_overview/other/with appropriate names. See this or any other file in that directory for an example. Make sure you put the correct full import path in the files you create.
(click Raw in web view to see the raw file, or just view local copies in your text editor of choice)
bakonydraco
@bakonydraco
Mar 21 03:24
Thanks @jarhill0 ! lookign into this
bakonydraco
@bakonydraco
Mar 21 03:29
@jarhill0 you talked about cloning and running my code, how do you do that?
I feel a bit like I'm flying blind haha
Joe RH
@jarhill0
Mar 21 03:37

Assuming you have git installed on your system:

git clone https://github.com/bakonydraco/praw.git will make a new folder in your working directory and download the code.

bakonydraco
@bakonydraco
Mar 21 03:40
oh of course, and I can just run it all locally
i added the requested changes and now I'm seeing
/home/travis/build/praw-dev/praw/docs/code_overview/other/emoji.rst:document isn't included in any toctree
so these new rst's I added need to be in a table of contents somewhere?
got it
Joe RH
@jarhill0
Mar 21 03:45
Ah, I forgot about that. They do need to be added to the appropriate table of contents
I can point you in the right direction if you need it
bakonydraco
@bakonydraco
Mar 21 03:47
i just fixed that
now it's just mad because one of the lines in the edit is too long haha
this pep257 is quite heavy handed haha
ack maybe i don't have it
/home/travis/build/praw-dev/praw/docs/code_overview/other.rst:53:toctree contains reference to document u'code_overview/other/emoji' that doesn't have a title: no link will be generated
bakonydraco
@bakonydraco
Mar 21 03:59
these linelength/whitespace conventions are the worst
Bryce Boe
@bboe
Mar 21 04:00
:)
Consistency > personal preferences
bakonydraco
@bakonydraco
Mar 21 04:02
annoying but fair :P
i can imagine running an opensource project from people with many different coding standards can be difficult
Bryce Boe
@bboe
Mar 21 04:03
Indeed. And it applies to most python projects as well.
I've never once heard your lines are too short ;)
ruby and c projects as well.
I don't know the standards for many other languages though.
Anyway, I appreciate all the progress you're making.
We'll get it in soon!
Joe RH
@jarhill0
Mar 21 04:06

@bakonydraco I think the doc error you posted above might be caused by the missing headers in the doc files you added.

A heading can be made by putting a title as the first line in the file, underlined by the same number of = signs as characters in the title. For example:

SubredditFilters
================

.. autoclass:: praw.models.reddit.subreddit.SubredditFilters
   :inherited-members:
bakonydraco
@bakonydraco
Mar 21 04:18
:)
bakonydraco
@bakonydraco
Mar 21 04:24
oh hmm
I don't see that on any of the other rsts?
./praw/models/reddit/subreddit.py:2218:17: E128 continuation line under-indented for visual indent
:angry: :joy:
Joe RH
@jarhill0
Mar 21 04:25
Are you looking at the "raw" form? Github web view renders the RST, so the header is rendered as a header. Try clicking "Raw" on one of them.
Also, yes, the whitespace regulations are quite frustrating! :D
bakonydraco
@bakonydraco
Mar 21 04:26
ah okay
I'll check raw
bakonydraco
@bakonydraco
Mar 21 04:29
yep, done
plz Travis be nice this time
Joe RH
@jarhill0
Mar 21 04:29
Sweet, let's see what CI says!
Hey @bboe do you know if it's possible for me to push to praw-dev/praw directly without a PR?
Bryce Boe
@bboe
Mar 21 04:33
I don't think so. I don't think I can either unless I disable the branch protection.
What might you want to do that for?
Joe RH
@jarhill0
Mar 21 04:33
I want to simplify if [ "$TRAVIS_PYTHON_VERSION" != "3.3" ]; then sphinx-build -W docs/ /tmp/foo; fi to sphinx-build -W docs/ /tmp/foo because the travis confic no longer includes.
Probably safer if I can't do that directly, but I was just curious.
Alright if I try or no?
(in .travis.yml)
Bryce Boe
@bboe
Mar 21 04:33
For sure, give it a try.
Joe RH
@jarhill0
Mar 21 04:34
@bakonydraco it looks like all the style and doc-related things pass CI now! Good work!
Bryce Boe
@bboe
Mar 21 04:34
The downside to that approach, which has bit me before, is I've made mistakes in little commits like that and then I've ended up with 2+ commits to fix it.
Joe RH
@jarhill0
Mar 21 04:35
When I do that on my own things I tend to just force-push a fix, but I am fully aware that that's not a valid solution for projects with >1 person working on them… :P
Bryce Boe
@bboe
Mar 21 04:35
Making a quick PR and letting it run through CI ensures everything works as intended.
:)
Yeah I do that occasionally too, but not on this project -- at least not in sometime.
Great work @bakonydraco. Next up, tests :)
bakonydraco
@bakonydraco
Mar 21 04:37
woo!!
haha
it's mad about coverage?
what does that mean
Bryce Boe
@bboe
Mar 21 04:37
Definitely, this project has 100% statement coverage.
Which means every line of code has some test case that executes that line in some way.
bakonydraco
@bakonydraco
Mar 21 04:38
ahh test-driven development
so i gotta put tests in somewhere?
Bryce Boe
@bboe
Mar 21 04:38
Not quite.
TDD is a way of writing tests before writing code.
bakonydraco
@bakonydraco
Mar 21 04:38
ah okay
Bryce Boe
@bboe
Mar 21 04:39
Red/green/refactor. It's a great way to get into the habit of writing code that is easily testable.
But yes, tests are needed so we know that what you've written works, and continues to work.
Joe RH
@jarhill0
Mar 21 04:40
As you said, @bboe, my push was rejected. Will PR!
bakonydraco
@bakonydraco
Mar 21 04:40
haha so where do i put the tests
Bryce Boe
@bboe
Mar 21 04:41
There's some information here but it doesn't explain the where: https://praw.readthedocs.io/en/latest/package_info/contributing.html#testing
You see two directories, unit and integration.
Unit tests, are tests that you can run which don't require network connectivity.
E.g., ensuring objects have the right str(object) representation, and hash(object) representation.
The integration test directory is for ensuring the network connectivity actually does what it is supposed to do.
bakonydraco
@bakonydraco
Mar 21 04:48
iiinteresting
bakonydraco
@bakonydraco
Mar 21 04:54
okay I think I wrote one for subreddit
still need to write it for emoji itself
let's see if i did that right
i'll be back in a min
Joe RH
@jarhill0
Mar 21 04:54
looks like a good test to me, if it passes
bakonydraco
@bakonydraco
Mar 21 04:54
woo!
so I anticipate I'll see 100% coverage on subreddit
and then I need to write a new test file for emoji
also I accidentally committed to a patch on praw-dev itself
ignore that
Joe RH
@jarhill0
Mar 21 04:57

Uh-oh @bakonydraco :

./tests/unit/models/reddit/test_subreddit.py:97:1: W293 blank line contains whitespace
./tests/unit/models/reddit/test_subreddit.py:98:1: E302 expected 2 blank lines, found 1
./tests/unit/models/reddit/test_subreddit.py:102:34: F821 undefined name 'Emoji'

You can fix it, I believe in you! :D

Bryce Boe
@bboe
Mar 21 05:04
@jarhill0 you had asked about the use of _next_unique on __iter__.
A few of the existing __iter__ methods use that parameter to break any CDN caching that might occur.
Joe RH
@jarhill0
Mar 21 05:05
Oh, interesting — I hadn't considered that. Good to know!
Bryce Boe
@bboe
Mar 21 05:06
It might not be necessary for emoji listing, but it doesn't really hurt to have it either.
It also is useful in testing to distinguish between the same request issued more than once.
As betamax will match the same request/response multiple times.
Bryce Boe
@bboe
Mar 21 05:12
Well, I'm off for the night. Great work @bakonydraco. Looking forward to seeing some test progress.
And thanks for being a great mentor @jarhill0!
Really awesome to have you as a member of this project.
On that note, you should totally move yourself into the "Team Members" section of https://github.com/praw-dev/praw/blob/master/AUTHORS.rst
It would be preferable if you put your name and some email as well with that.
Joe RH
@jarhill0
Mar 21 05:15
Sure!
Bryce Boe
@bboe
Mar 21 05:17
Awesome.
Goodnight.
Joe RH
@jarhill0
Mar 21 05:19
I'm going to go with last initials for a little bit of privacy if that's alright — my full name returns some fairly specific results that would make it easy to find me in person.
bakonydraco
@bakonydraco
Mar 21 05:32
siiigh
haha okay i'll fix it
bakonydraco
@bakonydraco
Mar 21 05:39
from praw.models import Subreddit, WikiPage, Emoji
E ImportError: cannot import name Emoji
why travis, why
Joe RH
@jarhill0
Mar 21 05:40
You probably need to put Emoji in models/__init__.py
bakonydraco
@bakonydraco
Mar 21 05:41
what is # NOQA
Joe RH
@jarhill0
Mar 21 05:42
It disables flake8 syntax checking on that line
I don't know why it's on every line, but I'm sure @bboe has a good reason
bakonydraco
@bakonydraco
Mar 21 05:43
caaaaaan i just add it to all my lines 😈
Joe RH
@jarhill0
Mar 21 05:44
that's one way to pass CI!
bakonydraco
@bakonydraco
Mar 21 05:44
:D
how do i kill this patch commit i accidentally pushed to praw-dev
E501 line too long (80 > 79 characters)
grrrrrrr
Joe RH
@jarhill0
Mar 21 05:45
:/
What happened with the patch commit? Can you send a link? I don't know what you mean.
i just want to abandon this
wait omg
did it actually work this time??
Joe RH
@jarhill0
Mar 21 05:50
Oh, I see. This is in your fork of PRAW, not the "canonical" praw-dev/praw copy.
bakonydraco
@bakonydraco
Mar 21 05:50
/shrug oh
okay so on the latest commit
no travis errors
but no travis success either
Joe RH
@jarhill0
Mar 21 05:52
Yeah, it didn't run. Let me see if I can make that happen manually.
bakonydraco
@bakonydraco
Mar 21 05:53
oh it looks like it's running for the previous one now
Joe RH
@jarhill0
Mar 21 05:54
yeah, I restarted the build but it seems to not pick up on the newest commit
bummer
If you push something else it might detect it, I don't know…
bakonydraco
@bakonydraco
Mar 21 05:55
well i gotta do the emoji part anyway so
bakonydraco
@bakonydraco
Mar 21 06:02
alright done
nope, it's not registering :(
Joe RH
@jarhill0
Mar 21 06:08
I suspect this has something to do with the merge conflict that has shown up since you added emoji to models/__init__.py.
bakonydraco
@bakonydraco
Mar 21 06:09
laaaame
Joe RH
@jarhill0
Mar 21 06:09
I'm going to bed soon, and I'm sorry to say that I don't feel like tackling this tonight.
bakonydraco
@bakonydraco
Mar 21 06:09
haha not lame to that
get some sleep
Joe RH
@jarhill0
Mar 21 06:09
:)
bakonydraco
@bakonydraco
Mar 21 06:10
can i resolve the merge conflict myself?
Joe RH
@jarhill0
Mar 21 06:10
If you feel confident enough to do it right, sure. I have almost no experience with merge conflicts.
The best way would probably be to rebase against the changes that have been pushed into the repo
(source)
bakonydraco
@bakonydraco
Mar 21 06:25
woo! done
and it's working again
Joe RH
@jarhill0
Mar 21 06:26
Woohoo you did it!
I think you need to add in the Preferences stuff and the Emoji stuff without removing either one.
bakonydraco
@bakonydraco
Mar 21 06:30
hmmm
Joe RH
@jarhill0
Mar 21 06:30
tests will definitely fail if you remove the Preferences import…
bakonydraco
@bakonydraco
Mar 21 06:31
wait what preferences stuff?
Joe RH
@jarhill0
Mar 21 06:33
This commit removed the line from .preferences import Preferences # NOQA and removes 'Preferences' from __all__.
bakonydraco
@bakonydraco
Mar 21 06:34
whoa what
i missed that i did that
ohhhh
yeah i got it
Joe RH
@jarhill0
Mar 21 06:36
Alright, I'm gonna head offline — good work so far and good luck with the remaining work! Thanks for your enthusiasm!
bakonydraco
@bakonydraco
Mar 21 06:39
haha no prob :)
thanks for your help!
bakonydraco
@bakonydraco
Mar 21 18:21
okay haha, got through further, but some of the tests are failing now

self = <tests.unit.models.reddit.test_emoji.TestEmoji object at 0x7f6194d27e50>
def test_repr(self):
emoji = Emoji(self.reddit, subreddit=Subreddit(self.reddit, 'a'),
name='x')

  assert repr(emoji) == ('Emoji(subreddit=Subreddit(display_name=\'a\''
                           '), name=\'x\')')

E assert "Emoji(name='x')" == "Emoji(subreddit=Sub...name='a'), name='x')"
E - Emoji(name='x')
E + Emoji(subreddit=Subreddit(display_name='a'), name='x')
tests/unit/models/reddit/test_emoji.py:51: AssertionError

Joe RH
@jarhill0
Mar 21 18:24

I think that your tests make the wrong assumptions. repr(emoji) will come out as "Emoji(name='x')", and I think that's perfectly fine.

Similarly, str(emoji) will be 'x', which is fine.

bakonydraco
@bakonydraco
Mar 21 18:27
ahhhh
not gonna lie i took this basically wholesale from the wiki
Joe RH
@jarhill0
Mar 21 18:28
Understandable — it's a good technique to model off of pre-existing code.
We just have to catch the mistakes :)
bakonydraco
@bakonydraco
Mar 21 18:31
so i'm not familiar with repr, what does it do?
Joe RH
@jarhill0
Mar 21 18:37

As you know, str() converts an object to a string. Objects can implement a __str__() function to control this functionality. Generally, str() should output something that is concievably useful and appropriate for displaying. If you do '{}'.format(x), str(x) will be called implicitly on x if x is not a string.

repr() is a lot like str() — implemented as __repr__() on objects, for instance — except the convention is that it converts an object to a more exact but less "friendly" format. So, for example, str(emoji) gives you something nice and pretty — the name of the emoji — while repr(emoji) will give you something more specific: Emoji(name='whatever').

According to this popular StackOverflow answer, "The goal of __repr__ is to be unambiguous" and "The goal of __str__ is to be readable."

bakonydraco
@bakonydraco
Mar 21 18:49
ohhh nice!!
thanks this is super helpful
Joe RH
@jarhill0
Mar 21 18:50
By the way, __repr__ and __str__ are defined in RedditBase. All that's required is the one class variable: STR_FIELD.
bakonydraco
@bakonydraco
Mar 21 18:50
ahh
so if i change from
assert repr(emoji) == ('Emoji(subreddit=Subreddit(display_name=\'a\'' '), name=\'x\')')
to
assert repr(emoji) == ('Emoji(name=\'x\')')
do I win?
Joe RH
@jarhill0
Mar 21 18:52
Yes — make sure to change the str_test also.
And btw I would use "Emoji(name='x')" instead of ('Emoji(name=\'x\')')
bakonydraco
@bakonydraco
Mar 21 18:52
yeah that's a lot more readable
Joe RH
@jarhill0
Mar 21 18:53
(parentheses are unneccessary and you can use quotation marks strategically to avoid escaping characters)
bakonydraco
@bakonydraco
Mar 21 18:54
oh sweet
i didn't remove the parens
but fixed the quotes
Joe RH
@jarhill0
Mar 21 18:56
I suspect flake8 might yell at you for unneccessary parentheses
bakonydraco
@bakonydraco
Mar 21 18:56
grrrrr
Joe RH
@jarhill0
Mar 21 18:57
I was wrong — it passed!
bakonydraco
@bakonydraco
Mar 21 18:57
YAY
did the coverage pass?
Joe RH
@jarhill0
Mar 21 18:57
I still recommend removing them, but nice work!
bakonydraco
@bakonydraco
Mar 21 18:57
alllmost
i'm up to 99.4% coverage on subreddit
but now i know how to fix these
Those show the lines you need to cover
bakonydraco
@bakonydraco
Mar 21 18:59
yep
so i don't quite grok, what defines coverage
like i need to cover the iter within SubredditEmoji
Joe RH
@jarhill0
Mar 21 18:59
A line is covered if it is evaluated at any point during the tests. If that line of code is never run, it is not covered.
PRAW has 100% coverage, meaning that every single line of code is run at least once in testing.
bakonydraco
@bakonydraco
Mar 21 19:00
ah! so if i call any iteration in the test
it will run that
Joe RH
@jarhill0
Mar 21 19:00
Yep!
And remember that if you access the network, you are writing integration tests, which involves using a library called Betamax. I can help you with that.
bakonydraco
@bakonydraco
Mar 21 19:02
i prefer VHS
wait how do i test a removal without actually doing it
Joe RH
@jarhill0
Mar 21 19:03
Here's an into to Betamax: https://betamax.readthedocs.io/en/latest/
By the way, the test you just added will not pass because it needs to access the network
Bryce Boe
@bboe
Mar 21 19:04

I don't know why it's on every line, but I'm sure @bboe has a good reason

They're imported there just for namespace convenience. The linter complains because that file doesn't directly use them.

Joe RH
@jarhill0
Mar 21 19:05

wait how do i test a removal without actually doing it

That's what Betamax is for. You actually delete an emoji, once, and Betamax "records" that network interaction. Then, in the future (and on Travis), you can "replay" the interaction to test code functionality without needing to actually contact Reddit.

Thanks for the explanation @bboe
bakonydraco
@bakonydraco
Mar 21 19:06
whoa
wait but the package itself would need mod permissions right?
on some subreddit?
do i need to create a dummy subreddit for this?
Joe RH
@jarhill0
Mar 21 19:07
When you write the test, you should also record the cassette using a Reddit account and subreddit you control. PRAW manages test authentication in such a way that you don't need to share your password or username with anyone else.
bakonydraco
@bakonydraco
Mar 21 19:08
oh man this just got another layer of complexity :D
Joe RH
@jarhill0
Mar 21 19:08
Yep, it's confusing at first.
bakonydraco
@bakonydraco
Mar 21 19:08
is there an example of where betamax is used in testing here
Joe RH
@jarhill0
Mar 21 19:09
Sure! One second
The most important part is that any section of your tests which accesses the network needs a line like with self.recorder.use_cassette('TestInbox.test_all'):
With appropriate cassette name based on class name and method name
Do you have the ability to run the tests locally?
Bryce Boe
@bboe
Mar 21 19:10
More on repr, oftentimes the output can be copy-pasted into python's terminal to create that exact object.
Joe RH
@jarhill0
Mar 21 19:11
python setup.py test or python3 setup.py test will be very useful for running tests, and neccessary for recording new cassettes.
bakonydraco
@bakonydraco
Mar 21 19:24
ahhh that makes sense on repr
i'm not set up locally yet
wait so in test_inbox, where is the cassette stored?
Joe RH
@jarhill0
Mar 21 19:26
The cassettes are stored in praw/tests/integration/cassettes/
But don't worry about the storage location, as Betamax handles that automatically!
bakonydraco
@bakonydraco
Mar 21 19:26
but like
what is stored
just the requests?
Joe RH
@jarhill0
Mar 21 19:27
Basically, everything sent in the request, and everything sent in the response is stored.
bakonydraco
@bakonydraco
Mar 21 19:29
@bboe i confirmed jpg/jpeg works
wait so if the tokens are stored in plain text
can't people do nefarious stuff?
Joe RH
@jarhill0
Mar 21 19:30

Are you talking about the cassettes @bakonydraco ? Such as

      "response": {
        "body": {
          "encoding": "UTF-8",
          "string": "{\"access_token\": \"7302867-ugXwePOkoMMpQttkLyOvLxa0Sl0\", \"token_type\": \"bearer\", \"expires_in\": 3600, \"scope\": \"*\"}"
},

?

bakonydraco
@bakonydraco
Mar 21 19:31
yeah
Joe RH
@jarhill0
Mar 21 19:31
That is something I wonder about — I suspect that those tokens can be used to log into an account
Which is not good
They're probably also time-sensitive
bakonydraco
@bakonydraco
Mar 21 19:31
:O
wait so if i give authorization for an hour
then i'm safe after an hour
but in the future if it tries to test
it will break for anyone else who modifies the test?
Joe RH
@jarhill0
Mar 21 19:32
I try to mitigate this by only recording test cassettes on a test account with nothing else, so that if somebody does steal my credentials they don't get access to anything important.
As for testing, the time-sensitivity of the token doesn't matter because the cassette is permanatly "trapped" in the time it was recorded
bakonydraco
@bakonydraco
Mar 21 19:33
ah good call
so i'm fixing another issue bboe pointed out

i currently have:

data = {'filepath': filepath, 'mimetype': 'image/png'}

but jpg is allowed
should i do
data = {'filepath': filepath, 'mimetype': 'image/png, image/jpeg, image/jpg'}
Joe RH
@jarhill0
Mar 21 19:34
Though this vulnerability is only my suspicion. I haven't actually tried exploiting it. bboe probably knows more.
bakonydraco
@bakonydraco
Mar 21 19:34
ah wait image/jpg isn't a thing
but can i comma separate?
Joe RH
@jarhill0
Mar 21 19:35
I don't think that would work @bakonydraco. The request probably only expects one mime-type
bakonydraco
@bakonydraco
Mar 21 19:35
oh man
so do i have to create a separate add functionality for jpg and png?
i've done this all wrong, too
i have:
   s3_key = self.wikipage._reddit.post(url, data=data)['s3_key']
obviously wikipage shouldn't be there
Joe RH
@jarhill0
Mar 21 19:37
I think you should have mime_type as a parameter to the add method.
bakonydraco
@bakonydraco
Mar 21 19:37
orrrr
okay so the function calls the filepath right
could i do something like
Joe RH
@jarhill0
Mar 21 19:40
I'd have to look into the emoji endpoints a little more to advise what you should do. I'm not quite clear on what the endpoints do, and I can't play around with them now.
bakonydraco
@bakonydraco
Mar 21 19:40
    if filepath[-4:].lower() == '.png':
        data = {'filepath': filepath, 'mimetype': 'image/png'}
    elif filepath[-4:].lower() == '.jpg' \
            or filepath[-4:].lower() == '.jpeg':
        data = {'filepath': filepath, 'mimetype': 'image/jpeg'}
    else: break
how does that look?
almost positive travis ci will get mad about whitespace on the linebreak haha
i'm going to get some lunch
i'll look at the cassettes after
Joe RH
@jarhill0
Mar 21 19:42
That looks good (aside from the else: breakwhich won't work because there is no loop to break from). The alternative is to take mime_type as a parameter. I advise waiting for bboe to advise on which he prefers
Have a good lunch!
bakonydraco
@bakonydraco
Mar 21 19:42
derp, i go back and forth between languages too much haha
i feel like from an enduser perspective, requiring the filetype as a parameter would be a negative
Bryce Boe
@bboe
Mar 21 20:24
I suggest not having mime type as a parameter. The stylesheet image upload has a little test for mimetype.
We can use that later, for now let's get it to work with simple extension check.
Regarding the access tokens in the cassette, I think new cassettes don't save them.
But yes, they are technically valid for 1 hour.
bakonydraco
@bakonydraco
Mar 21 20:25
okay :)
We didn't bother to clean up the old ones in the old cassettes because they shouldn't be usable.
bakonydraco
@bakonydraco
Mar 21 20:27
ah thanks!
why are spaces preferable after commas?
Consistency
bakonydraco
@bakonydraco
Mar 21 20:31
how do i tell pep8 they chose wrong :P
Bryce Boe
@bboe
Mar 21 20:31
Good luck.
bakonydraco
@bakonydraco
Mar 21 20:31
haha i'm teasing
Bryce Boe
@bboe
Mar 21 20:31
:)
bakonydraco
@bakonydraco
Mar 21 20:33
cleaned up the flake, a few more tests failing haha
okay i can't parse this error
self = <tests.unit.models.reddit.test_subreddit.TestSubredditEmoji object at 0x7fa67cd70590>
def test__getitem(self):
subreddit = Subreddit(self.reddit, display_name='name')
emoji = subreddit.emoji['Foo']
assert isinstance(emoji, Emoji)
assert 'foo' == emoji.name
  for emoji in subreddit.emoji:
that's the line it's mad about
but that's how i coded it?
bakonydraco
@bakonydraco
Mar 21 20:38
the trace below that is
praw/models/reddit/subreddit.py:2213: in iter
response = self.subreddit.fullname._reddit.get(
praw/models/reddit/base.py:26: in fullname
self.id) # pylint: disable=invalid-name
Bryce Boe
@bboe
Mar 21 21:51
    def request(self, *args, **kwargs):
        """Issue the HTTP request capturing any errors that may occur."""
        try:
>           return self._http.request(*args, timeout=TIMEOUT, **kwargs)
E           AttributeError: 'NoneType' object has no attribute 'request'
/home/travis/virtualenv/python3.4.6/lib/python3.4/site-packages/prawcore-0.14.0-py3.4.egg/prawcore/requestor.py:47: AttributeError
During handling of the above exception, another exception occurred:
self = <tests.unit.models.reddit.test_subreddit.TestSubredditEmoji object at 0x7f2113055cc0>
    def test__getitem(self):
        subreddit = Subreddit(self.reddit, display_name='name')
        emoji = subreddit.emoji['Foo']
        assert isinstance(emoji, Emoji)
        assert 'foo' == emoji.name
>       for emoji in subreddit.emoji:
AttributeError: 'NoneType' object has no attribute 'request'
That's the exception. ._http doesn't seem to be set.
It's probably because your in units tests which shouldn't be issuing any requests.
That part of the test should be an integration test.
@bakonydraco